aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md55
-rw-r--r--app/manifest.json7
-rw-r--r--app/scripts/background.js8
-rw-r--r--app/scripts/contentscript.js45
-rw-r--r--app/scripts/controllers/transactions.js48
-rw-r--r--app/scripts/keyring-controller.js3
-rw-r--r--app/scripts/lib/auto-reload.js62
-rw-r--r--app/scripts/lib/createLoggerMiddleware.js15
-rw-r--r--app/scripts/lib/createOriginMiddleware.js9
-rw-r--r--app/scripts/lib/createProviderMiddleware.js13
-rw-r--r--app/scripts/lib/inpage-provider.js86
-rw-r--r--app/scripts/lib/nonce-tracker.js107
-rw-r--r--app/scripts/lib/obj-multiplex.js48
-rw-r--r--app/scripts/lib/pending-tx-tracker.js8
-rw-r--r--app/scripts/lib/port-stream.js16
-rw-r--r--app/scripts/lib/stream-utils.js24
-rw-r--r--app/scripts/lib/tx-state-history-helper.js37
-rw-r--r--app/scripts/metamask-controller.js91
-rw-r--r--app/scripts/migrations/018.js52
-rw-r--r--app/scripts/migrations/019.js83
-rw-r--r--app/scripts/migrations/index.js2
-rw-r--r--circle.yml17
-rw-r--r--development/uiStore.js4
-rw-r--r--docs/add-to-firefox.md (renamed from docs/add-to-firef.md)0
-rw-r--r--karma.conf.js61
-rw-r--r--mascara/src/lib/setup-iframe.js4
-rw-r--r--mascara/src/proxy.js4
-rw-r--r--mock-dev.js73
-rw-r--r--package.json23
-rw-r--r--test/data/v17-long-history.json3053
-rw-r--r--test/integration/helpers.js7
-rw-r--r--test/integration/index.js19
-rw-r--r--test/integration/lib/first-time.js198
-rw-r--r--test/lib/mock-store.js4
-rw-r--r--test/lib/mock-tx-gen.js40
-rw-r--r--test/unit/actions/tx_test.js87
-rw-r--r--test/unit/nonce-tracker-test.js226
-rw-r--r--test/unit/tx-controller-test.js35
-rw-r--r--test/unit/tx-state-history-helper-test.js26
-rw-r--r--test/unit/tx-state-history-helper.js23
-rw-r--r--testem.yml10
-rw-r--r--ui/app/actions.js13
-rw-r--r--ui/app/add-token.js31
-rw-r--r--ui/app/app.js2
-rw-r--r--ui/app/components/account-export.js28
-rw-r--r--ui/app/components/dropdowns/components/account-dropdowns.js45
-rw-r--r--ui/app/components/network.js11
-rw-r--r--ui/app/components/pending-msg-details.js2
-rw-r--r--ui/app/components/pending-msg.js18
-rw-r--r--ui/app/components/pending-tx.js90
-rw-r--r--ui/app/components/token-list.js23
-rw-r--r--ui/app/components/transaction-list-item.js11
-rw-r--r--ui/app/conf-tx.js7
-rw-r--r--ui/app/config.js7
-rw-r--r--ui/app/css/itcss/tools/utilities.scss2
-rw-r--r--ui/app/info.js2
-rw-r--r--ui/app/keychains/hd/create-vault-complete.js10
-rw-r--r--ui/app/reducers.js5
-rw-r--r--ui/app/unlock.js2
-rw-r--r--ui/app/util.js16
-rw-r--r--ui/lib/account-link.js10
-rw-r--r--yarn.lock599
62 files changed, 5027 insertions, 640 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 516e8f9e8..1ba214cce 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,61 @@
## Current Master
+- Add ability to export private keys as a file.
+- Add ability to export seed words as a file.
+- Changed state logs to a file download than a clipboard copy.
+- Fixed a long standing memory leak associated with filters installed by dapps
+- Fix link to support center.
+
+## 3.10.0 2017-9-11
+
+- Readded loose keyring label back into the account list.
+- Remove cryptonator from chrome permissions.
+- Add info on token contract addresses.
+- Add validation preventing users from inputting their own addresses as token tracking addresses.
+- Added button to reject all transactions (thanks to davidp94! https://github.com/davidp94)
+
+## 3.9.13 2017-9-8
+
+- Changed the way we initialize the inpage provider to fix a bug affecting some developers.
+
+## 3.9.12 2017-9-6
+
+- Fix bug that prevented Web3 1.0 compatibility
+- Make eth_sign deprecation warning less noisy
+- Add useful link to eth_sign deprecation warning.
+- Fix bug with network version serialization over synchronous RPC
+- Add MetaMask version to state logs.
+- Add the total amount of tokens when multiple tokens are added under the token list
+- Use HTTPS links for Etherscan.
+- Update Support center link to new one with HTTPS.
+- Make web3 deprecation notice more useful by linking to a descriptive article.
+
+## 3.9.11 2017-8-24
+
+- Fix nonce calculation bug that would sometimes generate very wrong nonces.
+- Give up resubmitting a transaction after 3500 blocks.
+
+## 3.9.10 2017-8-23
+
+- Improve nonce calculation, to prevent bug where people are unable to send transactions reliably.
+- Remove link to eth-tx-viz from identicons in tx history.
+
+## 3.9.9 2017-8-18
+
+- Fix bug where some transaction submission errors would show an empty screen.
+- Fix bug that could mis-render token balances when very small.
+- Fix formatting of eth_sign "Sign Message" view.
+- Add deprecation warning to eth_sign "Sign Message" view.
+
+## 3.9.8 2017-8-16
+
+- Reenable token list.
+- Remove default tokens.
+
+## 3.9.7 2017-8-15
+
+- hotfix - disable token list
- Added a deprecation warning for web3 https://github.com/ethereum/mist/releases/tag/v0.9.0
## 3.9.6 2017-8-09
diff --git a/app/manifest.json b/app/manifest.json
index f34bdcec3..bd25c1f6f 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "MetaMask",
"short_name": "Metamask",
- "version": "3.9.6",
+ "version": "3.10.0",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "Ethereum Browser Extension",
@@ -57,9 +57,8 @@
"permissions": [
"storage",
"clipboardWrite",
- "http://localhost:8545/",
- "https://api.cryptonator.com/"
- ],
+ "http://localhost:8545/"
+ ],
"web_accessible_resources": [
"scripts/inpage.js"
],
diff --git a/app/scripts/background.js b/app/scripts/background.js
index f077ca7a8..1b96d68b5 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -1,6 +1,8 @@
const urlUtil = require('url')
const endOfStream = require('end-of-stream')
const pipe = require('pump')
+const log = require('loglevel')
+const extension = require('extensionizer')
const LocalStorageStore = require('obs-store/lib/localStorage')
const storeTransform = require('obs-store/lib/transform')
const ExtensionPlatform = require('./platforms/extension')
@@ -9,13 +11,11 @@ const migrations = require('./migrations/')
const PortStream = require('./lib/port-stream.js')
const NotificationManager = require('./lib/notification-manager.js')
const MetamaskController = require('./metamask-controller')
-const extension = require('extensionizer')
const firstTimeState = require('./first-time-state')
const STORAGE_KEY = 'metamask-config'
const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
-const log = require('loglevel')
window.log = log
log.setDefaultLevel(METAMASK_DEBUG ? 'debug' : 'warn')
@@ -29,12 +29,12 @@ let popupIsOpen = false
const diskStore = new LocalStorageStore({ storageKey: STORAGE_KEY })
// initialization flow
-initialize().catch(console.error)
+initialize().catch(log.error)
async function initialize () {
const initState = await loadStateFromPersistence()
await setupController(initState)
- console.log('MetaMask initialization complete.')
+ log.debug('MetaMask initialization complete.')
}
//
diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js
index acacf5d4c..90a0f1f22 100644
--- a/app/scripts/contentscript.js
+++ b/app/scripts/contentscript.js
@@ -1,11 +1,12 @@
+const fs = require('fs')
+const path = require('path')
+const pump = require('pump')
const LocalMessageDuplexStream = require('post-message-stream')
const PongStream = require('ping-pong-stream/pong')
-const PortStream = require('./lib/port-stream.js')
-const ObjectMultiplex = require('./lib/obj-multiplex')
+const ObjectMultiplex = require('obj-multiplex')
const extension = require('extensionizer')
+const PortStream = require('./lib/port-stream.js')
-const fs = require('fs')
-const path = require('path')
const inpageText = fs.readFileSync(path.join(__dirname, 'inpage.js')).toString()
// Eventually this streaming injection could be replaced with:
@@ -50,22 +51,42 @@ function setupStreams () {
pageStream.pipe(pluginStream).pipe(pageStream)
// setup local multistream channels
- const mx = ObjectMultiplex()
- mx.on('error', console.error)
- mx.pipe(pageStream).pipe(mx)
- mx.pipe(pluginStream).pipe(mx)
+ const mux = new ObjectMultiplex()
+ pump(
+ mux,
+ pageStream,
+ mux,
+ (err) => logStreamDisconnectWarning('MetaMask Inpage', err)
+ )
+ pump(
+ mux,
+ pluginStream,
+ mux,
+ (err) => logStreamDisconnectWarning('MetaMask Background', err)
+ )
// connect ping stream
const pongStream = new PongStream({ objectMode: true })
- pongStream.pipe(mx.createStream('pingpong')).pipe(pongStream)
+ pump(
+ mux,
+ pongStream,
+ mux,
+ (err) => logStreamDisconnectWarning('MetaMask PingPongStream', err)
+ )
// connect phishing warning stream
- const phishingStream = mx.createStream('phishing')
+ const phishingStream = mux.createStream('phishing')
phishingStream.once('data', redirectToPhishingWarning)
// ignore unused channels (handled by background, inpage)
- mx.ignoreStream('provider')
- mx.ignoreStream('publicConfig')
+ mux.ignoreStream('provider')
+ mux.ignoreStream('publicConfig')
+}
+
+function logStreamDisconnectWarning (remoteLabel, err) {
+ let warningMsg = `MetamaskContentscript - lost connection to ${remoteLabel}`
+ if (err) warningMsg += '\n' + err.stack
+ console.warn(warningMsg)
}
function shouldInjectWeb3 () {
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index 58c468e22..fb3be6073 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -1,6 +1,5 @@
const EventEmitter = require('events')
const extend = require('xtend')
-const clone = require('clone')
const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util')
const EthQuery = require('ethjs-query')
@@ -8,6 +7,7 @@ const TxProviderUtil = require('../lib/tx-utils')
const PendingTransactionTracker = require('../lib/pending-tx-tracker')
const createId = require('../lib/random-id')
const NonceTracker = require('../lib/nonce-tracker')
+const txStateHistoryHelper = require('../lib/tx-state-history-helper')
module.exports = class TransactionController extends EventEmitter {
constructor (opts) {
@@ -33,6 +33,17 @@ module.exports = class TransactionController extends EventEmitter {
err: undefined,
})
},
+ getConfirmedTransactions: (address) => {
+ return this.getFilteredTxList({
+ from: address,
+ status: 'confirmed',
+ err: undefined,
+ })
+ },
+ giveUpOnTransaction: (txId) => {
+ const msg = `Gave up submitting after 3500 blocks un-mined.`
+ this.setTxStatusFailed(txId, msg)
+ },
})
this.query = new EthQuery(this.provider)
this.txProviderUtil = new TxProviderUtil(this.provider)
@@ -128,19 +139,17 @@ module.exports = class TransactionController extends EventEmitter {
updateTx (txMeta) {
// create txMeta snapshot for history
- const txMetaForHistory = clone(txMeta)
- // dont include previous history in this snapshot
- delete txMetaForHistory.history
- // add snapshot to tx history
- if (!txMeta.history) txMeta.history = []
- txMeta.history.push(txMetaForHistory)
-
+ const currentState = txStateHistoryHelper.snapshotFromTxMeta(txMeta)
+ // recover previous tx state obj
+ const previousState = txStateHistoryHelper.replayHistory(txMeta.history)
+ // generate history entry and add to history
+ const entry = txStateHistoryHelper.generateHistoryEntry(previousState, currentState)
+ txMeta.history.push(entry)
+
+ // commit txMeta to state
const txId = txMeta.id
const txList = this.getFullTxList()
const index = txList.findIndex(txData => txData.id === txId)
- if (!txMeta.history) txMeta.history = []
- txMeta.history.push(txMetaForHistory)
-
txList[index] = txMeta
this._saveTxList(txList)
this.emit('update')
@@ -148,16 +157,22 @@ module.exports = class TransactionController extends EventEmitter {
// Adds a tx to the txlist
addTx (txMeta) {
- const txCount = this.getTxCount()
- const network = this.getNetwork()
- const fullTxList = this.getFullTxList()
- const txHistoryLimit = this.txHistoryLimit
+ // initialize history
+ txMeta.history = []
+ // capture initial snapshot of txMeta for history
+ const snapshot = txStateHistoryHelper.snapshotFromTxMeta(txMeta)
+ txMeta.history.push(snapshot)
// checks if the length of the tx history is
// longer then desired persistence limit
// and then if it is removes only confirmed
// or rejected tx's.
// not tx's that are pending or unapproved
+ const txCount = this.getTxCount()
+ const network = this.getNetwork()
+ const fullTxList = this.getFullTxList()
+ const txHistoryLimit = this.txHistoryLimit
+
if (txCount > txHistoryLimit - 1) {
const index = fullTxList.findIndex((metaTx) => ((metaTx.status === 'confirmed' || metaTx.status === 'rejected') && network === txMeta.metamaskNetworkId))
fullTxList.splice(index, 1)
@@ -206,7 +221,6 @@ module.exports = class TransactionController extends EventEmitter {
status: 'unapproved',
metamaskNetworkId: this.getNetwork(),
txParams: txParams,
- history: [],
}
// add default tx params
await this.addTxDefaults(txMeta)
@@ -441,4 +455,4 @@ module.exports = class TransactionController extends EventEmitter {
})
this.memStore.updateState({ unapprovedTxs, selectedAddressTxList })
}
-} \ No newline at end of file
+}
diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js
index 2edc8060e..fd57fac70 100644
--- a/app/scripts/keyring-controller.js
+++ b/app/scripts/keyring-controller.js
@@ -171,9 +171,9 @@ class KeyringController extends EventEmitter {
return this.setupAccounts(checkedAccounts)
})
.then(() => this.persistAllKeyrings())
+ .then(() => this._updateMemStoreKeyrings())
.then(() => this.fullUpdate())
.then(() => {
- this._updateMemStoreKeyrings()
return keyring
})
}
@@ -208,6 +208,7 @@ class KeyringController extends EventEmitter {
return selectedKeyring.addAccounts(1)
.then(this.setupAccounts.bind(this))
.then(this.persistAllKeyrings.bind(this))
+ .then(this._updateMemStoreKeyrings.bind(this))
.then(this.fullUpdate.bind(this))
}
diff --git a/app/scripts/lib/auto-reload.js b/app/scripts/lib/auto-reload.js
index 6abce73ea..cce31c3d2 100644
--- a/app/scripts/lib/auto-reload.js
+++ b/app/scripts/lib/auto-reload.js
@@ -2,33 +2,55 @@ module.exports = setupDappAutoReload
function setupDappAutoReload (web3, observable) {
// export web3 as a global, checking for usage
+ let hasBeenWarned = false
+ let reloadInProgress = false
+ let lastTimeUsed
+ let lastSeenNetwork
+
global.web3 = new Proxy(web3, {
- get: (_web3, name) => {
- // get the time of use
- if (name !== '_used') {
- console.warn('MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider \nhttps://github.com/ethereum/mist/releases/tag/v0.9.0')
- _web3._used = Date.now()
+ get: (_web3, key) => {
+ // show warning once on web3 access
+ if (!hasBeenWarned && key !== 'currentProvider') {
+ console.warn('MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider \nhttps://github.com/MetaMask/faq/blob/master/detecting_metamask.md#web3-deprecation')
+ hasBeenWarned = true
}
- return _web3[name]
+ // get the time of use
+ lastTimeUsed = Date.now()
+ // return value normally
+ return _web3[key]
},
- set: (_web3, name, value) => {
- _web3[name] = value
+ set: (_web3, key, value) => {
+ // set value normally
+ _web3[key] = value
},
})
- var networkVersion
observable.subscribe(function (state) {
- // get the initial network
- const curentNetVersion = state.networkVersion
- if (!networkVersion) networkVersion = curentNetVersion
-
- if (curentNetVersion !== networkVersion && web3._used) {
- const timeSinceUse = Date.now() - web3._used
- // if web3 was recently used then delay the reloading of the page
- timeSinceUse > 500 ? triggerReset() : setTimeout(triggerReset, 500)
- // prevent reentry into if statement if state updates again before
- // reload
- networkVersion = curentNetVersion
+ // if reload in progress, no need to check reload logic
+ if (reloadInProgress) return
+
+ const currentNetwork = state.networkVersion
+
+ // set the initial network
+ if (!lastSeenNetwork) {
+ lastSeenNetwork = currentNetwork
+ return
+ }
+
+ // skip reload logic if web3 not used
+ if (!lastTimeUsed) return
+
+ // if network did not change, exit
+ if (currentNetwork === lastSeenNetwork) return
+
+ // initiate page reload
+ reloadInProgress = true
+ const timeSinceUse = Date.now() - lastTimeUsed
+ // if web3 was recently used then delay the reloading of the page
+ if (timeSinceUse > 500) {
+ triggerReset()
+ } else {
+ setTimeout(triggerReset, 500)
}
})
}
diff --git a/app/scripts/lib/createLoggerMiddleware.js b/app/scripts/lib/createLoggerMiddleware.js
new file mode 100644
index 000000000..b92a965de
--- /dev/null
+++ b/app/scripts/lib/createLoggerMiddleware.js
@@ -0,0 +1,15 @@
+// log rpc activity
+module.exports = createLoggerMiddleware
+
+function createLoggerMiddleware({ origin }) {
+ return function loggerMiddleware (req, res, next, end) {
+ next((cb) => {
+ if (res.error) {
+ log.error('Error in RPC response:\n', res)
+ }
+ if (req.isMetamaskInternal) return
+ log.info(`RPC (${origin}):`, req, '->', res)
+ cb()
+ })
+ }
+} \ No newline at end of file
diff --git a/app/scripts/lib/createOriginMiddleware.js b/app/scripts/lib/createOriginMiddleware.js
new file mode 100644
index 000000000..e1e097cc4
--- /dev/null
+++ b/app/scripts/lib/createOriginMiddleware.js
@@ -0,0 +1,9 @@
+// append dapp origin domain to request
+module.exports = createOriginMiddleware
+
+function createOriginMiddleware({ origin }) {
+ return function originMiddleware (req, res, next, end) {
+ req.origin = origin
+ next()
+ }
+} \ No newline at end of file
diff --git a/app/scripts/lib/createProviderMiddleware.js b/app/scripts/lib/createProviderMiddleware.js
new file mode 100644
index 000000000..6dd192411
--- /dev/null
+++ b/app/scripts/lib/createProviderMiddleware.js
@@ -0,0 +1,13 @@
+
+module.exports = createProviderMiddleware
+
+// forward requests to provider
+function createProviderMiddleware({ provider }) {
+ return (req, res, next, end) => {
+ provider.sendAsync(req, (err, _res) => {
+ if (err) return end(err)
+ res.result = _res.result
+ end()
+ })
+ }
+} \ No newline at end of file
diff --git a/app/scripts/lib/inpage-provider.js b/app/scripts/lib/inpage-provider.js
index fd032a673..da75c4be2 100644
--- a/app/scripts/lib/inpage-provider.js
+++ b/app/scripts/lib/inpage-provider.js
@@ -1,8 +1,9 @@
-const pipe = require('pump')
-const StreamProvider = require('web3-stream-provider')
+const pump = require('pump')
+const RpcEngine = require('json-rpc-engine')
+const createIdRemapMiddleware = require('json-rpc-engine/src/idRemapMiddleware')
+const createStreamMiddleware = require('json-rpc-middleware-stream')
const LocalStorageStore = require('obs-store')
-const ObjectMultiplex = require('./obj-multiplex')
-const createRandomId = require('./random-id')
+const ObjectMultiplex = require('obj-multiplex')
module.exports = MetamaskInpageProvider
@@ -10,60 +11,49 @@ function MetamaskInpageProvider (connectionStream) {
const self = this
// setup connectionStream multiplexing
- var multiStream = self.multiStream = ObjectMultiplex()
- pipe(
+ const mux = self.mux = new ObjectMultiplex()
+ pump(
connectionStream,
- multiStream,
+ mux,
connectionStream,
(err) => logStreamDisconnectWarning('MetaMask', err)
)
// subscribe to metamask public config (one-way)
self.publicConfigStore = new LocalStorageStore({ storageKey: 'MetaMask-Config' })
- pipe(
- multiStream.createStream('publicConfig'),
+ pump(
+ mux.createStream('publicConfig'),
self.publicConfigStore,
(err) => logStreamDisconnectWarning('MetaMask PublicConfigStore', err)
)
// ignore phishing warning message (handled elsewhere)
- multiStream.ignoreStream('phishing')
+ mux.ignoreStream('phishing')
// connect to async provider
- const asyncProvider = self.asyncProvider = new StreamProvider()
- pipe(
- asyncProvider,
- multiStream.createStream('provider'),
- asyncProvider,
+ const streamMiddleware = createStreamMiddleware()
+ pump(
+ streamMiddleware.stream,
+ mux.createStream('provider'),
+ streamMiddleware.stream,
(err) => logStreamDisconnectWarning('MetaMask RpcProvider', err)
)
- // start and stop polling to unblock first block lock
-
- self.idMap = {}
- // handle sendAsync requests via asyncProvider
- self.sendAsync = function (payload, cb) {
- // rewrite request ids
- var request = eachJsonMessage(payload, (message) => {
- var newId = createRandomId()
- self.idMap[newId] = message.id
- message.id = newId
- return message
- })
- // forward to asyncProvider
- asyncProvider.sendAsync(request, function (err, res) {
- if (err) return cb(err)
- // transform messages to original ids
- eachJsonMessage(res, (message) => {
- var oldId = self.idMap[message.id]
- delete self.idMap[message.id]
- message.id = oldId
- return message
- })
- cb(null, res)
- })
- }
+
+ // handle sendAsync requests via dapp-side rpc engine
+ const rpcEngine = new RpcEngine()
+ rpcEngine.push(createIdRemapMiddleware())
+ rpcEngine.push(streamMiddleware)
+ self.rpcEngine = rpcEngine
+}
+
+// handle sendAsync requests via asyncProvider
+// also remap ids inbound and outbound
+MetamaskInpageProvider.prototype.sendAsync = function (payload, cb) {
+ const self = this
+ self.rpcEngine.handle(payload, cb)
}
+
MetamaskInpageProvider.prototype.send = function (payload) {
const self = this
@@ -80,7 +70,7 @@ MetamaskInpageProvider.prototype.send = function (payload) {
case 'eth_coinbase':
// read from localStorage
selectedAddress = self.publicConfigStore.getState().selectedAddress
- result = selectedAddress
+ result = selectedAddress || null
break
case 'eth_uninstallFilter':
@@ -90,7 +80,7 @@ MetamaskInpageProvider.prototype.send = function (payload) {
case 'net_version':
const networkVersion = self.publicConfigStore.getState().networkVersion
- result = networkVersion
+ result = networkVersion || null
break
// throw not-supported Error
@@ -109,10 +99,6 @@ MetamaskInpageProvider.prototype.send = function (payload) {
}
}
-MetamaskInpageProvider.prototype.sendAsync = function () {
- throw new Error('MetamaskInpageProvider - sendAsync not overwritten')
-}
-
MetamaskInpageProvider.prototype.isConnected = function () {
return true
}
@@ -121,14 +107,6 @@ MetamaskInpageProvider.prototype.isMetaMask = true
// util
-function eachJsonMessage (payload, transformFn) {
- if (Array.isArray(payload)) {
- return payload.map(transformFn)
- } else {
- return transformFn(payload)
- }
-}
-
function logStreamDisconnectWarning (remoteLabel, err) {
let warningMsg = `MetamaskInpageProvider - lost connection to ${remoteLabel}`
if (err) warningMsg += '\n' + err.stack
diff --git a/app/scripts/lib/nonce-tracker.js b/app/scripts/lib/nonce-tracker.js
index 8328e81ec..0029ac953 100644
--- a/app/scripts/lib/nonce-tracker.js
+++ b/app/scripts/lib/nonce-tracker.js
@@ -1,13 +1,14 @@
-const EthQuery = require('eth-query')
+const EthQuery = require('ethjs-query')
const assert = require('assert')
const Mutex = require('await-semaphore').Mutex
class NonceTracker {
- constructor ({ provider, getPendingTransactions }) {
+ constructor ({ provider, getPendingTransactions, getConfirmedTransactions }) {
this.provider = provider
this.ethQuery = new EthQuery(provider)
this.getPendingTransactions = getPendingTransactions
+ this.getConfirmedTransactions = getConfirmedTransactions
this.lockMap = {}
}
@@ -25,21 +26,28 @@ class NonceTracker {
await this._globalMutexFree()
// await lock free, then take lock
const releaseLock = await this._takeMutex(address)
- // calculate next nonce
- // we need to make sure our base count
- // and pending count are from the same block
- const currentBlock = await this._getCurrentBlock()
- const pendingTransactions = this.getPendingTransactions(address)
- const pendingCount = pendingTransactions.length
- assert(Number.isInteger(pendingCount), `nonce-tracker - pendingCount is not an integer - got: (${typeof pendingCount}) "${pendingCount}"`)
- const baseCountHex = await this._getTxCount(address, currentBlock)
- const baseCount = parseInt(baseCountHex, 16)
- assert(Number.isInteger(baseCount), `nonce-tracker - baseCount is not an integer - got: (${typeof baseCount}) "${baseCount}"`)
- const nextNonce = baseCount + pendingCount
+ // evaluate multiple nextNonce strategies
+ const nonceDetails = {}
+ const networkNonceResult = await this._getNetworkNextNonce(address)
+ const highestLocallyConfirmed = this._getHighestLocallyConfirmed(address)
+ const nextNetworkNonce = networkNonceResult.nonce
+ const highestLocalNonce = highestLocallyConfirmed
+ const highestSuggested = Math.max(nextNetworkNonce, highestLocalNonce)
+
+ const pendingTxs = this.getPendingTransactions(address)
+ const localNonceResult = this._getHighestContinuousFrom(pendingTxs, highestSuggested) || 0
+
+ nonceDetails.params = {
+ highestLocalNonce,
+ highestSuggested,
+ nextNetworkNonce,
+ }
+ nonceDetails.local = localNonceResult
+ nonceDetails.network = networkNonceResult
+
+ const nextNonce = Math.max(networkNonceResult.nonce, localNonceResult.nonce)
assert(Number.isInteger(nextNonce), `nonce-tracker - nextNonce is not an integer - got: (${typeof nextNonce}) "${nextNonce}"`)
- // collect the numbers used to calculate the nonce for debugging
- const blockNumber = currentBlock.number
- const nonceDetails = { blockNumber, baseCount, baseCountHex, pendingCount }
+
// return nonce and release cb
return { nextNonce, nonceDetails, releaseLock }
}
@@ -53,15 +61,6 @@ class NonceTracker {
})
}
- async _getTxCount (address, currentBlock) {
- const blockNumber = currentBlock.number
- return new Promise((resolve, reject) => {
- this.ethQuery.getTransactionCount(address, blockNumber, (err, result) => {
- err ? reject(err) : resolve(result)
- })
- })
- }
-
async _globalMutexFree () {
const globalMutex = this._lookupMutex('global')
const release = await globalMutex.acquire()
@@ -83,12 +82,68 @@ class NonceTracker {
return mutex
}
+ async _getNetworkNextNonce (address) {
+ // calculate next nonce
+ // we need to make sure our base count
+ // and pending count are from the same block
+ const currentBlock = await this._getCurrentBlock()
+ const blockNumber = currentBlock.blockNumber
+ const baseCountBN = await this.ethQuery.getTransactionCount(address, blockNumber || 'latest')
+ const baseCount = baseCountBN.toNumber()
+ assert(Number.isInteger(baseCount), `nonce-tracker - baseCount is not an integer - got: (${typeof baseCount}) "${baseCount}"`)
+ const nonceDetails = { blockNumber, baseCount }
+ return { name: 'network', nonce: baseCount, details: nonceDetails }
+ }
+
+ _getHighestLocallyConfirmed (address) {
+ const confirmedTransactions = this.getConfirmedTransactions(address)
+ const highest = this._getHighestNonce(confirmedTransactions)
+ return Number.isInteger(highest) ? highest + 1 : 0
+ }
+
+ _reduceTxListToUniqueNonces (txList) {
+ const reducedTxList = txList.reduce((reducedList, txMeta, index) => {
+ if (!index) return [txMeta]
+ const nonceMatches = txList.filter((txData) => {
+ return txMeta.txParams.nonce === txData.txParams.nonce
+ })
+ if (nonceMatches.length > 1) return reducedList
+ reducedList.push(txMeta)
+ return reducedList
+ }, [])
+ return reducedTxList
+ }
+
+ _getHighestNonce (txList) {
+ const nonces = txList.map((txMeta) => {
+ const nonce = txMeta.txParams.nonce
+ assert(typeof nonce, 'string', 'nonces should be hex strings')
+ return parseInt(nonce, 16)
+ })
+ const highestNonce = Math.max.apply(null, nonces)
+ return highestNonce
+ }
+
+ _getHighestContinuousFrom (txList, startPoint) {
+ const nonces = txList.map((txMeta) => {
+ const nonce = txMeta.txParams.nonce
+ assert(typeof nonce, 'string', 'nonces should be hex strings')
+ return parseInt(nonce, 16)
+ })
+
+ let highest = startPoint
+ while (nonces.includes(highest)) {
+ highest++
+ }
+
+ return { name: 'local', nonce: highest, details: { startPoint, highest } }
+ }
+
// this is a hotfix for the fact that the blockTracker will
// change when the network changes
_getBlockTracker () {
return this.provider._blockTracker
}
-
}
module.exports = NonceTracker
diff --git a/app/scripts/lib/obj-multiplex.js b/app/scripts/lib/obj-multiplex.js
deleted file mode 100644
index 0034febe0..000000000
--- a/app/scripts/lib/obj-multiplex.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const through = require('through2')
-
-module.exports = ObjectMultiplex
-
-function ObjectMultiplex (opts) {
- opts = opts || {}
- // create multiplexer
- const mx = through.obj(function (chunk, enc, cb) {
- const name = chunk.name
- const data = chunk.data
- if (!name) {
- console.warn(`ObjectMultiplex - Malformed chunk without name "${chunk}"`)
- return cb()
- }
- const substream = mx.streams[name]
- if (!substream) {
- console.warn(`ObjectMultiplex - orphaned data for stream "${name}"`)
- } else {
- if (substream.push) substream.push(data)
- }
- return cb()
- })
- mx.streams = {}
- // create substreams
- mx.createStream = function (name) {
- const substream = mx.streams[name] = through.obj(function (chunk, enc, cb) {
- mx.push({
- name: name,
- data: chunk,
- })
- return cb()
- })
- mx.on('end', function () {
- return substream.emit('end')
- })
- if (opts.error) {
- mx.on('error', function () {
- return substream.emit('error')
- })
- }
- return substream
- }
- // ignore streams (dont display orphaned data warning)
- mx.ignoreStream = function (name) {
- mx.streams[name] = true
- }
- return mx
-}
diff --git a/app/scripts/lib/pending-tx-tracker.js b/app/scripts/lib/pending-tx-tracker.js
index 19720db3f..b90851b58 100644
--- a/app/scripts/lib/pending-tx-tracker.js
+++ b/app/scripts/lib/pending-tx-tracker.js
@@ -1,6 +1,7 @@
const EventEmitter = require('events')
const EthQuery = require('ethjs-query')
const sufficientBalance = require('./util').sufficientBalance
+const RETRY_LIMIT = 3500 // Retry 3500 blocks, or about 1 day.
/*
Utility class for tracking the transactions as they
@@ -28,6 +29,7 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
this.getBalance = config.getBalance
this.getPendingTransactions = config.getPendingTransactions
this.publishTransaction = config.publishTransaction
+ this.giveUpOnTransaction = config.giveUpOnTransaction
}
// checks if a signed tx is in a block and
@@ -100,6 +102,10 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
if (balance === undefined) return
if (!('retryCount' in txMeta)) txMeta.retryCount = 0
+ if (txMeta.retryCount > RETRY_LIMIT) {
+ return this.giveUpOnTransaction(txMeta.id)
+ }
+
// if the value of the transaction is greater then the balance, fail.
if (!sufficientBalance(txMeta.txParams, balance)) {
const insufficientFundsError = new Error('Insufficient balance during rebroadcast.')
@@ -160,4 +166,4 @@ module.exports = class PendingTransactionTracker extends EventEmitter {
}
nonceGlobalLock.releaseLock()
}
-} \ No newline at end of file
+}
diff --git a/app/scripts/lib/port-stream.js b/app/scripts/lib/port-stream.js
index 607a9c9ed..648d88087 100644
--- a/app/scripts/lib/port-stream.js
+++ b/app/scripts/lib/port-stream.js
@@ -1,5 +1,6 @@
const Duplex = require('readable-stream').Duplex
const inherits = require('util').inherits
+const noop = function(){}
module.exports = PortDuplexStream
@@ -20,20 +21,14 @@ PortDuplexStream.prototype._onMessage = function (msg) {
if (Buffer.isBuffer(msg)) {
delete msg._isBuffer
var data = new Buffer(msg)
- // console.log('PortDuplexStream - saw message as buffer', data)
this.push(data)
} else {
- // console.log('PortDuplexStream - saw message', msg)
this.push(msg)
}
}
PortDuplexStream.prototype._onDisconnect = function () {
- try {
- this.push(null)
- } catch (err) {
- this.emit('error', err)
- }
+ this.destroy()
}
// stream plumbing
@@ -45,19 +40,12 @@ PortDuplexStream.prototype._write = function (msg, encoding, cb) {
if (Buffer.isBuffer(msg)) {
var data = msg.toJSON()
data._isBuffer = true
- // console.log('PortDuplexStream - sent message as buffer', data)
this._port.postMessage(data)
} else {
- // console.log('PortDuplexStream - sent message', msg)
this._port.postMessage(msg)
}
} catch (err) {
- // console.error(err)
return cb(new Error('PortDuplexStream - disconnected'))
}
cb()
}
-
-// util
-
-function noop () {}
diff --git a/app/scripts/lib/stream-utils.js b/app/scripts/lib/stream-utils.js
index ba79990cc..8bb0b4f3c 100644
--- a/app/scripts/lib/stream-utils.js
+++ b/app/scripts/lib/stream-utils.js
@@ -1,6 +1,6 @@
const Through = require('through2')
-const endOfStream = require('end-of-stream')
-const ObjectMultiplex = require('./obj-multiplex')
+const ObjectMultiplex = require('obj-multiplex')
+const pump = require('pump')
module.exports = {
jsonParseStream: jsonParseStream,
@@ -23,14 +23,14 @@ function jsonStringifyStream () {
}
function setupMultiplex (connectionStream) {
- var mx = ObjectMultiplex()
- connectionStream.pipe(mx).pipe(connectionStream)
- endOfStream(mx, function (err) {
- if (err) console.error(err)
- })
- endOfStream(connectionStream, function (err) {
- if (err) console.error(err)
- mx.destroy()
- })
- return mx
+ const mux = new ObjectMultiplex()
+ pump(
+ connectionStream,
+ mux,
+ connectionStream,
+ (err) => {
+ if (err) console.error(err)
+ }
+ )
+ return mux
}
diff --git a/app/scripts/lib/tx-state-history-helper.js b/app/scripts/lib/tx-state-history-helper.js
new file mode 100644
index 000000000..304069d57
--- /dev/null
+++ b/app/scripts/lib/tx-state-history-helper.js
@@ -0,0 +1,37 @@
+const jsonDiffer = require('fast-json-patch')
+const clone = require('clone')
+
+module.exports = {
+ generateHistoryEntry,
+ replayHistory,
+ snapshotFromTxMeta,
+ migrateFromSnapshotsToDiffs,
+}
+
+
+function migrateFromSnapshotsToDiffs(longHistory) {
+ return (
+ longHistory
+ // convert non-initial history entries into diffs
+ .map((entry, index) => {
+ if (index === 0) return entry
+ return generateHistoryEntry(longHistory[index - 1], entry)
+ })
+ )
+}
+
+function generateHistoryEntry(previousState, newState) {
+ return jsonDiffer.compare(previousState, newState)
+}
+
+function replayHistory(shortHistory) {
+ return shortHistory.reduce((val, entry) => jsonDiffer.applyPatch(val, entry).newDocument)
+}
+
+function snapshotFromTxMeta(txMeta) {
+ // create txMeta snapshot for history
+ const snapshot = clone(txMeta)
+ // dont include previous history in this snapshot
+ delete snapshot.history
+ return snapshot
+} \ No newline at end of file
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index a007d6fc5..fef16c3a9 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -1,12 +1,18 @@
const EventEmitter = require('events')
const extend = require('xtend')
const promiseToCallback = require('promise-to-callback')
-const pipe = require('pump')
+const pump = require('pump')
const Dnode = require('dnode')
const ObservableStore = require('obs-store')
const EthStore = require('./lib/eth-store')
const EthQuery = require('eth-query')
-const streamIntoProvider = require('web3-stream-provider/handler')
+const RpcEngine = require('json-rpc-engine')
+const debounce = require('debounce')
+const createEngineStream = require('json-rpc-middleware-stream/engineStream')
+const createFilterMiddleware = require('eth-json-rpc-filters')
+const createOriginMiddleware = require('./lib/createOriginMiddleware')
+const createLoggerMiddleware = require('./lib/createLoggerMiddleware')
+const createProviderMiddleware = require('./lib/createProviderMiddleware')
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
const KeyringController = require('./keyring-controller')
const NetworkController = require('./controllers/network')
@@ -24,8 +30,6 @@ const ConfigManager = require('./lib/config-manager')
const nodeify = require('./lib/nodeify')
const accountImporter = require('./account-import-strategies')
const getBuyEthUrl = require('./lib/buy-eth-url')
-const debounce = require('debounce')
-
const version = require('../manifest.json').version
module.exports = class MetamaskController extends EventEmitter {
@@ -77,12 +81,13 @@ module.exports = class MetamaskController extends EventEmitter {
// rpc provider
this.provider = this.initializeProvider()
+ this.blockTracker = this.provider
// eth data query tools
this.ethQuery = new EthQuery(this.provider)
this.ethStore = new EthStore({
provider: this.provider,
- blockTracker: this.provider,
+ blockTracker: this.blockTracker,
})
// key mgmt
@@ -109,7 +114,7 @@ module.exports = class MetamaskController extends EventEmitter {
getNetwork: this.networkController.getNetworkState.bind(this),
signTransaction: this.keyringController.signTransaction.bind(this.keyringController),
provider: this.provider,
- blockTracker: this.provider,
+ blockTracker: this.blockTracker,
ethQuery: this.ethQuery,
ethStore: this.ethStore,
})
@@ -337,36 +342,43 @@ module.exports = class MetamaskController extends EventEmitter {
setupUntrustedCommunication (connectionStream, originDomain) {
// Check if new connection is blacklisted
if (this.blacklistController.checkForPhishing(originDomain)) {
- console.log('MetaMask - sending phishing warning for', originDomain)
+ log.debug('MetaMask - sending phishing warning for', originDomain)
this.sendPhishingWarning(connectionStream, originDomain)
return
}
// setup multiplexing
- const mx = setupMultiplex(connectionStream)
+ const mux = setupMultiplex(connectionStream)
// connect features
- this.setupProviderConnection(mx.createStream('provider'), originDomain)
- this.setupPublicConfig(mx.createStream('publicConfig'))
+ this.setupProviderConnection(mux.createStream('provider'), originDomain)
+ this.setupPublicConfig(mux.createStream('publicConfig'))
}
setupTrustedCommunication (connectionStream, originDomain) {
// setup multiplexing
- const mx = setupMultiplex(connectionStream)
+ const mux = setupMultiplex(connectionStream)
// connect features
- this.setupControllerConnection(mx.createStream('controller'))
- this.setupProviderConnection(mx.createStream('provider'), originDomain)
+ this.setupControllerConnection(mux.createStream('controller'))
+ this.setupProviderConnection(mux.createStream('provider'), originDomain)
}
sendPhishingWarning (connectionStream, hostname) {
- const mx = setupMultiplex(connectionStream)
- const phishingStream = mx.createStream('phishing')
+ const mux = setupMultiplex(connectionStream)
+ const phishingStream = mux.createStream('phishing')
phishingStream.write({ hostname })
}
setupControllerConnection (outStream) {
const api = this.getApi()
const dnode = Dnode(api)
- outStream.pipe(dnode).pipe(outStream)
+ pump(
+ outStream,
+ dnode,
+ outStream,
+ (err) => {
+ if (err) log.error(err)
+ }
+ )
dnode.on('remote', (remote) => {
// push updates to popup
const sendUpdate = remote.sendUpdate.bind(remote)
@@ -374,27 +386,42 @@ module.exports = class MetamaskController extends EventEmitter {
})
}
- setupProviderConnection (outStream, originDomain) {
- streamIntoProvider(outStream, this.provider, onRequest, onResponse)
- // append dapp origin domain to request
- function onRequest (request) {
- request.origin = originDomain
- }
- // log rpc activity
- function onResponse (err, request, response) {
- if (err) return console.error(err)
- if (response.error) {
- console.error('Error in RPC response:\n', response)
+ setupProviderConnection (outStream, origin) {
+ // setup json rpc engine stack
+ const engine = new RpcEngine()
+
+ // create filter polyfill middleware
+ const filterMiddleware = createFilterMiddleware({
+ provider: this.provider,
+ blockTracker: this.blockTracker,
+ })
+
+ engine.push(createOriginMiddleware({ origin }))
+ engine.push(createLoggerMiddleware({ origin }))
+ engine.push(filterMiddleware)
+ engine.push(createProviderMiddleware({ provider: this.provider }))
+
+ // setup connection
+ const providerStream = createEngineStream({ engine })
+ pump(
+ outStream,
+ providerStream,
+ outStream,
+ (err) => {
+ // cleanup filter polyfill middleware
+ filterMiddleware.destroy()
+ if (err) log.error(err)
}
- if (request.isMetamaskInternal) return
- log.info(`RPC (${originDomain}):`, request, '->', response)
- }
+ )
}
setupPublicConfig (outStream) {
- pipe(
+ pump(
this.publicConfigStore,
- outStream
+ outStream,
+ (err) => {
+ if (err) log.error(err)
+ }
)
}
diff --git a/app/scripts/migrations/018.js b/app/scripts/migrations/018.js
new file mode 100644
index 000000000..d27fe3f46
--- /dev/null
+++ b/app/scripts/migrations/018.js
@@ -0,0 +1,52 @@
+const version = 18
+
+/*
+
+This migration updates "transaction state history" to diffs style
+
+*/
+
+const clone = require('clone')
+const txStateHistoryHelper = require('../lib/tx-state-history-helper')
+
+
+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
+ const transactions = newState.TransactionController.transactions
+ newState.TransactionController.transactions = transactions.map((txMeta) => {
+ // no history: initialize
+ if (!txMeta.history || txMeta.history.length === 0) {
+ const snapshot = txStateHistoryHelper.snapshotFromTxMeta(txMeta)
+ txMeta.history = [snapshot]
+ return txMeta
+ }
+ // has history: migrate
+ const newHistory = (
+ txStateHistoryHelper.migrateFromSnapshotsToDiffs(txMeta.history)
+ // remove empty diffs
+ .filter((entry) => {
+ return !Array.isArray(entry) || entry.length > 0
+ })
+ )
+ txMeta.history = newHistory
+ return txMeta
+ })
+ return newState
+}
diff --git a/app/scripts/migrations/019.js b/app/scripts/migrations/019.js
new file mode 100644
index 000000000..072c96370
--- /dev/null
+++ b/app/scripts/migrations/019.js
@@ -0,0 +1,83 @@
+
+const version = 19
+
+/*
+
+This migration sets transactions as failed
+whos nonce is too high
+
+*/
+
+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
+ const transactions = newState.TransactionController.transactions
+
+ newState.TransactionController.transactions = transactions.map((txMeta, _, txList) => {
+ if (txMeta.status !== 'submitted') return txMeta
+
+ const confirmedTxs = txList.filter((tx) => tx.status === 'confirmed')
+ .filter((tx) => tx.txParams.from === txMeta.txParams.from)
+ .filter((tx) => tx.metamaskNetworkId.from === txMeta.metamaskNetworkId.from)
+ const highestConfirmedNonce = getHighestNonce(confirmedTxs)
+
+ const pendingTxs = txList.filter((tx) => tx.status === 'submitted')
+ .filter((tx) => tx.txParams.from === txMeta.txParams.from)
+ .filter((tx) => tx.metamaskNetworkId.from === txMeta.metamaskNetworkId.from)
+ const highestContinuousNonce = getHighestContinuousFrom(pendingTxs, highestConfirmedNonce)
+
+ const maxNonce = Math.max(highestContinuousNonce, highestConfirmedNonce)
+
+ if (parseInt(txMeta.txParams.nonce, 16) > maxNonce + 1) {
+ txMeta.status = 'failed'
+ txMeta.err = {
+ message: 'nonce too high',
+ note: 'migration 019 custom error',
+ }
+ }
+ return txMeta
+ })
+ return newState
+}
+
+function getHighestContinuousFrom (txList, startPoint) {
+ const nonces = txList.map((txMeta) => {
+ const nonce = txMeta.txParams.nonce
+ return parseInt(nonce, 16)
+ })
+
+ let highest = startPoint
+ while (nonces.includes(highest)) {
+ highest++
+ }
+
+ return highest
+}
+
+function getHighestNonce (txList) {
+ const nonces = txList.map((txMeta) => {
+ const nonce = txMeta.txParams.nonce
+ return parseInt(nonce || '0x0', 16)
+ })
+ const highestNonce = Math.max.apply(null, nonces)
+ return highestNonce
+}
+
diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js
index f4c87499f..e9cbd7b98 100644
--- a/app/scripts/migrations/index.js
+++ b/app/scripts/migrations/index.js
@@ -28,4 +28,6 @@ module.exports = [
require('./015'),
require('./016'),
require('./017'),
+ require('./018'),
+ require('./019'),
]
diff --git a/circle.yml b/circle.yml
index 2ea60bb9d..f5da6857d 100644
--- a/circle.yml
+++ b/circle.yml
@@ -1,10 +1,17 @@
machine:
node:
version: 8.1.4
-dependencies:
- pre:
- - "npm i -g testem"
- - "npm i -g mocha"
test:
override:
- - "npm run ci" \ No newline at end of file
+ - "npm run ci"
+dependencies:
+ pre:
+ - sudo apt-get update
+ # get latest stable firefox
+ - sudo apt-get install firefox
+ - firefox_cmd=`which firefox`; sudo rm -f $firefox_cmd; sudo ln -s `which firefox.ubuntu` $firefox_cmd
+ # get latest stable chrome
+ - wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
+ - sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
+ - sudo apt-get update
+ - sudo apt-get install google-chrome-stable \ No newline at end of file
diff --git a/development/uiStore.js b/development/uiStore.js
index 1299ee1dc..c71d66d3b 100644
--- a/development/uiStore.js
+++ b/development/uiStore.js
@@ -1,7 +1,7 @@
const createStore = require('redux').createStore
const applyMiddleware = require('redux').applyMiddleware
-const thunkMiddleware = require('redux-thunk')
-const createLogger = require('redux-logger')
+const thunkMiddleware = require('redux-thunk').default
+const createLogger = require('redux-logger').createLogger
const rootReducer = require('../ui/app/reducers')
module.exports = configureStore
diff --git a/docs/add-to-firef.md b/docs/add-to-firefox.md
index 593d06170..593d06170 100644
--- a/docs/add-to-firef.md
+++ b/docs/add-to-firefox.md
diff --git a/karma.conf.js b/karma.conf.js
new file mode 100644
index 000000000..8e6d55972
--- /dev/null
+++ b/karma.conf.js
@@ -0,0 +1,61 @@
+// Karma configuration
+// Generated on Mon Sep 11 2017 18:45:48 GMT-0700 (PDT)
+
+module.exports = function(config) {
+ config.set({
+ // base path that will be used to resolve all patterns (eg. files, exclude)
+ basePath: process.cwd(),
+
+ browserConsoleLogOptions: {
+ terminal: false,
+ },
+
+ // frameworks to use
+ // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
+ frameworks: ['qunit'],
+
+ // list of files / patterns to load in the browser
+ files: [
+ 'development/bundle.js',
+ 'test/integration/jquery-3.1.0.min.js',
+ 'test/integration/bundle.js',
+ { pattern: 'dist/chrome/images/**/*.*', watched: false, included: false, served: true },
+ { pattern: 'dist/chrome/fonts/**/*.*', watched: false, included: false, served: true },
+ ],
+
+ proxies: {
+ '/images/': '/base/dist/chrome/images/',
+ '/fonts/': '/base/dist/chrome/fonts/',
+ },
+
+ // test results reporter to use
+ // possible values: 'dots', 'progress'
+ // available reporters: https://npmjs.org/browse/keyword/karma-reporter
+ reporters: ['progress'],
+
+ // web server port
+ port: 9876,
+
+ // enable / disable colors in the output (reporters and logs)
+ colors: true,
+
+ // level of logging
+ // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+ logLevel: config.LOG_INFO,
+
+ // enable / disable watching file and executing tests whenever any file changes
+ autoWatch: false,
+
+ // start these browsers
+ // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
+ browsers: ['Chrome', 'Firefox'],
+
+ // Continuous Integration mode
+ // if true, Karma captures browsers, runs the tests and exits
+ singleRun: true,
+
+ // Concurrency level
+ // how many browser should be started simultaneous
+ concurrency: Infinity
+ })
+}
diff --git a/mascara/src/lib/setup-iframe.js b/mascara/src/lib/setup-iframe.js
index db67163df..dcf404574 100644
--- a/mascara/src/lib/setup-iframe.js
+++ b/mascara/src/lib/setup-iframe.js
@@ -1,5 +1,5 @@
const Iframe = require('iframe')
-const IframeStream = require('iframe-stream').IframeStream
+const createIframeStream = require('iframe-stream').IframeStream
module.exports = setupIframe
@@ -13,7 +13,7 @@ function setupIframe(opts) {
})
var iframe = frame.iframe
iframe.style.setProperty('display', 'none')
- var iframeStream = new IframeStream(iframe)
+ var iframeStream = createIframeStream(iframe)
return iframeStream
}
diff --git a/mascara/src/proxy.js b/mascara/src/proxy.js
index eabc547b4..5b95175f1 100644
--- a/mascara/src/proxy.js
+++ b/mascara/src/proxy.js
@@ -1,4 +1,4 @@
-const ParentStream = require('iframe-stream').ParentStream
+const createParentStream = require('iframe-stream').ParentStream
const SWcontroller = require('client-sw-ready-event/lib/sw-client.js')
const SwStream = require('sw-stream/lib/sw-stream.js')
const SetupUntrustedComunication = ('./lib/setup-untrusted-connection.js')
@@ -11,7 +11,7 @@ const background = new SWcontroller({
intervalDelay,
})
-const pageStream = new ParentStream()
+const pageStream = createParentStream()
background.on('ready', (_) => {
let swStream = SwStream({
serviceWorker: background.controller,
diff --git a/mock-dev.js b/mock-dev.js
index 8e1923a82..b6652bdf7 100644
--- a/mock-dev.js
+++ b/mock-dev.js
@@ -85,40 +85,47 @@ actions.update = function(stateName) {
var css = MetaMaskUiCss()
injectCss(css)
-const container = document.querySelector('#app-content')
-
// parse opts
var store = configureStore(firstState)
// start app
-render(
- h('.super-dev-container', [
-
- h('button', {
- onClick: (ev) => {
- ev.preventDefault()
- store.dispatch(actions.update('terms'))
- },
- style: {
- margin: '19px 19px 0px 19px',
- },
- }, 'Reset State'),
-
- h(Selector, { actions, selectedKey: selectedView, states, store }),
-
- h('.mock-app-root', {
- style: {
- height: '500px',
- width: '360px',
- boxShadow: 'grey 0px 2px 9px',
- margin: '20px',
- },
- }, [
- h(Root, {
- store: store,
- }),
- ]),
-
- ]
-), container)
-
+startApp()
+
+function startApp(){
+ const body = document.body
+ const container = document.createElement('div')
+ container.id = 'app-content'
+ body.appendChild(container)
+ console.log('container', container)
+
+ render(
+ h('.super-dev-container', [
+
+ h('button', {
+ onClick: (ev) => {
+ ev.preventDefault()
+ store.dispatch(actions.update('terms'))
+ },
+ style: {
+ margin: '19px 19px 0px 19px',
+ },
+ }, 'Reset State'),
+
+ h(Selector, { actions, selectedKey: selectedView, states, store }),
+
+ h('.mock-app-root', {
+ style: {
+ height: '500px',
+ width: '360px',
+ boxShadow: 'grey 0px 2px 9px',
+ margin: '20px',
+ },
+ }, [
+ h(Root, {
+ store: store,
+ }),
+ ]),
+
+ ]
+ ), container)
+}
diff --git a/package.json b/package.json
index 15cb058ec..9d72360df 100644
--- a/package.json
+++ b/package.json
@@ -12,8 +12,8 @@
"test": "npm run lint && npm run test-unit && npm run test-integration",
"test-unit": "METAMASK_ENV=test mocha --require test/helper.js --recursive \"test/unit/**/*.js\"",
"single-test": "METAMASK_ENV=test mocha --require test/helper.js",
- "test-integration": "npm run buildMock && npm run buildCiUnits && testem ci -P 2",
- "test-coverage": "nyc npm run test-unit && nyc report --reporter=text-lcov | coveralls",
+ "test-integration": "npm run buildMock && npm run buildCiUnits && karma start",
+ "test-coverage": "nyc npm run test-unit && if [ $COVERALLS_REPO_TOKEN ]; then nyc report --reporter=text-lcov | coveralls; fi",
"ci": "npm run lint && npm run test-coverage && npm run test-integration",
"lint": "gulp lint",
"buildCiUnits": "node test/integration/index.js",
@@ -22,7 +22,6 @@
"ui": "npm run genStates && beefy ui-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./",
"mock": "beefy mock-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./",
"buildMock": "npm run genStates && browserify ./mock-dev.js -o ./development/bundle.js",
- "testem": "npm run buildMock && testem",
"announce": "node development/announcer.js",
"generateNotice": "node notices/notice-generator.js",
"deleteNotice": "node notices/notice-delete.js",
@@ -74,11 +73,12 @@
"eth-bin-to-ops": "^1.0.1",
"eth-contract-metadata": "^1.1.4",
"eth-hd-keyring": "^1.1.1",
+ "eth-json-rpc-filters": "^1.1.0",
"eth-phishing-detect": "^1.1.4",
"eth-query": "^2.1.2",
"eth-sig-util": "^1.2.2",
"eth-simple-keyring": "^1.1.1",
- "eth-token-tracker": "^1.1.2",
+ "eth-token-tracker": "^1.1.3",
"ethereumjs-tx": "^1.3.0",
"ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
"ethereumjs-wallet": "^0.6.0",
@@ -88,6 +88,7 @@
"express": "^4.14.0",
"extension-link-enabler": "^1.0.0",
"extensionizer": "^1.0.0",
+ "fast-json-patch": "^2.0.4",
"fast-levenshtein": "^2.0.6",
"gulp": "github:gulpjs/gulp#4.0",
"gulp-autoprefixer": "^4.0.0",
@@ -101,12 +102,15 @@
"iframe-stream": "^3.0.0",
"inject-css": "^0.1.1",
"jazzicon": "^1.2.0",
+ "json-rpc-engine": "^3.1.0",
+ "json-rpc-middleware-stream": "^1.0.0",
"loglevel": "^1.4.1",
"metamask-logo": "^2.1.2",
"mississippi": "^1.2.0",
"mkdirp": "^0.5.1",
"multiplex": "^6.7.0",
"number-to-bn": "^1.7.0",
+ "obj-multiplex": "^1.0.0",
"obs-store": "^2.3.1",
"once": "^1.3.3",
"ping-pong-stream": "^1.0.0",
@@ -130,7 +134,7 @@
"react-tooltip-component": "^0.3.0",
"react-transition-group": "^2.2.0",
"reactify": "^1.1.1",
- "readable-stream": "^2.1.2",
+ "readable-stream": "^2.3.3",
"redux": "^3.0.5",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.2.0",
@@ -150,7 +154,7 @@
},
"devDependencies": {
"babel-core": "^6.24.1",
- "babel-eslint": "^7.2.3",
+ "babel-eslint": "^8.0.0",
"babel-plugin-transform-async-to-generator": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-polyfill": "^6.23.0",
@@ -186,6 +190,11 @@
"jsdom-global": "^3.0.2",
"jshint-stylish": "~2.2.1",
"json-rpc-engine": "^3.0.1",
+ "karma": "^1.7.1",
+ "karma-chrome-launcher": "^2.2.0",
+ "karma-cli": "^1.0.1",
+ "karma-firefox-launcher": "^1.0.1",
+ "karma-qunit": "^1.2.1",
"lodash.assign": "^4.0.6",
"mocha": "^3.4.2",
"mocha-eslint": "^4.0.0",
@@ -200,8 +209,8 @@
"react-addons-test-utils": "^15.5.1",
"react-test-renderer": "^15.5.4",
"react-testutils-additions": "^15.2.0",
- "sinon": "^2.3.8",
"stylelint-config-standard": "^17.0.0",
+ "sinon": "^3.2.0",
"tape": "^4.5.1",
"testem": "^1.10.3",
"uglifyify": "^4.0.2",
diff --git a/test/data/v17-long-history.json b/test/data/v17-long-history.json
new file mode 100644
index 000000000..a33d425f8
--- /dev/null
+++ b/test/data/v17-long-history.json
@@ -0,0 +1,3053 @@
+{
+ "meta": {
+ "version": 17
+ },
+ "data": {
+ "config": {},
+ "NetworkController": {
+ "provider": {
+ "type": "ropsten",
+ "rpcTarget": "https://ropsten.infura.io/metamask"
+ },
+ "network": "3"
+ },
+ "NoticeController": {
+ "noticesList": [
+ {
+ "read": true,
+ "date": "Thu Feb 09 2017",
+ "title": "Terms of Use",
+ "body": "",
+ "id": 0
+ },
+ {
+ "read": true,
+ "date": "Mon May 08 2017",
+ "title": "Privacy Notice",
+ "body": "",
+ "id": 2
+ }
+ ]
+ },
+ "CurrencyController": {
+ "currentCurrency": "USD",
+ "conversionRate": 295.81988556,
+ "conversionDate": 1502734981
+ },
+ "KeyringController": {
+ "vault": "{\"data\":\"fFwVD3Msyq1o9NsDbjMlyJ1ZfoMcqfTgjR9cium0C5Vnpk9IM6f/RTVXfk0J4c4UkbgbKd++q8t1S+D22s7Ddz/BT/fe0GrbwPvAYQi1oJuOI9/Lf7I0JbESGv4PheijCIH4h/FiO+tIAuqM0Co3PULM4mOHdzXD8SWmzxbDGx+4wG84EQE9a1NEbqEjyqrX02h3NwZsjrSeuV5TibpGJB9vnKNpDu9wF0DVKLtLCG5n67uoTI/ve9Z7hIDa03vNi/71iE4avFb6ogE2SAkFDncEcU0xXVkBMapBXjrpe5sIq08Ddo0Hhi4fkd4yFW77sAH4TKzd6bWSn2AK8HL8Gpcrk4R6Cvv8EtyjUqsOJfE4AmYI6rWfFutLqEAp\",\"iv\":\"9fJ/OGDVwUnu3H0U71qOGA==\",\"salt\":\"5yGOu/+yrrb3DyP+cvMKIZqjhSjrEY+bnceHnz9n8gM=\"}",
+ "walletNicknames": {
+ "0x3ae39e89dc7e736cce53091057a45bf44b1a566c": "Account 1",
+ "0xa7a467edcb16a51976418ec6133f14f7939dc378": "Account 2",
+ "0x03ce38bd04b4ad7581a7070570381a530951ebbe": "Account 3"
+ }
+ },
+ "PreferencesController": {
+ "frequentRpcList": [],
+ "currentAccountTab": "history",
+ "tokens": [],
+ "selectedAddress": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c"
+ },
+ "seedWords": null,
+ "InfuraController": {
+ "infuraNetworkStatus": {
+ "mainnet": "degraded",
+ "ropsten": "ok",
+ "kovan": "ok",
+ "rinkeby": "ok"
+ }
+ },
+ "BlacklistController": {
+ "phishing": {
+ "version": 2,
+ "tolerance": 2,
+ "fuzzylist": [
+ "metamask.io",
+ "myetherwallet.com"
+ ],
+ "whitelist": [
+ "metamask.io",
+ "myetherwallet.com",
+ "ethereum.org",
+ "myetheroll.com",
+ "myetherapi.com",
+ "ledgerwallet.com",
+ "etherscan.io",
+ "etherid.org",
+ "ether.cards",
+ "etheroll.com",
+ "ethnews.com",
+ "ethex.market",
+ "ethereumdev.io",
+ "ethereumdev.kr",
+ "dether.io",
+ "ethermine.org",
+ "slaask.com",
+ "etherbtc.io",
+ "ethereal.capital",
+ "etherisc.com",
+ "m.famalk.net",
+ "etherecho.com",
+ "ethereum.os.tc",
+ "theethereum.wiki",
+ "metajack.im",
+ "etherhub.io",
+ "ethereum.network",
+ "ethereum.link",
+ "ethereum.com",
+ "prethereum.org",
+ "ethereumj.io",
+ "etheraus.com",
+ "ethereum.dev",
+ "1ethereum.ru",
+ "ethereum.nz",
+ "nethereum.com",
+ "metabank.com",
+ "metamas.com",
+ "metabase.com"
+ ],
+ "blacklist": [
+ "numerai.tech",
+ "decentraiand.org",
+ "blockcrein.info",
+ "blockchealn.info",
+ "bllookchain.info",
+ "blockcbhain.info",
+ "myetherwallet.com.ethpromonodes.com",
+ "mettamask.io",
+ "tokenswap.org",
+ "netherum.com",
+ "etherexx.org",
+ "etherume.io",
+ "ethereum.plus",
+ "ehtereum.org",
+ "etereurm.org",
+ "etheream.com",
+ "ethererum.org",
+ "ethereum.io",
+ "0xtoken.com",
+ "cryptoalliance.herokuapp.com",
+ "bitspark2.com",
+ "indorsetoken.com",
+ "bittreat.com",
+ "iconexus.tk",
+ "iconexus.ml",
+ "iconexus.ga",
+ "iconexus.cf",
+ "etherwallet.online",
+ "wallet-ethereum.net",
+ "bitsdigit.com",
+ "etherswap.org",
+ "eos.ac",
+ "uasfwallet.com",
+ "ziber.io",
+ "multiply-ethereum.info",
+ "bittrex.comze.com",
+ "karbon.vacau.com",
+ "etherdelta.gitlhub.io",
+ "etherdelta.glthub.io",
+ "digitaldevelopersfund.vacau.com",
+ "district-0x.io",
+ "coin-dash.com",
+ "coindash.ru",
+ "district0x.net",
+ "aragonproject.io",
+ "coin-wallet.info",
+ "coinswallet.info",
+ "contribute-status.im",
+ "ether-api.com",
+ "ether-wall.com",
+ "mycoinwallet.net",
+ "ethereumchamber.com",
+ "ethereumchamber.net",
+ "ethereumchest.com",
+ "myetherweb.com.de",
+ "myetherieumwallet.com",
+ "myetehrwallet.com",
+ "myeterwalet.com",
+ "myetherwaiiet.com",
+ "myetherwallet.info",
+ "myetherwallet.ch",
+ "myetherwallet.om",
+ "myethervallet.com",
+ "myetherwallet.com.cm",
+ "myetherwallet.com.co",
+ "myetherwallet.com.de",
+ "myetherwallet.com.gl",
+ "myetherwallet.com.im",
+ "myetherwallet.com.ua",
+ "secure-myetherwallet.com",
+ "update-myetherwallet.com",
+ "wwwmyetherwallet.com",
+ "myeatherwallet.com",
+ "myetharwallet.com",
+ "myelherwallel.com",
+ "myetherwaillet.com",
+ "myetherwaliet.com",
+ "myetherwallel.com",
+ "myetherwallet.cam",
+ "myetherwallet.cc",
+ "myetherwallet.co",
+ "myetherwallet.cm",
+ "myetherwallet.cz",
+ "myetherwallet.org",
+ "myetherwallet.tech",
+ "myetherwallet.top",
+ "myetherwallet.net",
+ "etherclassicwallet.com",
+ "omg-omise.co",
+ "omise-go.com",
+ "tenx-tech.com",
+ "tokensale-tenx.tech",
+ "ubiqcoin.org",
+ "metamask.com",
+ "ethtrade.io",
+ "myetcwallet.com",
+ "account-kigo.net",
+ "bitcoin-wallet.net",
+ "blocklichan.info",
+ "bloclkicihan.info",
+ "coindash.ml",
+ "eos-bonus.com",
+ "eos-io.info",
+ "ether-wallet.net",
+ "ethereum-wallet.info",
+ "ethereum-wallet.net",
+ "ethereumchest.net",
+ "reservations-kigo.net",
+ "reservations-lodgix.com",
+ "secure-liverez.com",
+ "secure-onerooftop.com",
+ "settings-liverez.com",
+ "software-liverez.com",
+ "software-lodgix.com",
+ "unhackableetherwallets.com",
+ "www-myetherwallet.com",
+ "etherwallet.co.za",
+ "etherwalletchain.com",
+ "etherwallets.net",
+ "etherwallets.nl",
+ "my-ethwallet.com",
+ "my.ether-wallet.co",
+ "myetherwallet.com.am",
+ "myetherwallet.com.ht",
+ "myetherwalletcom.com",
+ "xn--myetherwalle-xoc.com",
+ "xn--myetherwalle-44i.com",
+ "xn--myetherwalle-xhk.com",
+ "xn--myetherwallt-cfb.com",
+ "xn--myetherwallt-6tb.com",
+ "xn--myetherwallt-xub.com",
+ "xn--myetherwallt-ovb.com",
+ "xn--myetherwallt-fwb.com",
+ "xn--myetherwallt-5wb.com",
+ "xn--myetherwallt-jzi.com",
+ "xn--myetherwallt-2ck.com",
+ "xn--myetherwallt-lok.com",
+ "xn--myetherwallt-lsl.com",
+ "xn--myetherwallt-ce6f.com",
+ "xn--myetherwalet-mcc.com",
+ "xn--myetherwalet-xhf.com",
+ "xn--myetherwalet-lcc.com",
+ "xn--myetherwaet-15ba.com",
+ "xn--myetherwalet-whf.com",
+ "xn--myetherwaet-v2ea.com",
+ "xn--myetherwllet-59a.com",
+ "xn--myetherwllet-jbb.com",
+ "xn--myetherwllet-wbb.com",
+ "xn--myetherwllet-9bb.com",
+ "xn--myetherwllet-ncb.com",
+ "xn--myetherwllet-0cb.com",
+ "xn--myetherwllet-5nb.com",
+ "xn--myetherwllet-ktd.com",
+ "xn--myetherwllet-mre.com",
+ "xn--myetherwllet-76e.com",
+ "xn--myetherwllet-o0l.com",
+ "xn--myetherwllet-c45f.com",
+ "xn--myetherallet-ejn.com",
+ "xn--myethewallet-4nf.com",
+ "xn--myethewallet-iof.com",
+ "xn--myethewallet-mpf.com",
+ "xn--myethewallet-6bk.com",
+ "xn--myethewallet-i31f.com",
+ "xn--myethrwallet-feb.com",
+ "xn--myethrwallt-fbbf.com",
+ "xn--myethrwallet-seb.com",
+ "xn--myethrwallt-rbbf.com",
+ "xn--myethrwallet-5eb.com",
+ "xn--myethrwallt-3bbf.com",
+ "xn--myethrwallet-0tb.com",
+ "xn--myethrwallt-tpbf.com",
+ "xn--myethrwallet-rub.com",
+ "xn--myethrwallt-iqbf.com",
+ "xn--myethrwallet-ivb.com",
+ "xn--myethrwallt-6qbf.com",
+ "xn--myethrwallet-8vb.com",
+ "xn--myethrwallt-vrbf.com",
+ "xn--myethrwallet-zwb.com",
+ "xn--myethrwallt-ksbf.com",
+ "xn--myethrwallet-dzi.com",
+ "xn--myethrwallt-wbif.com",
+ "xn--myethrwallet-wck.com",
+ "xn--myethrwallt-skjf.com",
+ "xn--myethrwallet-fok.com",
+ "xn--myethrwallt-fvjf.com",
+ "xn--myethrwallet-fsl.com",
+ "xn--myethrwallt-fwkf.com",
+ "xn--myethrwallet-5d6f.com",
+ "xn--myethrwallt-319ef.com",
+ "xn--myeterwallet-ufk.com",
+ "xn--myeterwallet-nrl.com",
+ "xn--myeterwallet-von.com",
+ "xn--myeterwallet-jl6c.com",
+ "xn--myeherwallet-ooc.com",
+ "xn--myeherwalle-6hci.com",
+ "xn--myeherwallet-v4i.com",
+ "xn--myeherwalle-zgii.com",
+ "xn--myeherwallet-ohk.com",
+ "xn--myeherwalle-6oji.com",
+ "xn--mytherwallet-ceb.com",
+ "xn--mythrwallet-cbbc.com",
+ "xn--mythrwallt-c7acf.com",
+ "xn--mytherwallet-peb.com",
+ "xn--mythrwallet-obbc.com",
+ "xn--mythrwallt-n7acf.com",
+ "xn--mytherwallet-2eb.com",
+ "xn--mythrwallet-0bbc.com",
+ "xn--mythrwallt-y7acf.com",
+ "xn--mytherwallet-xtb.com",
+ "xn--mythrwallet-qpbc.com",
+ "xn--mythrwallt-jlbcf.com",
+ "xn--mytherwallet-oub.com",
+ "xn--mythrwallet-fqbc.com",
+ "xn--mythrwallt-5lbcf.com",
+ "xn--mythrwallet-3qbc.com",
+ "xn--mythrwallt-smbcf.com",
+ "xn--mytherwallet-5vb.com",
+ "xn--mythrwallet-srbc.com",
+ "xn--mythrwallt-fnbcf.com",
+ "xn--mytherwallet-wwb.com",
+ "xn--mythrwallet-hsbc.com",
+ "xn--mythrwallt-1nbcf.com",
+ "xn--mytherwallet-9yi.com",
+ "xn--mythrwallet-tbic.com",
+ "xn--mythrwallt-dnhcf.com",
+ "xn--mytherwallet-tck.com",
+ "xn--mythrwallet-pkjc.com",
+ "xn--mythrwallt-lsicf.com",
+ "xn--mytherwallet-cok.com",
+ "xn--mythrwallet-cvjc.com",
+ "xn--mythrwallt-c2icf.com",
+ "xn--mytherwallet-csl.com",
+ "xn--mythrwallet-cwkc.com",
+ "xn--mythrwallt-c0jcf.com",
+ "xn--mytherwallet-2d6f.com",
+ "xn--mythrwallet-019ec.com",
+ "xn--mythrwallt-yq3ecf.com",
+ "xn--metherwallet-qlb.com",
+ "xn--metherwallet-1uf.com",
+ "xn--metherwallet-iyi.com",
+ "xn--metherwallet-zhk.com",
+ "xn--metherwallet-3ml.com",
+ "xn--mytherwallet-fvb.com",
+ "xn--myetherwallt-7db.com",
+ "xn--myetherwallt-leb.com",
+ "xn--myetherwallt-yeb.com",
+ "xn--yetherwallet-vjf.com",
+ "xn--yetherwallet-dfk.com",
+ "xn--yetherwallet-1t1f.com",
+ "xn--yetherwallet-634f.com"
+ ]
+ }
+ },
+ "AddressBookController": {
+ "addressBook": []
+ },
+ "TransactionController": {
+ "transactions": [
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "chainId": 3
+ },
+ "history": [
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "3b9aca00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "3b9aca00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "3b9aca00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "3b9aca00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": 0
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ }
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": 0
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ }
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ }
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ }
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf86380843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a02e45f61129f0c97634e37a1823b858df7b0dfc867a44949aae7dd9bcea1c1b5aa03b1f002cda0872d40517d5b26caefa3e407ec8fd03bc7dc2d995b84726961264"
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf86380843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a02e45f61129f0c97634e37a1823b858df7b0dfc867a44949aae7dd9bcea1c1b5aa03b1f002cda0872d40517d5b26caefa3e407ec8fd03bc7dc2d995b84726961264"
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf86380843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a02e45f61129f0c97634e37a1823b858df7b0dfc867a44949aae7dd9bcea1c1b5aa03b1f002cda0872d40517d5b26caefa3e407ec8fd03bc7dc2d995b84726961264",
+ "hash": "0x38c254639139c94303a3141aee041b15301509e743f08569ffac6aca17518012"
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf86380843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a02e45f61129f0c97634e37a1823b858df7b0dfc867a44949aae7dd9bcea1c1b5aa03b1f002cda0872d40517d5b26caefa3e407ec8fd03bc7dc2d995b84726961264",
+ "hash": "0x38c254639139c94303a3141aee041b15301509e743f08569ffac6aca17518012"
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf86380843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a02e45f61129f0c97634e37a1823b858df7b0dfc867a44949aae7dd9bcea1c1b5aa03b1f002cda0872d40517d5b26caefa3e407ec8fd03bc7dc2d995b84726961264",
+ "hash": "0x38c254639139c94303a3141aee041b15301509e743f08569ffac6aca17518012"
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf86380843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a02e45f61129f0c97634e37a1823b858df7b0dfc867a44949aae7dd9bcea1c1b5aa03b1f002cda0872d40517d5b26caefa3e407ec8fd03bc7dc2d995b84726961264",
+ "hash": "0x38c254639139c94303a3141aee041b15301509e743f08569ffac6aca17518012"
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf86380843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a02e45f61129f0c97634e37a1823b858df7b0dfc867a44949aae7dd9bcea1c1b5aa03b1f002cda0872d40517d5b26caefa3e407ec8fd03bc7dc2d995b84726961264",
+ "hash": "0x38c254639139c94303a3141aee041b15301509e743f08569ffac6aca17518012",
+ "retryCount": 1
+ },
+ {
+ "id": 6616756286038869,
+ "time": 1502438908445,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf86380843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a02e45f61129f0c97634e37a1823b858df7b0dfc867a44949aae7dd9bcea1c1b5aa03b1f002cda0872d40517d5b26caefa3e407ec8fd03bc7dc2d995b84726961264",
+ "hash": "0x38c254639139c94303a3141aee041b15301509e743f08569ffac6aca17518012",
+ "retryCount": 1
+ }
+ ],
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16643c",
+ "baseCount": 0,
+ "baseCountHex": "0x0",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf86380843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a02e45f61129f0c97634e37a1823b858df7b0dfc867a44949aae7dd9bcea1c1b5aa03b1f002cda0872d40517d5b26caefa3e407ec8fd03bc7dc2d995b84726961264",
+ "hash": "0x38c254639139c94303a3141aee041b15301509e743f08569ffac6aca17518012",
+ "retryCount": 1
+ },
+ {
+ "id": 6616756286038870,
+ "time": 1502573153664,
+ "status": "rejected",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "28fa6ae00",
+ "gas": "0x7b0d"
+ },
+ "history": [
+ {
+ "id": 6616756286038870,
+ "time": 1502573153664,
+ "status": "rejected",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "28fa6ae00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038870,
+ "time": 1502573153664,
+ "status": "rejected",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "28fa6ae00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ }
+ ],
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": "0x01",
+ "chainId": 3
+ },
+ "history": [
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "28fa6ae00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "28fa6ae00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "28fa6ae00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "28fa6ae00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": 1
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ }
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": 1
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ }
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": "0x01",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ }
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": "0x01",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ }
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": "0x01",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf8640185028fa6ae00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a06261831b3d599a90dc24fac67bc648fd58cab2036e4e8dfbbb5c00c3fd9cf66ba00e2ea6ebc63ba715a94dc94e24120639c4ad60832d3285dd558929a61cc18cc0"
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": "0x01",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf8640185028fa6ae00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a06261831b3d599a90dc24fac67bc648fd58cab2036e4e8dfbbb5c00c3fd9cf66ba00e2ea6ebc63ba715a94dc94e24120639c4ad60832d3285dd558929a61cc18cc0"
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": "0x01",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf8640185028fa6ae00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a06261831b3d599a90dc24fac67bc648fd58cab2036e4e8dfbbb5c00c3fd9cf66ba00e2ea6ebc63ba715a94dc94e24120639c4ad60832d3285dd558929a61cc18cc0",
+ "hash": "0xeb1c57dec9df8410bcc65374c7f684fc8ebfcda6865a149e38bb000fa706a150"
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": "0x01",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf8640185028fa6ae00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a06261831b3d599a90dc24fac67bc648fd58cab2036e4e8dfbbb5c00c3fd9cf66ba00e2ea6ebc63ba715a94dc94e24120639c4ad60832d3285dd558929a61cc18cc0",
+ "hash": "0xeb1c57dec9df8410bcc65374c7f684fc8ebfcda6865a149e38bb000fa706a150"
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": "0x01",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf8640185028fa6ae00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a06261831b3d599a90dc24fac67bc648fd58cab2036e4e8dfbbb5c00c3fd9cf66ba00e2ea6ebc63ba715a94dc94e24120639c4ad60832d3285dd558929a61cc18cc0",
+ "hash": "0xeb1c57dec9df8410bcc65374c7f684fc8ebfcda6865a149e38bb000fa706a150"
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": "0x01",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf8640185028fa6ae00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a06261831b3d599a90dc24fac67bc648fd58cab2036e4e8dfbbb5c00c3fd9cf66ba00e2ea6ebc63ba715a94dc94e24120639c4ad60832d3285dd558929a61cc18cc0",
+ "hash": "0xeb1c57dec9df8410bcc65374c7f684fc8ebfcda6865a149e38bb000fa706a150"
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": "0x01",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf8640185028fa6ae00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a06261831b3d599a90dc24fac67bc648fd58cab2036e4e8dfbbb5c00c3fd9cf66ba00e2ea6ebc63ba715a94dc94e24120639c4ad60832d3285dd558929a61cc18cc0",
+ "hash": "0xeb1c57dec9df8410bcc65374c7f684fc8ebfcda6865a149e38bb000fa706a150",
+ "retryCount": 1
+ },
+ {
+ "id": 6616756286038871,
+ "time": 1502573157128,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x28fa6ae00",
+ "gas": "0x7b0d",
+ "nonce": "0x01",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf8640185028fa6ae00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a06261831b3d599a90dc24fac67bc648fd58cab2036e4e8dfbbb5c00c3fd9cf66ba00e2ea6ebc63ba715a94dc94e24120639c4ad60832d3285dd558929a61cc18cc0",
+ "hash": "0xeb1c57dec9df8410bcc65374c7f684fc8ebfcda6865a149e38bb000fa706a150",
+ "retryCount": 1
+ }
+ ],
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x168739",
+ "baseCount": 1,
+ "baseCountHex": "0x1",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf8640185028fa6ae00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a06261831b3d599a90dc24fac67bc648fd58cab2036e4e8dfbbb5c00c3fd9cf66ba00e2ea6ebc63ba715a94dc94e24120639c4ad60832d3285dd558929a61cc18cc0",
+ "hash": "0xeb1c57dec9df8410bcc65374c7f684fc8ebfcda6865a149e38bb000fa706a150",
+ "retryCount": 1
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x02",
+ "chainId": 3
+ },
+ "history": [
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d",
+ "nonce": 2
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ }
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d",
+ "nonce": 2
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ }
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x02",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ }
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x02",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ }
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x02",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf864028504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa057380f9007a48d4bce31792859b1a25cb2b45ba615e7951d8e8a925360a0b301a042393e72d1a96a2605c0da95705c5f3f7c744f0affcac01e0a64721037f04adc"
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x02",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf864028504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa057380f9007a48d4bce31792859b1a25cb2b45ba615e7951d8e8a925360a0b301a042393e72d1a96a2605c0da95705c5f3f7c744f0affcac01e0a64721037f04adc"
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x02",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf864028504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa057380f9007a48d4bce31792859b1a25cb2b45ba615e7951d8e8a925360a0b301a042393e72d1a96a2605c0da95705c5f3f7c744f0affcac01e0a64721037f04adc",
+ "hash": "0xc28ceb1e2c4e5c61b805b181e3cc99dd7bade58935233fab76c63cedfd494270"
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x02",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf864028504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa057380f9007a48d4bce31792859b1a25cb2b45ba615e7951d8e8a925360a0b301a042393e72d1a96a2605c0da95705c5f3f7c744f0affcac01e0a64721037f04adc",
+ "hash": "0xc28ceb1e2c4e5c61b805b181e3cc99dd7bade58935233fab76c63cedfd494270"
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x02",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf864028504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa057380f9007a48d4bce31792859b1a25cb2b45ba615e7951d8e8a925360a0b301a042393e72d1a96a2605c0da95705c5f3f7c744f0affcac01e0a64721037f04adc",
+ "hash": "0xc28ceb1e2c4e5c61b805b181e3cc99dd7bade58935233fab76c63cedfd494270"
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x02",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf864028504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa057380f9007a48d4bce31792859b1a25cb2b45ba615e7951d8e8a925360a0b301a042393e72d1a96a2605c0da95705c5f3f7c744f0affcac01e0a64721037f04adc",
+ "hash": "0xc28ceb1e2c4e5c61b805b181e3cc99dd7bade58935233fab76c63cedfd494270"
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x02",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf864028504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa057380f9007a48d4bce31792859b1a25cb2b45ba615e7951d8e8a925360a0b301a042393e72d1a96a2605c0da95705c5f3f7c744f0affcac01e0a64721037f04adc",
+ "hash": "0xc28ceb1e2c4e5c61b805b181e3cc99dd7bade58935233fab76c63cedfd494270",
+ "retryCount": 1
+ },
+ {
+ "id": 6616756286038872,
+ "time": 1502734903652,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x02",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf864028504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa057380f9007a48d4bce31792859b1a25cb2b45ba615e7951d8e8a925360a0b301a042393e72d1a96a2605c0da95705c5f3f7c744f0affcac01e0a64721037f04adc",
+ "hash": "0xc28ceb1e2c4e5c61b805b181e3cc99dd7bade58935233fab76c63cedfd494270",
+ "retryCount": 1
+ }
+ ],
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b066",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 0
+ },
+ "rawTx": "0xf864028504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa057380f9007a48d4bce31792859b1a25cb2b45ba615e7951d8e8a925360a0b301a042393e72d1a96a2605c0da95705c5f3f7c744f0affcac01e0a64721037f04adc",
+ "hash": "0xc28ceb1e2c4e5c61b805b181e3cc99dd7bade58935233fab76c63cedfd494270",
+ "retryCount": 1
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": "0x03",
+ "chainId": 3
+ },
+ "history": [
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ }
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ }
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": "0x03",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ }
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": "0x03",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ }
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": "0x03",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ },
+ "rawTx": "0xf86303843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0e442afe9386066936f556d852a296d22b8392652aa2ddb26969d83d661759ee1a06dc55b164f666a37107e86d575d2701602fc100f0ef4875736d45995150d4897"
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": "0x03",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ },
+ "rawTx": "0xf86303843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0e442afe9386066936f556d852a296d22b8392652aa2ddb26969d83d661759ee1a06dc55b164f666a37107e86d575d2701602fc100f0ef4875736d45995150d4897"
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": "0x03",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ },
+ "rawTx": "0xf86303843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0e442afe9386066936f556d852a296d22b8392652aa2ddb26969d83d661759ee1a06dc55b164f666a37107e86d575d2701602fc100f0ef4875736d45995150d4897",
+ "hash": "0xfcc66b8002c64a5aaa076adea7f7e48d194de10e40eb64924c8de344805c8cb7"
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": "0x03",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ },
+ "rawTx": "0xf86303843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0e442afe9386066936f556d852a296d22b8392652aa2ddb26969d83d661759ee1a06dc55b164f666a37107e86d575d2701602fc100f0ef4875736d45995150d4897",
+ "hash": "0xfcc66b8002c64a5aaa076adea7f7e48d194de10e40eb64924c8de344805c8cb7"
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": "0x03",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ },
+ "rawTx": "0xf86303843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0e442afe9386066936f556d852a296d22b8392652aa2ddb26969d83d661759ee1a06dc55b164f666a37107e86d575d2701602fc100f0ef4875736d45995150d4897",
+ "hash": "0xfcc66b8002c64a5aaa076adea7f7e48d194de10e40eb64924c8de344805c8cb7"
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": "0x03",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ },
+ "rawTx": "0xf86303843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0e442afe9386066936f556d852a296d22b8392652aa2ddb26969d83d661759ee1a06dc55b164f666a37107e86d575d2701602fc100f0ef4875736d45995150d4897",
+ "hash": "0xfcc66b8002c64a5aaa076adea7f7e48d194de10e40eb64924c8de344805c8cb7"
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": "0x03",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ },
+ "rawTx": "0xf86303843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0e442afe9386066936f556d852a296d22b8392652aa2ddb26969d83d661759ee1a06dc55b164f666a37107e86d575d2701602fc100f0ef4875736d45995150d4897",
+ "hash": "0xfcc66b8002c64a5aaa076adea7f7e48d194de10e40eb64924c8de344805c8cb7",
+ "retryCount": 2
+ },
+ {
+ "id": 6616756286038873,
+ "time": 1502734910224,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0d",
+ "nonce": "0x03",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ },
+ "rawTx": "0xf86303843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0e442afe9386066936f556d852a296d22b8392652aa2ddb26969d83d661759ee1a06dc55b164f666a37107e86d575d2701602fc100f0ef4875736d45995150d4897",
+ "hash": "0xfcc66b8002c64a5aaa076adea7f7e48d194de10e40eb64924c8de344805c8cb7",
+ "retryCount": 2
+ }
+ ],
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 1
+ },
+ "rawTx": "0xf86303843b9aca00827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0e442afe9386066936f556d852a296d22b8392652aa2ddb26969d83d661759ee1a06dc55b164f666a37107e86d575d2701602fc100f0ef4875736d45995150d4897",
+ "hash": "0xfcc66b8002c64a5aaa076adea7f7e48d194de10e40eb64924c8de344805c8cb7",
+ "retryCount": 2
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x04",
+ "chainId": 3
+ },
+ "history": [
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d",
+ "nonce": 4
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ }
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d",
+ "nonce": 4
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ }
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x04",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ }
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x04",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ }
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x04",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864048504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a04be1c01535745fa7ec7aeb6e0b64d009981713808ca443b181fad802ce941352a03887e90375d9225b8dfd0d42324eed8eb4982fd14ea7b4069290237b29d1dcd3"
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x04",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864048504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a04be1c01535745fa7ec7aeb6e0b64d009981713808ca443b181fad802ce941352a03887e90375d9225b8dfd0d42324eed8eb4982fd14ea7b4069290237b29d1dcd3"
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x04",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864048504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a04be1c01535745fa7ec7aeb6e0b64d009981713808ca443b181fad802ce941352a03887e90375d9225b8dfd0d42324eed8eb4982fd14ea7b4069290237b29d1dcd3",
+ "hash": "0x9258ed7e451402612f572cbef52b63cd63cc2c59f443a207b7b4f8d317958635"
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x04",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864048504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a04be1c01535745fa7ec7aeb6e0b64d009981713808ca443b181fad802ce941352a03887e90375d9225b8dfd0d42324eed8eb4982fd14ea7b4069290237b29d1dcd3",
+ "hash": "0x9258ed7e451402612f572cbef52b63cd63cc2c59f443a207b7b4f8d317958635"
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x04",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864048504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a04be1c01535745fa7ec7aeb6e0b64d009981713808ca443b181fad802ce941352a03887e90375d9225b8dfd0d42324eed8eb4982fd14ea7b4069290237b29d1dcd3",
+ "hash": "0x9258ed7e451402612f572cbef52b63cd63cc2c59f443a207b7b4f8d317958635"
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x04",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864048504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a04be1c01535745fa7ec7aeb6e0b64d009981713808ca443b181fad802ce941352a03887e90375d9225b8dfd0d42324eed8eb4982fd14ea7b4069290237b29d1dcd3",
+ "hash": "0x9258ed7e451402612f572cbef52b63cd63cc2c59f443a207b7b4f8d317958635"
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x04",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864048504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a04be1c01535745fa7ec7aeb6e0b64d009981713808ca443b181fad802ce941352a03887e90375d9225b8dfd0d42324eed8eb4982fd14ea7b4069290237b29d1dcd3",
+ "hash": "0x9258ed7e451402612f572cbef52b63cd63cc2c59f443a207b7b4f8d317958635",
+ "retryCount": 4
+ },
+ {
+ "id": 6616756286038874,
+ "time": 1502734917414,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x04",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864048504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a04be1c01535745fa7ec7aeb6e0b64d009981713808ca443b181fad802ce941352a03887e90375d9225b8dfd0d42324eed8eb4982fd14ea7b4069290237b29d1dcd3",
+ "hash": "0x9258ed7e451402612f572cbef52b63cd63cc2c59f443a207b7b4f8d317958635",
+ "retryCount": 4
+ }
+ ],
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b067",
+ "baseCount": 2,
+ "baseCountHex": "0x2",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864048504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a04be1c01535745fa7ec7aeb6e0b64d009981713808ca443b181fad802ce941352a03887e90375d9225b8dfd0d42324eed8eb4982fd14ea7b4069290237b29d1dcd3",
+ "hash": "0x9258ed7e451402612f572cbef52b63cd63cc2c59f443a207b7b4f8d317958635",
+ "retryCount": 4
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x05",
+ "chainId": 3
+ },
+ "history": [
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d",
+ "nonce": 5
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ }
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d",
+ "nonce": 5
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ }
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x05",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ }
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x05",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ }
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x05",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864058504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a0dac4756e84c008714b3b8b43807157ed63737450780bc57590e930c8a360750ca00b43ac8ec5235f57ccca7e68ce8fbf77f43d6ffa5fbff296cba66cef47889cf5"
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x05",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864058504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a0dac4756e84c008714b3b8b43807157ed63737450780bc57590e930c8a360750ca00b43ac8ec5235f57ccca7e68ce8fbf77f43d6ffa5fbff296cba66cef47889cf5"
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x05",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864058504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a0dac4756e84c008714b3b8b43807157ed63737450780bc57590e930c8a360750ca00b43ac8ec5235f57ccca7e68ce8fbf77f43d6ffa5fbff296cba66cef47889cf5",
+ "hash": "0x67cdff49c1f8ed506c759fc8fd7ffe93d59fcb3bfd926b964cad47e2e504dc9e"
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x05",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864058504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a0dac4756e84c008714b3b8b43807157ed63737450780bc57590e930c8a360750ca00b43ac8ec5235f57ccca7e68ce8fbf77f43d6ffa5fbff296cba66cef47889cf5",
+ "hash": "0x67cdff49c1f8ed506c759fc8fd7ffe93d59fcb3bfd926b964cad47e2e504dc9e"
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x05",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864058504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a0dac4756e84c008714b3b8b43807157ed63737450780bc57590e930c8a360750ca00b43ac8ec5235f57ccca7e68ce8fbf77f43d6ffa5fbff296cba66cef47889cf5",
+ "hash": "0x67cdff49c1f8ed506c759fc8fd7ffe93d59fcb3bfd926b964cad47e2e504dc9e"
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x05",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864058504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a0dac4756e84c008714b3b8b43807157ed63737450780bc57590e930c8a360750ca00b43ac8ec5235f57ccca7e68ce8fbf77f43d6ffa5fbff296cba66cef47889cf5",
+ "hash": "0x67cdff49c1f8ed506c759fc8fd7ffe93d59fcb3bfd926b964cad47e2e504dc9e"
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x05",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864058504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a0dac4756e84c008714b3b8b43807157ed63737450780bc57590e930c8a360750ca00b43ac8ec5235f57ccca7e68ce8fbf77f43d6ffa5fbff296cba66cef47889cf5",
+ "hash": "0x67cdff49c1f8ed506c759fc8fd7ffe93d59fcb3bfd926b964cad47e2e504dc9e",
+ "retryCount": 3
+ },
+ {
+ "id": 6616756286038875,
+ "time": 1502734922745,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x05",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864058504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a0dac4756e84c008714b3b8b43807157ed63737450780bc57590e930c8a360750ca00b43ac8ec5235f57ccca7e68ce8fbf77f43d6ffa5fbff296cba66cef47889cf5",
+ "hash": "0x67cdff49c1f8ed506c759fc8fd7ffe93d59fcb3bfd926b964cad47e2e504dc9e",
+ "retryCount": 3
+ }
+ ],
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 2
+ },
+ "rawTx": "0xf864058504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c808029a0dac4756e84c008714b3b8b43807157ed63737450780bc57590e930c8a360750ca00b43ac8ec5235f57ccca7e68ce8fbf77f43d6ffa5fbff296cba66cef47889cf5",
+ "hash": "0x67cdff49c1f8ed506c759fc8fd7ffe93d59fcb3bfd926b964cad47e2e504dc9e",
+ "retryCount": 3
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x06",
+ "chainId": 3
+ },
+ "history": [
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "unapproved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d"
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209"
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d",
+ "nonce": 6
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ }
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "approved",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "4a817c800",
+ "gas": "0x7b0d",
+ "nonce": 6
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ }
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x06",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ }
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x06",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ }
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x06",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ },
+ "rawTx": "0xf864068504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0d983a744f58179522b4bb75f6320dbcf0a699506f2470139282a2ad02e92554fa030d818c35e997ba5d004df65a0c4ebcb49d098ec7dc190d7287a72f9c96f89e7"
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x06",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ },
+ "rawTx": "0xf864068504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0d983a744f58179522b4bb75f6320dbcf0a699506f2470139282a2ad02e92554fa030d818c35e997ba5d004df65a0c4ebcb49d098ec7dc190d7287a72f9c96f89e7"
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x06",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ },
+ "rawTx": "0xf864068504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0d983a744f58179522b4bb75f6320dbcf0a699506f2470139282a2ad02e92554fa030d818c35e997ba5d004df65a0c4ebcb49d098ec7dc190d7287a72f9c96f89e7",
+ "hash": "0x2c12c403aeb62a92bd5eabd3edcc38ab9e63bb0c93f706520bd2042894737ad1"
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "signed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x06",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ },
+ "rawTx": "0xf864068504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0d983a744f58179522b4bb75f6320dbcf0a699506f2470139282a2ad02e92554fa030d818c35e997ba5d004df65a0c4ebcb49d098ec7dc190d7287a72f9c96f89e7",
+ "hash": "0x2c12c403aeb62a92bd5eabd3edcc38ab9e63bb0c93f706520bd2042894737ad1"
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x06",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ },
+ "rawTx": "0xf864068504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0d983a744f58179522b4bb75f6320dbcf0a699506f2470139282a2ad02e92554fa030d818c35e997ba5d004df65a0c4ebcb49d098ec7dc190d7287a72f9c96f89e7",
+ "hash": "0x2c12c403aeb62a92bd5eabd3edcc38ab9e63bb0c93f706520bd2042894737ad1"
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "submitted",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x06",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ },
+ "rawTx": "0xf864068504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0d983a744f58179522b4bb75f6320dbcf0a699506f2470139282a2ad02e92554fa030d818c35e997ba5d004df65a0c4ebcb49d098ec7dc190d7287a72f9c96f89e7",
+ "hash": "0x2c12c403aeb62a92bd5eabd3edcc38ab9e63bb0c93f706520bd2042894737ad1"
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x06",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ },
+ "rawTx": "0xf864068504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0d983a744f58179522b4bb75f6320dbcf0a699506f2470139282a2ad02e92554fa030d818c35e997ba5d004df65a0c4ebcb49d098ec7dc190d7287a72f9c96f89e7",
+ "hash": "0x2c12c403aeb62a92bd5eabd3edcc38ab9e63bb0c93f706520bd2042894737ad1",
+ "retryCount": 5
+ },
+ {
+ "id": 6616756286038876,
+ "time": 1502734928623,
+ "status": "confirmed",
+ "metamaskNetworkId": "3",
+ "txParams": {
+ "from": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "to": "0x3ae39e89dc7e736cce53091057a45bf44b1a566c",
+ "value": "0x0",
+ "gasPrice": "0x4a817c800",
+ "gas": "0x7b0d",
+ "nonce": "0x06",
+ "chainId": 3
+ },
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ },
+ "rawTx": "0xf864068504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0d983a744f58179522b4bb75f6320dbcf0a699506f2470139282a2ad02e92554fa030d818c35e997ba5d004df65a0c4ebcb49d098ec7dc190d7287a72f9c96f89e7",
+ "hash": "0x2c12c403aeb62a92bd5eabd3edcc38ab9e63bb0c93f706520bd2042894737ad1",
+ "retryCount": 5
+ }
+ ],
+ "gasLimitSpecified": false,
+ "estimatedGas": "5209",
+ "nonceDetails": {
+ "blockNumber": "0x16b068",
+ "baseCount": 3,
+ "baseCountHex": "0x3",
+ "pendingCount": 3
+ },
+ "rawTx": "0xf864068504a817c800827b0d943ae39e89dc7e736cce53091057a45bf44b1a566c80802aa0d983a744f58179522b4bb75f6320dbcf0a699506f2470139282a2ad02e92554fa030d818c35e997ba5d004df65a0c4ebcb49d098ec7dc190d7287a72f9c96f89e7",
+ "hash": "0x2c12c403aeb62a92bd5eabd3edcc38ab9e63bb0c93f706520bd2042894737ad1",
+ "retryCount": 5
+ }
+ ]
+ }
+ }
+} \ No newline at end of file
diff --git a/test/integration/helpers.js b/test/integration/helpers.js
deleted file mode 100644
index 10cd74e64..000000000
--- a/test/integration/helpers.js
+++ /dev/null
@@ -1,7 +0,0 @@
-function wait(time) {
- return new Promise(function (resolve, reject) {
- setTimeout(function () {
- resolve()
- }, time * 3 || 1500)
- })
-}
diff --git a/test/integration/index.js b/test/integration/index.js
index e089fc39b..144303dbb 100644
--- a/test/integration/index.js
+++ b/test/integration/index.js
@@ -1,5 +1,6 @@
const fs = require('fs')
const path = require('path')
+const pump = require('pump')
const browserify = require('browserify')
const tests = fs.readdirSync(path.join(__dirname, 'lib'))
const bundlePath = path.join(__dirname, 'bundle.js')
@@ -9,11 +10,17 @@ const b = browserify()
const writeStream = fs.createWriteStream(bundlePath)
tests.forEach(function (fileName) {
- b.add(path.join(__dirname, 'lib', fileName))
+ const filePath = path.join(__dirname, 'lib', fileName)
+ console.log(`bundling test "${filePath}"`)
+ b.add(filePath)
})
-b.bundle()
-.pipe(writeStream)
-.on('error', (err) => {
- throw err
-})
+pump(
+ b.bundle(),
+ writeStream,
+ (err) => {
+ if (err) throw err
+ console.log(`Integration test build completed: "${bundlePath}"`)
+ process.exit(0)
+ }
+) \ No newline at end of file
diff --git a/test/integration/lib/first-time.js b/test/integration/lib/first-time.js
index 0e4b802da..38a94e551 100644
--- a/test/integration/lib/first-time.js
+++ b/test/integration/lib/first-time.js
@@ -2,125 +2,137 @@ const PASSWORD = 'password123'
QUnit.module('first time usage')
-QUnit.test('render init screen', function (assert) {
- var done = assert.async()
- let app
-
- wait().then(function() {
- app = $('iframe').contents().find('#app-content .mock-app-root')
-
- const recurseNotices = function () {
- let button = app.find('button')
- if (button.html() === 'Accept') {
- let termsPage = app.find('.markdown')[0]
- termsPage.scrollTop = termsPage.scrollHeight
- return wait().then(() => {
- button.click()
- return wait()
- }).then(() => {
- return recurseNotices()
- })
- } else {
- return wait()
- }
+QUnit.test('render init screen', (assert) => {
+ const done = assert.async()
+ runFirstTimeUsageTest(assert).then(done).catch((err) => {
+ assert.notOk(err, `Error was thrown: ${err.stack}`)
+ done()
+ })
+})
+
+// QUnit.testDone(({ module, name, total, passed, failed, skipped, todo, runtime }) => {
+// if (failed > 0) {
+// const app = $('iframe').contents()[0].documentElement
+// console.warn('Test failures - dumping DOM:')
+// console.log(app.innerHTML)
+// }
+// })
+
+async function runFirstTimeUsageTest(assert, done) {
+
+ await timeout()
+
+ const app = $('#app-content .mock-app-root')
+
+ // recurse notices
+ while (true) {
+ const button = app.find('button')
+ if (button.html() === 'Accept') {
+ // still notices to accept
+ const termsPage = app.find('.markdown')[0]
+ termsPage.scrollTop = termsPage.scrollHeight
+ await timeout()
+ button.click()
+ await timeout()
+ } else {
+ // exit loop
+ break
}
- return recurseNotices()
- }).then(function() {
- // Scroll through terms
- var title = app.find('h1').text()
- assert.equal(title, 'MetaMask', 'title screen')
+ }
- // enter password
- var pwBox = app.find('#password-box')[0]
- var confBox = app.find('#password-box-confirm')[0]
- pwBox.value = PASSWORD
- confBox.value = PASSWORD
+ await timeout()
- return wait()
- }).then(function() {
+ // Scroll through terms
+ const title = app.find('h1').text()
+ assert.equal(title, 'MetaMask', 'title screen')
- // create vault
- var createButton = app.find('button.primary')[0]
- createButton.click()
+ // enter password
+ const pwBox = app.find('#password-box')[0]
+ const confBox = app.find('#password-box-confirm')[0]
+ pwBox.value = PASSWORD
+ confBox.value = PASSWORD
- return wait(1500)
- }).then(function() {
+ await timeout()
- var created = app.find('h3')[0]
- assert.equal(created.textContent, 'Vault Created', 'Vault created screen')
+ // create vault
+ const createButton = app.find('button.primary')[0]
+ createButton.click()
- // Agree button
- var button = app.find('button')[0]
- assert.ok(button, 'button present')
- button.click()
+ await timeout(1500)
- return wait(1000)
- }).then(function() {
+ const created = app.find('h3')[0]
+ assert.equal(created.textContent, 'Vault Created', 'Vault created screen')
- var detail = app.find('.account-detail-section')[0]
- assert.ok(detail, 'Account detail section loaded.')
+ // Agree button
+ const button = app.find('button')[0]
+ assert.ok(button, 'button present')
+ button.click()
- var sandwich = app.find('.sandwich-expando')[0]
- sandwich.click()
+ await timeout(1000)
- return wait()
- }).then(function() {
+ const detail = app.find('.account-detail-section')[0]
+ assert.ok(detail, 'Account detail section loaded.')
- var sandwich = app.find('.menu-droppo')[0]
- var children = sandwich.children
- var lock = children[children.length - 2]
- assert.ok(lock, 'Lock menu item found')
- lock.click()
+ const sandwich = app.find('.sandwich-expando')[0]
+ sandwich.click()
- return wait(1000)
- }).then(function() {
+ await timeout()
- var pwBox = app.find('#password-box')[0]
- pwBox.value = PASSWORD
+ const menu = app.find('.menu-droppo')[0]
+ const children = menu.children
+ const lock = children[children.length - 2]
+ assert.ok(lock, 'Lock menu item found')
+ lock.click()
- var createButton = app.find('button.primary')[0]
- createButton.click()
+ await timeout(1000)
- return wait(1000)
- }).then(function() {
+ const pwBox2 = app.find('#password-box')[0]
+ pwBox2.value = PASSWORD
- var detail = app.find('.account-detail-section')[0]
- assert.ok(detail, 'Account detail section loaded again.')
+ const createButton2 = app.find('button.primary')[0]
+ createButton2.click()
- return wait()
- }).then(function (){
+ await timeout(1000)
- var qrButton = app.find('.fa.fa-ellipsis-h')[0] // open account settings dropdown
- qrButton.click()
+ const detail2 = app.find('.account-detail-section')[0]
+ assert.ok(detail2, 'Account detail section loaded again.')
- return wait(1000)
- }).then(function (){
+ await timeout()
- var qrButton = app.find('.dropdown-menu-item')[1] // qr code item
- qrButton.click()
+ // open account settings dropdown
+ const qrButton = app.find('.fa.fa-ellipsis-h')[0]
+ qrButton.click()
- return wait(1000)
- }).then(function (){
+ await timeout(1000)
- var qrHeader = app.find('.qr-header')[0]
- var qrContainer = app.find('#qr-container')[0]
- assert.equal(qrHeader.textContent, 'Account 1', 'Should show account label.')
- assert.ok(qrContainer, 'QR Container found')
+ // qr code item
+ const qrButton2 = app.find('.dropdown-menu-item')[1]
+ qrButton2.click()
- return wait()
- }).then(function (){
+ await timeout(1000)
- var networkMenu = app.find('.network-indicator')[0]
- networkMenu.click()
+ const qrHeader = app.find('.qr-header')[0]
+ const qrContainer = app.find('#qr-container')[0]
+ assert.equal(qrHeader.textContent, 'Account 1', 'Should show account label.')
+ assert.ok(qrContainer, 'QR Container found')
- return wait()
- }).then(function (){
+ await timeout()
- var networkMenu = app.find('.network-indicator')[0]
- var children = networkMenu.children
- children.length[3]
- assert.ok(children, 'All network options present')
+ const networkMenu = app.find('.network-indicator')[0]
+ networkMenu.click()
- done()
+ await timeout()
+
+ const networkMenu2 = app.find('.network-indicator')[0]
+ const children2 = networkMenu2.children
+ children2.length[3]
+ assert.ok(children2, 'All network options present')
+}
+
+function timeout(time) {
+ return new Promise(function (resolve, reject) {
+ setTimeout(function () {
+ resolve()
+ }, time * 3 || 1500)
})
-})
+} \ No newline at end of file
diff --git a/test/lib/mock-store.js b/test/lib/mock-store.js
index 0d50e2d9c..8af8f6d23 100644
--- a/test/lib/mock-store.js
+++ b/test/lib/mock-store.js
@@ -1,7 +1,7 @@
const createStore = require('redux').createStore
const applyMiddleware = require('redux').applyMiddleware
-const thunkMiddleware = require('redux-thunk')
-const createLogger = require('redux-logger')
+const thunkMiddleware = require('redux-thunk').default
+const createLogger = require('redux-logger').createLogger
const rootReducer = function () {}
module.exports = configureStore
diff --git a/test/lib/mock-tx-gen.js b/test/lib/mock-tx-gen.js
new file mode 100644
index 000000000..7aea09c59
--- /dev/null
+++ b/test/lib/mock-tx-gen.js
@@ -0,0 +1,40 @@
+const extend = require('xtend')
+const BN = require('ethereumjs-util').BN
+const template = {
+ 'status': 'submitted',
+ 'txParams': {
+ 'from': '0x7d3517b0d011698406d6e0aed8453f0be2697926',
+ 'gas': '0x30d40',
+ 'value': '0x0',
+ 'nonce': '0x3',
+ },
+}
+
+class TxGenerator {
+
+ constructor () {
+ this.txs = []
+ }
+
+ generate (tx = {}, opts = {}) {
+ let { count, fromNonce } = opts
+ let nonce = fromNonce || this.txs.length
+ let txs = []
+ for (let i = 0; i < count; i++) {
+ txs.push(extend(template, {
+ txParams: {
+ nonce: hexify(nonce++),
+ }
+ }, tx))
+ }
+ this.txs = this.txs.concat(txs)
+ return txs
+ }
+
+}
+
+function hexify (number) {
+ return '0x' + (new BN(number)).toString(16)
+}
+
+module.exports = TxGenerator
diff --git a/test/unit/actions/tx_test.js b/test/unit/actions/tx_test.js
index 67c72e9a5..ea6dfda6a 100644
--- a/test/unit/actions/tx_test.js
+++ b/test/unit/actions/tx_test.js
@@ -53,7 +53,7 @@ describe('tx confirmation screen', function () {
result = reducers(initialState, action)
done()
})
-
+
})
it('should transition to the account detail view', function () {
@@ -65,91 +65,6 @@ describe('tx confirmation screen', function () {
assert.equal(count, 0)
})
})
-
- describe('sendTx', function () {
- var result
-
- describe('when there is an error', function () {
- before(function (done) {
- actions._setBackgroundConnection({
- approveTransaction (txId, cb) { cb({message: 'An error!'}) },
- })
-
- actions.sendTx({id: firstTxId})(function (action) {
- result = reducers(initialState, action)
- done()
- })
- })
-
- it('should stay on the page', function () {
- assert.equal(result.appState.currentView.name, 'confTx')
- })
-
- it('should set errorMessage on the currentView', function () {
- assert(result.appState.currentView.errorMessage)
- })
- })
-
- describe('when there is success', function () {
- it('should complete tx and go home', function () {
- actions._setBackgroundConnection({
- approveTransaction (txId, cb) { cb() },
- })
-
- var dispatchExpect = sinon.mock()
- dispatchExpect.twice()
-
- actions.sendTx({id: firstTxId})(dispatchExpect)
- })
- })
- })
-
- describe('when there are two pending txs', function () {
- var firstTxId = 1457634084250832
- var result, initialState
- before(function (done) {
- initialState = {
- appState: {
- currentView: {
- name: 'confTx',
- },
- },
- metamask: {
- unapprovedTxs: {
- '1457634084250832': {
- id: firstTxId,
- status: 'unconfirmed',
- time: 1457634084250,
- },
- '1457634084250833': {
- id: 1457634084250833,
- status: 'unconfirmed',
- time: 1457634084255,
- },
- },
- },
- }
- freeze(initialState)
-
- // Mocking a background connection:
- actions._setBackgroundConnection({
- approveTransaction (firstTxId, cb) { cb() },
- })
-
- actions.sendTx({id: firstTxId})(function (action) {
- result = reducers(initialState, action)
- })
- done()
- })
-
- it('should stay on the confTx view', function () {
- assert.equal(result.appState.currentView.name, 'confTx')
- })
-
- it('should transition to the first tx', function () {
- assert.equal(result.appState.currentView.context, 0)
- })
- })
})
})
diff --git a/test/unit/nonce-tracker-test.js b/test/unit/nonce-tracker-test.js
index 36025a360..8970cf84d 100644
--- a/test/unit/nonce-tracker-test.js
+++ b/test/unit/nonce-tracker-test.js
@@ -1,41 +1,203 @@
const assert = require('assert')
const NonceTracker = require('../../app/scripts/lib/nonce-tracker')
+const MockTxGen = require('../lib/mock-tx-gen')
+let providerResultStub = {}
describe('Nonce Tracker', function () {
- let nonceTracker, provider, getPendingTransactions, pendingTxs
-
-
- beforeEach(function () {
- pendingTxs = [{
- 'status': 'submitted',
- 'txParams': {
- 'from': '0x7d3517b0d011698406d6e0aed8453f0be2697926',
- 'gas': '0x30d40',
- 'value': '0x0',
- 'nonce': '0x0',
- },
- }]
-
-
- getPendingTransactions = () => pendingTxs
- provider = {
- sendAsync: (_, cb) => { cb(undefined, {result: '0x0'}) },
- _blockTracker: {
- getCurrentBlock: () => '0x11b568',
- },
- }
- nonceTracker = new NonceTracker({
- provider,
- getPendingTransactions,
- })
- })
+ let nonceTracker, provider
+ let getPendingTransactions, pendingTxs
+ let getConfirmedTransactions, confirmedTxs
describe('#getNonceLock', function () {
- it('should work', async function () {
- this.timeout(15000)
- const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
- assert.equal(nonceLock.nextNonce, '1', 'nonce should be 1')
- await nonceLock.releaseLock()
+
+ describe('with 3 confirmed and 1 pending', function () {
+ beforeEach(function () {
+ const txGen = new MockTxGen()
+ confirmedTxs = txGen.generate({ status: 'confirmed' }, { count: 3 })
+ pendingTxs = txGen.generate({ status: 'submitted' }, { count: 1 })
+ nonceTracker = generateNonceTrackerWith(pendingTxs, confirmedTxs, '0x1')
+ })
+
+ it('should return 4', async function () {
+ this.timeout(15000)
+ const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
+ assert.equal(nonceLock.nextNonce, '4', `nonce should be 4 got ${nonceLock.nextNonce}`)
+ await nonceLock.releaseLock()
+ })
+
+ it('should use localNonce if network returns a nonce lower then a confirmed tx in state', async function () {
+ this.timeout(15000)
+ const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
+ assert.equal(nonceLock.nextNonce, '4', 'nonce should be 4')
+ await nonceLock.releaseLock()
+ })
+ })
+
+ describe('with no previous txs', function () {
+ beforeEach(function () {
+ nonceTracker = generateNonceTrackerWith([], [])
+ })
+
+ it('should return 0', async function () {
+ this.timeout(15000)
+ const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
+ assert.equal(nonceLock.nextNonce, '0', `nonce should be 0 returned ${nonceLock.nextNonce}`)
+ await nonceLock.releaseLock()
+ })
+ })
+
+ describe('with multiple previous txs with same nonce', function () {
+ beforeEach(function () {
+ const txGen = new MockTxGen()
+ confirmedTxs = txGen.generate({ status: 'confirmed' }, { count: 1 })
+ pendingTxs = txGen.generate({
+ status: 'submitted',
+ txParams: { nonce: '0x01' },
+ }, { count: 5 })
+
+ nonceTracker = generateNonceTrackerWith(pendingTxs, confirmedTxs, '0x0')
+ })
+
+ it('should return nonce after those', async function () {
+ this.timeout(15000)
+ const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
+ assert.equal(nonceLock.nextNonce, '2', `nonce should be 2 got ${nonceLock.nextNonce}`)
+ await nonceLock.releaseLock()
+ })
+ })
+
+ describe('when local confirmed count is higher than network nonce', function () {
+ beforeEach(function () {
+ const txGen = new MockTxGen()
+ confirmedTxs = txGen.generate({ status: 'confirmed' }, { count: 3 })
+ nonceTracker = generateNonceTrackerWith([], confirmedTxs, '0x1')
+ })
+
+ it('should return nonce after those', async function () {
+ this.timeout(15000)
+ const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
+ assert.equal(nonceLock.nextNonce, '3', `nonce should be 3 got ${nonceLock.nextNonce}`)
+ await nonceLock.releaseLock()
+ })
+ })
+
+ describe('when local pending count is higher than other metrics', function () {
+ beforeEach(function () {
+ const txGen = new MockTxGen()
+ pendingTxs = txGen.generate({ status: 'submitted' }, { count: 2 })
+ nonceTracker = generateNonceTrackerWith(pendingTxs, [])
+ })
+
+ it('should return nonce after those', async function () {
+ this.timeout(15000)
+ const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
+ assert.equal(nonceLock.nextNonce, '2', `nonce should be 2 got ${nonceLock.nextNonce}`)
+ await nonceLock.releaseLock()
+ })
+ })
+
+ describe('when provider nonce is higher than other metrics', function () {
+ beforeEach(function () {
+ const txGen = new MockTxGen()
+ pendingTxs = txGen.generate({ status: 'submitted' }, { count: 2 })
+ nonceTracker = generateNonceTrackerWith(pendingTxs, [], '0x05')
+ })
+
+ it('should return nonce after those', async function () {
+ this.timeout(15000)
+ const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
+ assert.equal(nonceLock.nextNonce, '5', `nonce should be 5 got ${nonceLock.nextNonce}`)
+ await nonceLock.releaseLock()
+ })
+ })
+
+ describe('when there are some pending nonces below the remote one and some over.', function () {
+ beforeEach(function () {
+ const txGen = new MockTxGen()
+ pendingTxs = txGen.generate({ status: 'submitted' }, { count: 5 })
+ nonceTracker = generateNonceTrackerWith(pendingTxs, [], '0x03')
+ })
+
+ it('should return nonce after those', async function () {
+ this.timeout(15000)
+ const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
+ assert.equal(nonceLock.nextNonce, '5', `nonce should be 5 got ${nonceLock.nextNonce}`)
+ await nonceLock.releaseLock()
+ })
+ })
+
+ describe('when there are pending nonces non sequentially over the network nonce.', function () {
+ beforeEach(function () {
+ const txGen = new MockTxGen()
+ txGen.generate({ status: 'submitted' }, { count: 5 })
+ // 5 over that number
+ pendingTxs = txGen.generate({ status: 'submitted' }, { count: 5 })
+ nonceTracker = generateNonceTrackerWith(pendingTxs, [], '0x00')
+ })
+
+ it('should return nonce after network nonce', async function () {
+ this.timeout(15000)
+ const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
+ assert.equal(nonceLock.nextNonce, '0', `nonce should be 0 got ${nonceLock.nextNonce}`)
+ await nonceLock.releaseLock()
+ })
+ })
+
+ describe('When all three return different values', function () {
+ beforeEach(function () {
+ const txGen = new MockTxGen()
+ const confirmedTxs = txGen.generate({ status: 'confirmed' }, { count: 10 })
+ const pendingTxs = txGen.generate({
+ status: 'submitted',
+ nonce: 100,
+ }, { count: 1 })
+ // 0x32 is 50 in hex:
+ nonceTracker = generateNonceTrackerWith(pendingTxs, confirmedTxs, '0x32')
+ })
+
+ it('should return nonce after network nonce', async function () {
+ this.timeout(15000)
+ const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
+ assert.equal(nonceLock.nextNonce, '50', `nonce should be 50 got ${nonceLock.nextNonce}`)
+ await nonceLock.releaseLock()
+ })
+ })
+
+ describe('Faq issue 67', function () {
+ beforeEach(function () {
+ const txGen = new MockTxGen()
+ const confirmedTxs = txGen.generate({ status: 'confirmed' }, { count: 64 })
+ const pendingTxs = txGen.generate({
+ status: 'submitted',
+ }, { count: 10 })
+ // 0x40 is 64 in hex:
+ nonceTracker = generateNonceTrackerWith(pendingTxs, [], '0x40')
+ })
+
+ it('should return nonce after network nonce', async function () {
+ this.timeout(15000)
+ const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
+ assert.equal(nonceLock.nextNonce, '74', `nonce should be 74 got ${nonceLock.nextNonce}`)
+ await nonceLock.releaseLock()
+ })
})
})
})
+
+function generateNonceTrackerWith (pending, confirmed, providerStub = '0x0') {
+ const getPendingTransactions = () => pending
+ const getConfirmedTransactions = () => confirmed
+ providerResultStub.result = providerStub
+ const provider = {
+ sendAsync: (_, cb) => { cb(undefined, providerResultStub) },
+ _blockTracker: {
+ getCurrentBlock: () => '0x11b568',
+ },
+ }
+ return new NonceTracker({
+ provider,
+ getPendingTransactions,
+ getConfirmedTransactions,
+ })
+}
+
diff --git a/test/unit/tx-controller-test.js b/test/unit/tx-controller-test.js
index 57d7deccd..7bb193242 100644
--- a/test/unit/tx-controller-test.js
+++ b/test/unit/tx-controller-test.js
@@ -6,12 +6,15 @@ const clone = require('clone')
const sinon = require('sinon')
const TransactionController = require('../../app/scripts/controllers/transactions')
const TxProvideUtils = require('../../app/scripts/lib/tx-utils')
+const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
+
const noop = () => true
const currentNetworkId = 42
const otherNetworkId = 36
const privKey = new Buffer('8718b9618a37d1fc78c436511fc6df3c8258d3250635bba617f33003270ec03e', 'hex')
const { createStubedProvider } = require('../stub/provider')
+
describe('Transaction Controller', function () {
let txController, engine, provider, providerResultStub
@@ -47,7 +50,7 @@ describe('Transaction Controller', function () {
metamaskNetworkId: currentNetworkId,
txParams,
}
- txController._saveTxList([txMeta])
+ txController.addTx(txMeta)
stub = sinon.stub(txController, 'addUnapprovedTransaction').returns(Promise.resolve(txMeta))
})
@@ -279,12 +282,15 @@ describe('Transaction Controller', function () {
it('replaces the tx with the same id', function () {
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')
+ const tx1 = txController.getTx('1')
+ tx1.status = 'blah'
+ tx1.hash = 'foo'
+ txController.updateTx(tx1)
+ const savedResult = txController.getTx('1')
+ assert.equal(savedResult.hash, 'foo')
})
- it('updates gas price', function () {
+ it('updates gas price and adds history items', function () {
const originalGasPrice = '0x01'
const desiredGasPrice = '0x02'
@@ -297,13 +303,22 @@ describe('Transaction Controller', function () {
},
}
- const updatedMeta = clone(txMeta)
-
txController.addTx(txMeta)
- updatedMeta.txParams.gasPrice = desiredGasPrice
- txController.updateTx(updatedMeta)
- var result = txController.getTx('1')
+ const updatedTx = txController.getTx('1')
+ // verify tx was initialized correctly
+ assert.equal(updatedTx.history.length, 1, 'one history item (initial)')
+ assert.equal(Array.isArray(updatedTx.history[0]), false, 'first history item is initial state')
+ assert.deepEqual(updatedTx.history[0], txStateHistoryHelper.snapshotFromTxMeta(updatedTx), 'first history item is initial state')
+ // modify value and updateTx
+ updatedTx.txParams.gasPrice = desiredGasPrice
+ txController.updateTx(updatedTx)
+ // check updated value
+ const result = txController.getTx('1')
assert.equal(result.txParams.gasPrice, desiredGasPrice, 'gas price updated')
+ // validate history was updated
+ assert.equal(result.history.length, 2, 'two history items (initial + diff)')
+ const expectedEntry = { op: 'replace', path: '/txParams/gasPrice', value: desiredGasPrice }
+ assert.deepEqual(result.history[1], [expectedEntry], 'two history items (initial + diff)')
})
})
diff --git a/test/unit/tx-state-history-helper-test.js b/test/unit/tx-state-history-helper-test.js
new file mode 100644
index 000000000..90cb10713
--- /dev/null
+++ b/test/unit/tx-state-history-helper-test.js
@@ -0,0 +1,26 @@
+const assert = require('assert')
+const clone = require('clone')
+const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
+
+describe('deepCloneFromTxMeta', function () {
+ it('should clone deep', function () {
+ const input = {
+ foo: {
+ bar: {
+ bam: 'baz'
+ }
+ }
+ }
+ const output = txStateHistoryHelper.snapshotFromTxMeta(input)
+ assert('foo' in output, 'has a foo key')
+ assert('bar' in output.foo, 'has a bar key')
+ assert('bam' in output.foo.bar, 'has a bar key')
+ assert.equal(output.foo.bar.bam, 'baz', 'has a baz value')
+ })
+
+ it('should remove the history key', function () {
+ const input = { foo: 'bar', history: 'remembered' }
+ const output = txStateHistoryHelper.snapshotFromTxMeta(input)
+ assert(typeof output.history, 'undefined', 'should remove history')
+ })
+})
diff --git a/test/unit/tx-state-history-helper.js b/test/unit/tx-state-history-helper.js
new file mode 100644
index 000000000..5bb6c9bee
--- /dev/null
+++ b/test/unit/tx-state-history-helper.js
@@ -0,0 +1,23 @@
+const assert = require('assert')
+const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
+const testVault = require('../data/v17-long-history.json')
+
+
+describe('tx-state-history-helper', function () {
+ it('migrates history to diffs and can recover original values', function () {
+ testVault.data.TransactionController.transactions.forEach((tx, index) => {
+ const newHistory = txStateHistoryHelper.migrateFromSnapshotsToDiffs(tx.history)
+ newHistory.forEach((newEntry, index) => {
+ if (index === 0) {
+ assert.equal(Array.isArray(newEntry), false, 'initial history item IS NOT a json patch obj')
+ } else {
+ assert.equal(Array.isArray(newEntry), true, 'non-initial history entry IS a json patch obj')
+ }
+ const oldEntry = tx.history[index]
+ const historySubset = newHistory.slice(0, index + 1)
+ const reconstructedValue = txStateHistoryHelper.replayHistory(historySubset)
+ assert.deepEqual(oldEntry, reconstructedValue, 'was able to reconstruct old entry from diffs')
+ })
+ })
+ })
+})
diff --git a/testem.yml b/testem.yml
deleted file mode 100644
index 2cf40f7f4..000000000
--- a/testem.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-launch_in_dev:
- - Chrome
- - Firefox
-launch_in_ci:
- - Chrome
- - Firefox
-framework:
- - qunit
-before_tests: "npm run buildCiUnits"
-test_page: "test/integration/index.html"
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 47da70277..678c68a6a 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -126,6 +126,7 @@ var actions = {
txError: txError,
nextTx: nextTx,
previousTx: previousTx,
+ cancelAllTx: cancelAllTx,
viewPendingTx: viewPendingTx,
VIEW_PENDING_TX: 'VIEW_PENDING_TX',
// app messages
@@ -420,6 +421,7 @@ function signPersonalMsg (msgData) {
function signTx (txData) {
return (dispatch) => {
+ dispatch(actions.showLoadingIndication())
global.ethQuery.sendTransaction(txData, (err, data) => {
dispatch(actions.hideLoadingIndication())
if (err) return dispatch(actions.displayWarning(err.message))
@@ -464,6 +466,7 @@ function updateAndApproveTx (txData) {
dispatch(actions.hideLoadingIndication())
if (err) {
dispatch(actions.txError(err))
+ dispatch(actions.goHome())
return log.error(err.message)
}
dispatch(actions.completedTx(txData.id))
@@ -506,6 +509,16 @@ function cancelTx (txData) {
}
}
+function cancelAllTx (txsData) {
+ return (dispatch) => {
+ txsData.forEach((txData, i) => {
+ background.cancelTransaction(txData.id, () => {
+ dispatch(actions.completedTx(txData.id))
+ i === txsData.length - 1 ? dispatch(actions.goHome()) : null
+ })
+ })
+ }
+}
//
// initialize screen
//
diff --git a/ui/app/add-token.js b/ui/app/add-token.js
index 5c6dea4a0..4374ee586 100644
--- a/ui/app/add-token.js
+++ b/ui/app/add-token.js
@@ -3,6 +3,8 @@ const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
const actions = require('./actions')
+const Tooltip = require('./components/tooltip.js')
+
const ethUtil = require('ethereumjs-util')
const abi = require('human-standard-token-abi')
@@ -15,6 +17,7 @@ module.exports = connect(mapStateToProps)(AddTokenScreen)
function mapStateToProps (state) {
return {
+ identities: state.metamask.identities,
}
}
@@ -64,15 +67,25 @@ AddTokenScreen.prototype.render = function () {
}, [
h('div', [
- h('span', {
- style: { fontWeight: 'bold', paddingRight: '10px'},
- }, 'Token Address'),
+ h(Tooltip, {
+ position: 'top',
+ title: 'The contract of the actual token contract. Click for more info.',
+ }, [
+ h('a', {
+ style: { fontWeight: 'bold', paddingRight: '10px'},
+ href: 'https://consensyssupport.happyfox.com/staff/kb/article/24-what-is-a-token-contract-address',
+ target: '_blank',
+ }, [
+ h('span', 'Token Contract Address '),
+ h('i.fa.fa-question-circle'),
+ ]),
+ ]),
]),
h('section.flex-row.flex-center', [
h('input#token-address', {
name: 'address',
- placeholder: 'Token Address',
+ placeholder: 'Token Contract Address',
onChange: this.tokenAddressDidChange.bind(this),
style: {
width: 'inherit',
@@ -171,7 +184,9 @@ AddTokenScreen.prototype.tokenAddressDidChange = function (event) {
AddTokenScreen.prototype.validateInputs = function () {
let msg = ''
const state = this.state
+ const identitiesList = Object.keys(this.props.identities)
const { address, symbol, decimals } = state
+ const standardAddress = ethUtil.addHexPrefix(address).toLowerCase()
const validAddress = ethUtil.isValidAddress(address)
if (!validAddress) {
@@ -189,7 +204,12 @@ AddTokenScreen.prototype.validateInputs = function () {
msg += 'Symbol must be between 0 and 10 characters.'
}
- const isValid = validAddress && validDecimals
+ const ownAddress = identitiesList.includes(standardAddress)
+ if (ownAddress) {
+ msg = 'Personal address detected. Input the token contract address.'
+ }
+
+ const isValid = validAddress && validDecimals && !ownAddress
if (!isValid) {
this.setState({
@@ -215,4 +235,3 @@ AddTokenScreen.prototype.attemptToAutoFillTokenParams = async function (address)
this.setState({ symbol: symbol[0], decimals: decimals[0].toString() })
}
}
-
diff --git a/ui/app/app.js b/ui/app/app.js
index 1ca59e406..14e6a26e2 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -46,6 +46,7 @@ function mapStateToProps (state) {
identities,
accounts,
address,
+ keyrings,
} = state.metamask
const selected = address || Object.keys(accounts)[0]
@@ -75,6 +76,7 @@ function mapStateToProps (state) {
// state needed to get account dropdown temporarily rendering from app bar
identities,
selected,
+ keyrings,
}
}
diff --git a/ui/app/components/account-export.js b/ui/app/components/account-export.js
index 330f73805..32b103c86 100644
--- a/ui/app/components/account-export.js
+++ b/ui/app/components/account-export.js
@@ -1,6 +1,7 @@
const Component = require('react').Component
const h = require('react-hyperscript')
const inherits = require('util').inherits
+const exportAsFile = require('../util').exportAsFile
const copyToClipboard = require('copy-to-clipboard')
const actions = require('../actions')
const ethUtil = require('ethereumjs-util')
@@ -20,20 +21,21 @@ function mapStateToProps (state) {
}
ExportAccountView.prototype.render = function () {
- var state = this.props
- var accountDetail = state.accountDetail
+ const state = this.props
+ const accountDetail = state.accountDetail
+ const nickname = state.identities[state.address].name
if (!accountDetail) return h('div')
- var accountExport = accountDetail.accountExport
+ const accountExport = accountDetail.accountExport
- var notExporting = accountExport === 'none'
- var exportRequested = accountExport === 'requested'
- var accountExported = accountExport === 'completed'
+ const notExporting = accountExport === 'none'
+ const exportRequested = accountExport === 'requested'
+ const accountExported = accountExport === 'completed'
if (notExporting) return h('div')
if (exportRequested) {
- var warning = `Export private keys at your own risk.`
+ const warning = `Export private keys at your own risk.`
return (
h('div', {
style: {
@@ -89,6 +91,8 @@ ExportAccountView.prototype.render = function () {
}
if (accountExported) {
+ const plainKey = ethUtil.stripHexPrefix(accountDetail.privateKey)
+
return h('div.privateKey', {
style: {
margin: '0 20px',
@@ -105,10 +109,16 @@ ExportAccountView.prototype.render = function () {
onClick: function (event) {
copyToClipboard(ethUtil.stripHexPrefix(accountDetail.privateKey))
},
- }, ethUtil.stripHexPrefix(accountDetail.privateKey)),
+ }, plainKey),
h('button', {
onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)),
}, 'Done'),
+ h('button', {
+ style: {
+ marginLeft: '10px',
+ },
+ onClick: () => exportAsFile(`MetaMask ${nickname} Private Key`, plainKey),
+ }, 'Save as File'),
])
}
}
@@ -117,6 +127,6 @@ ExportAccountView.prototype.onExportKeyPress = function (event) {
if (event.key !== 'Enter') return
event.preventDefault()
- var input = document.getElementById('exportAccount').value
+ const input = document.getElementById('exportAccount').value
this.props.dispatch(actions.exportAccount(input, this.props.address))
}
diff --git a/ui/app/components/dropdowns/components/account-dropdowns.js b/ui/app/components/dropdowns/components/account-dropdowns.js
index bb112dcca..e2d3d6d64 100644
--- a/ui/app/components/dropdowns/components/account-dropdowns.js
+++ b/ui/app/components/dropdowns/components/account-dropdowns.js
@@ -25,7 +25,7 @@ class AccountDropdowns extends Component {
}
renderAccounts () {
- const { identities, accounts, selected, menuItemStyles, actions } = this.props
+ const { identities, accounts, selected, menuItemStyles, actions, keyrings } = this.props
return Object.keys(identities).map((key, index) => {
const identity = identities[key]
@@ -33,6 +33,12 @@ class AccountDropdowns extends Component {
const balanceValue = accounts[key].balance
const formattedBalance = balanceValue ? formatBalance(balanceValue, 6) : '...'
+ const simpleAddress = identity.address.substring(2).toLowerCase()
+
+ const keyring = keyrings.find((kr) => {
+ return kr.accounts.includes(simpleAddress) ||
+ kr.accounts.includes(identity.address)
+ })
return h(
DropdownMenuItem,
@@ -88,6 +94,7 @@ class AccountDropdowns extends Component {
marginLeft: '10px',
},
}, [
+ this.indicateIfLoose(keyring),
h('span.account-dropdown-name', {
style: {
fontSize: '18px',
@@ -97,6 +104,7 @@ class AccountDropdowns extends Component {
textOverflow: 'ellipsis',
},
}, identity.name || ''),
+ h('span', { style: { marginLeft: '20px', fontSize: '24px' } }, isSelected ? h('.check', '✓') : null),
h('span.account-dropdown-balance', {
style: {
@@ -125,11 +133,35 @@ class AccountDropdowns extends Component {
]),
]),
+// =======
+// },
+// ),
+// this.indicateIfLoose(keyring),
+// h('span', {
+// style: {
+// marginLeft: '20px',
+// fontSize: '24px',
+// maxWidth: '145px',
+// whiteSpace: 'nowrap',
+// overflow: 'hidden',
+// textOverflow: 'ellipsis',
+// },
+// }, identity.name || ''),
+// h('span', { style: { marginLeft: '20px', fontSize: '24px' } }, isSelected ? h('.check', '✓') : null),
+// >>>>>>> master:ui/app/components/account-dropdowns.js
]
)
})
}
+ indicateIfLoose (keyring) {
+ try { // Sometimes keyrings aren't loaded yet:
+ const type = keyring.type
+ const isLoose = type !== 'HD Key Tree'
+ return isLoose ? h('.keyring-label', 'LOOSE') : null
+ } catch (e) { return }
+ }
+
renderAccountSelector () {
const { actions, useCssTransition, innerStyle } = this.props
const { accountSelectorActive, menuItemStyles } = this.state
@@ -389,7 +421,8 @@ AccountDropdowns.defaultProps = {
AccountDropdowns.propTypes = {
identities: PropTypes.objectOf(PropTypes.object),
- selected: PropTypes.string, // TODO: refactor to be more explicit: selectedAddress
+ selected: PropTypes.string,
+ keyrings: PropTypes.array,
}
const mapDispatchToProps = (dispatch) => {
@@ -420,5 +453,11 @@ const mapDispatchToProps = (dispatch) => {
}
}
-module.exports = connect(null, mapDispatchToProps)(AccountDropdowns)
+function mapStateToProps (state) {
+ return {
+ keyrings: state.metamask.keyrings,
+ }
+}
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDropdowns)
diff --git a/ui/app/components/network.js b/ui/app/components/network.js
index 9133c78e3..8424a479a 100644
--- a/ui/app/components/network.js
+++ b/ui/app/components/network.js
@@ -23,7 +23,7 @@ Network.prototype.render = function () {
let iconName, hoverText
if (networkNumber === 'loading') {
- return h('span', {
+ return h('span.pointer', {
style: {
display: 'flex',
alignItems: 'center',
@@ -38,7 +38,7 @@ Network.prototype.render = function () {
},
src: 'images/loading.svg',
}),
- h('i.fa.fa-sort-desc'),
+ h('i.fa.fa-caret-down'),
])
} else if (providerName === 'mainnet') {
hoverText = 'Main Ethereum Network'
@@ -77,7 +77,8 @@ Network.prototype.render = function () {
style: {
color: '#039396',
}},
- 'Ethereum Main Net'),
+ 'Main Network'),
+ h('i.fa.fa-caret-down.fa-lg'),
])
case 'ropsten-test-network':
return h('.network-indicator', [
@@ -90,6 +91,7 @@ Network.prototype.render = function () {
color: '#ff6666',
}},
'Ropsten Test Net'),
+ h('i.fa.fa-caret-down.fa-lg'),
])
case 'kovan-test-network':
return h('.network-indicator', [
@@ -102,6 +104,7 @@ Network.prototype.render = function () {
color: '#690496',
}},
'Kovan Test Net'),
+ h('i.fa.fa-caret-down.fa-lg'),
])
case 'rinkeby-test-network':
return h('.network-indicator', [
@@ -114,6 +117,7 @@ Network.prototype.render = function () {
color: '#e7a218',
}},
'Rinkeby Test Net'),
+ h('i.fa.fa-caret-down.fa-lg'),
])
default:
return h('.network-indicator', [
@@ -129,6 +133,7 @@ Network.prototype.render = function () {
color: '#AEAEAE',
}},
'Private Network'),
+ h('i.fa.fa-caret-down.fa-lg'),
])
}
})(),
diff --git a/ui/app/components/pending-msg-details.js b/ui/app/components/pending-msg-details.js
index 16308d121..718a22de0 100644
--- a/ui/app/components/pending-msg-details.js
+++ b/ui/app/components/pending-msg-details.js
@@ -38,7 +38,7 @@ PendingMsgDetails.prototype.render = function () {
// message data
h('.tx-data.flex-column.flex-justify-center.flex-grow.select-none', [
- h('.flex-row.flex-space-between', [
+ h('.flex-column.flex-space-between', [
h('label.font-small', 'MESSAGE'),
h('span.font-small', msgParams.data),
]),
diff --git a/ui/app/components/pending-msg.js b/ui/app/components/pending-msg.js
index b2cac164a..834719c53 100644
--- a/ui/app/components/pending-msg.js
+++ b/ui/app/components/pending-msg.js
@@ -18,6 +18,9 @@ PendingMsg.prototype.render = function () {
h('div', {
key: msgData.id,
+ style: {
+ maxWidth: '350px',
+ },
}, [
// header
@@ -32,10 +35,21 @@ PendingMsg.prototype.render = function () {
style: {
margin: '10px',
},
- }, `Signing this message can have
+ }, [
+ `Signing this message can have
dangerous side effects. Only sign messages from
sites you fully trust with your entire account.
- This will be fixed in a future version.`),
+ This dangerous method will be removed in a future version. `,
+ h('a', {
+ href: 'https://medium.com/metamask/the-new-secure-way-to-sign-data-in-your-browser-6af9dd2a1527',
+ style: { color: 'rgb(247, 134, 28)' },
+ onClick: (event) => {
+ event.preventDefault()
+ const url = 'https://medium.com/metamask/the-new-secure-way-to-sign-data-in-your-browser-6af9dd2a1527'
+ global.platform.openWindow({ url })
+ },
+ }, 'Read more here.'),
+ ]),
// message details
h(PendingTxDetails, state),
diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js
index c1b079a25..a679107c9 100644
--- a/ui/app/components/pending-tx.js
+++ b/ui/app/components/pending-tx.js
@@ -240,6 +240,15 @@ PendingTx.prototype.render = function () {
totalInETH,
} = this.getData()
+ // This is from the latest master
+ // It handles some of the errors that we are not currently handling
+ // Leaving as comments fo reference
+
+ // const balanceBn = hexToBn(balance)
+ // const insufficientBalance = balanceBn.lt(maxCost)
+ // const buyDisabled = insufficientBalance || !this.state.valid || !isValidAddress || this.state.submitting
+ // const showRejectAll = props.unconfTxListLength > 1
+
this.inputs = []
return (
@@ -332,9 +341,88 @@ PendingTx.prototype.render = function () {
h('div.confirm-screen-row-info', `$${totalInUSD} USD`),
h('div.confirm-screen-row-detail', `${totalInETH} ETH`),
]),
- ]),
+ ]),
]),
+// These are latest errors handling from master
+// Leaving as comments as reference when we start implementing error handling
+// h('style', `
+// .conf-buttons button {
+// margin-left: 10px;
+// text-transform: uppercase;
+// }
+// `),
+
+// txMeta.simulationFails ?
+// h('.error', {
+// style: {
+// marginLeft: 50,
+// fontSize: '0.9em',
+// },
+// }, 'Transaction Error. Exception thrown in contract code.')
+// : null,
+
+// !isValidAddress ?
+// h('.error', {
+// style: {
+// marginLeft: 50,
+// fontSize: '0.9em',
+// },
+// }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH.')
+// : null,
+
+// insufficientBalance ?
+// h('span.error', {
+// style: {
+// marginLeft: 50,
+// fontSize: '0.9em',
+// },
+// }, 'Insufficient balance for transaction')
+// : null,
+
+// // send + cancel
+// h('.flex-row.flex-space-around.conf-buttons', {
+// style: {
+// display: 'flex',
+// justifyContent: 'flex-end',
+// margin: '14px 25px',
+// },
+// }, [
+// h('button', {
+// onClick: (event) => {
+// this.resetGasFields()
+// event.preventDefault()
+// },
+// }, 'Reset'),
+
+// // Accept Button or Buy Button
+// insufficientBalance ? h('button.btn-green', { onClick: props.buyEth }, 'Buy Ether') :
+// h('input.confirm.btn-green', {
+// type: 'submit',
+// value: 'SUBMIT',
+// style: { marginLeft: '10px' },
+// disabled: buyDisabled,
+// }),
+
+// h('button.cancel.btn-red', {
+// onClick: props.cancelTransaction,
+// }, 'Reject'),
+// ]),
+// showRejectAll ? h('.flex-row.flex-space-around.conf-buttons', {
+// style: {
+// display: 'flex',
+// justifyContent: 'flex-end',
+// margin: '14px 25px',
+// },
+// }, [
+// h('button.cancel.btn-red', {
+// onClick: props.cancelAllTransactions,
+// }, 'Reject All'),
+// ]) : null,
+// ]),
+// ])
+// )
+// }
]),
h('form#pending-tx-form.flex-column.flex-center', {
diff --git a/ui/app/components/token-list.js b/ui/app/components/token-list.js
index 2d1dd0ea7..0efa89c63 100644
--- a/ui/app/components/token-list.js
+++ b/ui/app/components/token-list.js
@@ -48,10 +48,28 @@ TokenList.prototype.render = function () {
if (error) {
log.error(error)
- return this.message('There was a problem loading your token balances.')
+ return h('.hotFix', {
+ style: {
+ padding: '80px',
+ },
+ }, [
+ 'We had trouble loading your token balances. You can view them ',
+ h('span.hotFix', {
+ style: {
+ color: 'rgba(247, 134, 28, 1)',
+ cursor: 'pointer',
+ },
+ onClick: () => {
+ global.platform.openWindow({
+ url: `https://ethplorer.io/address/${userAddress}`,
+ })
+ },
+ }, 'here'),
+ ])
}
return h('div', tokens.map((tokenData) => h(TokenCell, tokenData)))
+
}
TokenList.prototype.message = function (body) {
@@ -84,7 +102,7 @@ TokenList.prototype.createFreshTokenTracker = function () {
this.tracker = new TokenTracker({
userAddress,
provider: global.ethereumProvider,
- tokens: uniqueMergeTokens(defaultTokens, this.props.tokens),
+ tokens: this.props.tokens,
pollingInterval: 8000,
})
@@ -149,4 +167,3 @@ function uniqueMergeTokens (tokensA, tokensB = []) {
})
return result
}
-
diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js
index eca2a7100..880a288af 100644
--- a/ui/app/components/transaction-list-item.js
+++ b/ui/app/components/transaction-list-item.js
@@ -60,16 +60,7 @@ TransactionListItem.prototype.render = function () {
}, [
h('.identicon-wrapper.flex-column.flex-center.select-none', [
- h('.pop-hover', {
- onClick: (event) => {
- event.stopPropagation()
- if (!isTx || isPending) return
- var url = `https://metamask.github.io/eth-tx-viz/?tx=${transaction.hash}`
- global.platform.openWindow({ url })
- },
- }, [
- h(TransactionIcon, { txParams, transaction, isTx, isMsg }),
- ]),
+ h(TransactionIcon, { txParams, transaction, isTx, isMsg }),
]),
h(Tooltip, {
diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js
index 7cc319509..7062eee6b 100644
--- a/ui/app/conf-tx.js
+++ b/ui/app/conf-tx.js
@@ -76,6 +76,7 @@ ConfirmTxScreen.prototype.render = function () {
cancelMessage: this.cancelMessage.bind(this, txData),
cancelPersonalMessage: this.cancelPersonalMessage.bind(this, txData),
})
+
}
function currentTxView (opts) {
@@ -116,6 +117,12 @@ ConfirmTxScreen.prototype.cancelTransaction = function (txData, event) {
this.props.dispatch(actions.cancelTx(txData))
}
+ConfirmTxScreen.prototype.cancelAllTransactions = function (unconfTxList, event) {
+ this.stopPropagation(event)
+ event.preventDefault()
+ this.props.dispatch(actions.cancelAllTx(unconfTxList))
+}
+
ConfirmTxScreen.prototype.signMessage = function (msgData, event) {
log.info('conf-tx.js: signing message')
var params = msgData.msgParams
diff --git a/ui/app/config.js b/ui/app/config.js
index 62785c49b..d64088ccb 100644
--- a/ui/app/config.js
+++ b/ui/app/config.js
@@ -5,7 +5,8 @@ const connect = require('react-redux').connect
const actions = require('./actions')
const currencies = require('./conversion.json').rows
const validUrl = require('valid-url')
-const copyToClipboard = require('copy-to-clipboard')
+const exportAsFile = require('./util').exportAsFile
+
module.exports = connect(mapStateToProps)(ConfigScreen)
@@ -110,9 +111,9 @@ ConfigScreen.prototype.render = function () {
alignSelf: 'center',
},
onClick (event) {
- copyToClipboard(window.logState())
+ exportAsFile('MetaMask State Logs', window.logState())
},
- }, 'Copy State Logs'),
+ }, 'Download State Logs'),
]),
h('hr.horizontal-line'),
diff --git a/ui/app/css/itcss/tools/utilities.scss b/ui/app/css/itcss/tools/utilities.scss
index b9c99219b..9f1caa732 100644
--- a/ui/app/css/itcss/tools/utilities.scss
+++ b/ui/app/css/itcss/tools/utilities.scss
@@ -238,7 +238,7 @@ hr.horizontal-line {
border-radius: 10px;
height: 20px;
min-width: 20px;
- position: relative;
+ position: absolute;
display: flex;
align-items: center;
justify-content: center;
diff --git a/ui/app/info.js b/ui/app/info.js
index 899841c83..4c7d4cb4c 100644
--- a/ui/app/info.js
+++ b/ui/app/info.js
@@ -103,7 +103,7 @@ InfoScreen.prototype.render = function () {
[
h('div.fa.fa-support', [
h('a.info', {
- href: 'http://metamask.consensyssupport.happyfox.com',
+ href: 'https://support.metamask.io',
target: '_blank',
}, 'Visit our Support Center'),
]),
diff --git a/ui/app/keychains/hd/create-vault-complete.js b/ui/app/keychains/hd/create-vault-complete.js
index c32751fff..745990351 100644
--- a/ui/app/keychains/hd/create-vault-complete.js
+++ b/ui/app/keychains/hd/create-vault-complete.js
@@ -3,6 +3,7 @@ const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
const actions = require('../../actions')
+const exportAsFile = require('../../util').exportAsFile
module.exports = connect(mapStateToProps)(CreateVaultCompleteScreen)
@@ -65,8 +66,17 @@ CreateVaultCompleteScreen.prototype.render = function () {
style: {
margin: '24px',
fontSize: '0.9em',
+ marginBottom: '10px',
},
}, 'I\'ve copied it somewhere safe'),
+
+ h('button.primary', {
+ onClick: () => exportAsFile(`MetaMask Seed Words`, seed),
+ style: {
+ margin: '10px',
+ fontSize: '0.9em',
+ },
+ }, 'Save Seed Words As File'),
])
)
}
diff --git a/ui/app/reducers.js b/ui/app/reducers.js
index 36045772f..6a2f44534 100644
--- a/ui/app/reducers.js
+++ b/ui/app/reducers.js
@@ -42,7 +42,10 @@ function rootReducer (state, action) {
}
window.logState = function () {
- var stateString = JSON.stringify(window.METAMASK_CACHED_LOG_STATE, removeSeedWords, 2)
+ let state = window.METAMASK_CACHED_LOG_STATE
+ const version = global.platform.getVersion()
+ state.version = version
+ let stateString = JSON.stringify(state, removeSeedWords, 2)
return stateString
}
diff --git a/ui/app/unlock.js b/ui/app/unlock.js
index 1918e2e6a..ec97b03bf 100644
--- a/ui/app/unlock.js
+++ b/ui/app/unlock.js
@@ -80,7 +80,7 @@ UnlockScreen.prototype.render = function () {
color: 'rgb(247, 134, 28)',
textDecoration: 'underline',
},
- }, 'I forgot my password.'),
+ }, 'Restore from seed phrase'),
]),
])
)
diff --git a/ui/app/util.js b/ui/app/util.js
index 6596ebafb..be26e15a5 100644
--- a/ui/app/util.js
+++ b/ui/app/util.js
@@ -53,6 +53,7 @@ module.exports = {
getTxFeeBn,
shortenBalance,
getContractAtAddress,
+ exportAsFile: exportAsFile,
}
function valuesFor (obj) {
@@ -250,3 +251,18 @@ function getTxFeeBn (gas, gasPrice = MIN_GAS_PRICE_BN.toString(16), blockGasLimi
function getContractAtAddress (tokenAddress) {
return global.eth.contract(abi).at(tokenAddress)
}
+
+function exportAsFile (filename, data) {
+ // source: https://stackoverflow.com/a/33542499 by Ludovic Feltz
+ const blob = new Blob([data], {type: 'text/csv'})
+ if (window.navigator.msSaveOrOpenBlob) {
+ window.navigator.msSaveBlob(blob, filename)
+ } else {
+ const elem = window.document.createElement('a')
+ elem.href = window.URL.createObjectURL(blob)
+ elem.download = filename
+ document.body.appendChild(elem)
+ elem.click()
+ document.body.removeChild(elem)
+ }
+}
diff --git a/ui/lib/account-link.js b/ui/lib/account-link.js
index d061d0ad1..037d990fa 100644
--- a/ui/lib/account-link.js
+++ b/ui/lib/account-link.js
@@ -3,19 +3,19 @@ module.exports = function (address, network) {
let link
switch (net) {
case 1: // main net
- link = `http://etherscan.io/address/${address}`
+ link = `https://etherscan.io/address/${address}`
break
case 2: // morden test net
- link = `http://morden.etherscan.io/address/${address}`
+ link = `https://morden.etherscan.io/address/${address}`
break
case 3: // ropsten test net
- link = `http://ropsten.etherscan.io/address/${address}`
+ link = `https://ropsten.etherscan.io/address/${address}`
break
case 4: // rinkeby test net
- link = `http://rinkeby.etherscan.io/address/${address}`
+ link = `https://rinkeby.etherscan.io/address/${address}`
break
case 42: // kovan test net
- link = `http://kovan.etherscan.io/address/${address}`
+ link = `https://kovan.etherscan.io/address/${address}`
break
default:
link = ''
diff --git a/yarn.lock b/yarn.lock
index 84cad4c6c..aed3a9da8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -121,6 +121,10 @@ after@0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/after/-/after-0.8.1.tgz#ab5d4fb883f596816d3515f8f791c0af486dd627"
+after@0.8.2:
+ version "0.8.2"
+ resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
+
ajv-keywords@^1.0.0, ajv-keywords@^1.1.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
@@ -300,6 +304,10 @@ array-reduce@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
+array-slice@^0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5"
+
array-slice@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.0.0.tgz#e73034f00dcc1f40876008fd20feae77bd4b7c2f"
@@ -467,6 +475,14 @@ aws4@^1.2.1:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
+babel-code-frame@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-7.0.0-beta.0.tgz#418a7b5f3f7dc9a4670e61b1158b4c5661bec98d"
+ dependencies:
+ chalk "^2.0.0"
+ esutils "^2.0.2"
+ js-tokens "^3.0.0"
+
babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
@@ -499,14 +515,14 @@ babel-core@^6.0.14, babel-core@^6.23.1, babel-core@^6.24.1, babel-core@^6.26.0:
slash "^1.0.0"
source-map "^0.5.6"
-babel-eslint@^7.2.3:
- version "7.2.3"
- resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-7.2.3.tgz#b2fe2d80126470f5c19442dc757253a897710827"
+babel-eslint@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.0.0.tgz#ce06f385bdfb5b6d7e603f06222f891abd14c240"
dependencies:
- babel-code-frame "^6.22.0"
- babel-traverse "^6.23.1"
- babel-types "^6.23.0"
- babylon "^6.17.0"
+ babel-code-frame "7.0.0-beta.0"
+ babel-traverse "7.0.0-beta.0"
+ babel-types "7.0.0-beta.0"
+ babylon "7.0.0-beta.22"
babel-generator@^6.18.0, babel-generator@^6.26.0:
version "6.26.0"
@@ -572,6 +588,15 @@ babel-helper-explode-class@^6.24.1:
babel-traverse "^6.24.1"
babel-types "^6.24.1"
+babel-helper-function-name@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-7.0.0-beta.0.tgz#d1b6779b647e5c5c31ebeb05e13b998e4d352d56"
+ dependencies:
+ babel-helper-get-function-arity "7.0.0-beta.0"
+ babel-template "7.0.0-beta.0"
+ babel-traverse "7.0.0-beta.0"
+ babel-types "7.0.0-beta.0"
+
babel-helper-function-name@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9"
@@ -582,6 +607,12 @@ babel-helper-function-name@^6.24.1:
babel-traverse "^6.24.1"
babel-types "^6.24.1"
+babel-helper-get-function-arity@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-7.0.0-beta.0.tgz#9d1ab7213bb5efe1ef1638a8ea1489969b5a8b6e"
+ dependencies:
+ babel-types "7.0.0-beta.0"
+
babel-helper-get-function-arity@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d"
@@ -648,6 +679,10 @@ babel-loader@^6.3.2:
mkdirp "^0.5.1"
object-assign "^4.0.1"
+babel-messages@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-7.0.0-beta.0.tgz#6df01296e49fc8fbd0637394326a167f36da817b"
+
babel-messages@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
@@ -1104,6 +1139,15 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runti
core-js "^2.4.0"
regenerator-runtime "^0.11.0"
+babel-template@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-7.0.0-beta.0.tgz#85083cf9e4395d5e48bf5154d7a8d6991cafecfb"
+ dependencies:
+ babel-traverse "7.0.0-beta.0"
+ babel-types "7.0.0-beta.0"
+ babylon "7.0.0-beta.22"
+ lodash "^4.2.0"
+
babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02"
@@ -1114,7 +1158,21 @@ babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0:
babylon "^6.18.0"
lodash "^4.17.4"
-babel-traverse@^6.18.0, babel-traverse@^6.23.1, babel-traverse@^6.24.1, babel-traverse@^6.26.0:
+babel-traverse@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-7.0.0-beta.0.tgz#da14be9b762f62a2f060db464eaafdd8cd072a41"
+ dependencies:
+ babel-code-frame "7.0.0-beta.0"
+ babel-helper-function-name "7.0.0-beta.0"
+ babel-messages "7.0.0-beta.0"
+ babel-types "7.0.0-beta.0"
+ babylon "7.0.0-beta.22"
+ debug "^3.0.1"
+ globals "^10.0.0"
+ invariant "^2.2.0"
+ lodash "^4.2.0"
+
+babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
dependencies:
@@ -1128,7 +1186,15 @@ babel-traverse@^6.18.0, babel-traverse@^6.23.1, babel-traverse@^6.24.1, babel-tr
invariant "^2.2.2"
lodash "^4.17.4"
-babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.26.0:
+babel-types@7.0.0-beta.0:
+ version "7.0.0-beta.0"
+ resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-beta.0.tgz#eb8b6e556470e6dcc4aef982d79ad229469b5169"
+ dependencies:
+ esutils "^2.0.2"
+ lodash "^4.2.0"
+ to-fast-properties "^2.0.0"
+
+babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
dependencies:
@@ -1144,7 +1210,11 @@ babelify@^7.2.0, babelify@^7.3.0:
babel-core "^6.0.14"
object-assign "^4.0.0"
-babylon@^6.17.0, babylon@^6.18.0:
+babylon@7.0.0-beta.22:
+ version "7.0.0-beta.22"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.22.tgz#74f0ad82ed7c7c3cfeab74cf684f815104161b65"
+
+babylon@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
@@ -1204,6 +1274,10 @@ base64id@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/base64id/-/base64id-0.1.0.tgz#02ce0fdeee0cef4f40080e1e73e834f0b1bfce3f"
+base64id@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6"
+
bcrypt-pbkdf@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
@@ -1315,7 +1389,7 @@ block-stream@*:
dependencies:
inherits "~2.0.0"
-bluebird@^3.0.5, bluebird@^3.1.1, bluebird@^3.4.6, bluebird@^3.5.0:
+bluebird@^3.0.5, bluebird@^3.1.1, bluebird@^3.3.0, bluebird@^3.4.6, bluebird@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c"
@@ -1327,6 +1401,21 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.3, bn.js@^4.11.7, bn.js@^4
version "4.11.8"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
+body-parser@^1.16.1:
+ version "1.18.1"
+ resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.1.tgz#9c1629370bcfd42917f30641a2dcbe2ec50d4c26"
+ dependencies:
+ bytes "3.0.0"
+ content-type "~1.0.4"
+ debug "2.6.8"
+ depd "~1.1.1"
+ http-errors "~1.6.2"
+ iconv-lite "0.4.19"
+ on-finished "~2.3.0"
+ qs "6.5.1"
+ raw-body "2.3.2"
+ type-is "~1.6.15"
+
body-parser@~1.14.0:
version "1.14.2"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.14.2.tgz#1015cb1fe2c443858259581db53332f8d0cf50f9"
@@ -1372,6 +1461,12 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
+braces@^0.1.2:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-0.1.5.tgz#c085711085291d8b75fdd74eab0f8597280711e6"
+ dependencies:
+ expand-range "^0.1.0"
+
braces@^1.8.2:
version "1.8.5"
resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
@@ -1606,6 +1701,21 @@ buffer@^5.0.2:
base64-js "^1.0.2"
ieee754 "^1.1.4"
+build@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/build/-/build-0.1.4.tgz#707fe026ffceddcacbfdcdf356eafda64f151046"
+ dependencies:
+ cssmin "0.3.x"
+ jsmin "1.x"
+ jxLoader "*"
+ moo-server "*"
+ promised-io "*"
+ timespan "2.x"
+ uglify-js "1.x"
+ walker "1.x"
+ winston "*"
+ wrench "1.3.x"
+
builtin-modules@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
@@ -1626,6 +1736,10 @@ bytes@2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339"
+bytes@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
+
cached-path-relative@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.1.tgz#d09c4b52800aa4c078e2dd81a869aac90d2e54e7"
@@ -1786,7 +1900,7 @@ cheerio@^0.22.0:
lodash.reject "^4.4.0"
lodash.some "^4.4.0"
-chokidar@^1.0.0, chokidar@^1.4.3, chokidar@^1.6.1, chokidar@^1.7.0:
+chokidar@^1.0.0, chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.6.1, chokidar@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
dependencies:
@@ -1949,10 +2063,16 @@ colors@1.0.3, colors@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
-colors@^1.1.2:
+colors@^1.1.0, colors@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
+combine-lists@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/combine-lists/-/combine-lists-1.0.1.tgz#458c07e09e0d900fc28b70a3fec2dacd1d2cb7f6"
+ dependencies:
+ lodash "^4.5.0"
+
combine-source-map@~0.7.1:
version "0.7.2"
resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.7.2.tgz#0870312856b307a87cc4ac486f3a9a62aeccc09e"
@@ -2067,6 +2187,15 @@ config-chain@~1.1.5:
ini "^1.3.4"
proto-list "~1.2.1"
+connect@^3.6.0:
+ version "3.6.3"
+ resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.3.tgz#f7320d46a25b4be7b483a2236517f24b1e27e301"
+ dependencies:
+ debug "2.6.8"
+ finalhandler "1.0.4"
+ parseurl "~1.3.1"
+ utils-merge "1.0.0"
+
console-browserify@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10"
@@ -2095,7 +2224,7 @@ content-type-parser@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.1.tgz#c3e56988c53c65127fb46d4032a3a900246fdc94"
-content-type@~1.0.1, content-type@~1.0.2:
+content-type@~1.0.1, content-type@~1.0.2, content-type@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
@@ -2132,7 +2261,7 @@ core-js@^1.0.0:
version "1.2.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
-core-js@^2.4.0, core-js@^2.5.0:
+core-js@^2.2.0, core-js@^2.4.0, core-js@^2.5.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b"
@@ -2302,6 +2431,10 @@ cssauron@^1.1.0:
dependencies:
through X.X.X
+cssmin@0.3.x:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/cssmin/-/cssmin-0.3.2.tgz#ddce4c547b510ae0d594a8f1fbf8aaf8e2c5c00d"
+
cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
version "0.3.2"
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b"
@@ -2318,6 +2451,10 @@ currently-unhandled@^0.4.1:
dependencies:
array-find-index "^1.0.1"
+custom-event@~1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425"
+
cycle@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2"
@@ -2390,7 +2527,7 @@ debug@2.6.8, debug@^2.1.0, debug@^2.2.0, debug@^2.6.0, debug@^2.6.3, debug@^2.6.
dependencies:
ms "2.0.0"
-debug@^3.0.0:
+debug@^3.0.0, debug@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.0.1.tgz#0564c612b521dc92d9f2988f0549e34f9c98db64"
dependencies:
@@ -2571,6 +2708,10 @@ detective@^4.0.0, detective@^4.3.1:
acorn "^4.0.3"
defined "^1.0.0"
+di@^0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c"
+
diff@3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
@@ -2650,6 +2791,15 @@ dom-helpers@^3.2.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a"
+dom-serialize@^2.2.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b"
+ dependencies:
+ custom-event "~1.0.0"
+ ent "~2.2.0"
+ extend "^3.0.0"
+ void-elements "^2.0.0"
+
dom-serializer@0, dom-serializer@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
@@ -2787,7 +2937,7 @@ encoding@^0.1.11:
dependencies:
iconv-lite "~0.4.13"
-end-of-stream@^1.0.0, end-of-stream@^1.1.0:
+end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206"
dependencies:
@@ -2810,6 +2960,23 @@ engine.io-client@1.8.0:
xmlhttprequest-ssl "1.5.3"
yeast "0.1.2"
+engine.io-client@1.8.3:
+ version "1.8.3"
+ resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-1.8.3.tgz#1798ed93451246453d4c6f635d7a201fe940d5ab"
+ dependencies:
+ component-emitter "1.2.1"
+ component-inherit "0.0.3"
+ debug "2.3.3"
+ engine.io-parser "1.3.2"
+ has-cors "1.1.0"
+ indexof "0.0.1"
+ parsejson "0.0.3"
+ parseqs "0.0.5"
+ parseuri "0.0.5"
+ ws "1.1.2"
+ xmlhttprequest-ssl "1.5.3"
+ yeast "0.1.2"
+
engine.io-parser@1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-1.3.1.tgz#9554f1ae33107d6fbd170ca5466d2f833f6a07cf"
@@ -2821,6 +2988,17 @@ engine.io-parser@1.3.1:
has-binary "0.1.6"
wtf-8 "1.0.0"
+engine.io-parser@1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-1.3.2.tgz#937b079f0007d0893ec56d46cb220b8cb435220a"
+ dependencies:
+ after "0.8.2"
+ arraybuffer.slice "0.0.6"
+ base64-arraybuffer "0.1.5"
+ blob "0.0.4"
+ has-binary "0.1.7"
+ wtf-8 "1.0.0"
+
engine.io@1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.0.tgz#3eeb5f264cb75dbbec1baaea26d61f5a4eace2aa"
@@ -2832,6 +3010,17 @@ engine.io@1.8.0:
engine.io-parser "1.3.1"
ws "1.1.1"
+engine.io@1.8.3:
+ version "1.8.3"
+ resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-1.8.3.tgz#8de7f97895d20d39b85f88eeee777b2bd42b13d4"
+ dependencies:
+ accepts "1.3.3"
+ base64id "1.0.0"
+ cookie "0.3.1"
+ debug "2.3.3"
+ engine.io-parser "1.3.2"
+ ws "1.1.2"
+
enhanced-resolve@^3.3.0:
version "3.4.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e"
@@ -2847,6 +3036,10 @@ ensnare@^1.0.0:
dependencies:
tape "^4.6.0"
+ent@~2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d"
+
entities@^1.1.1, "entities@~ 1.1.1", entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
@@ -3166,7 +3359,7 @@ eth-block-tracker@^1.0.7:
pify "^2.3.0"
tape "^4.6.3"
-eth-block-tracker@^2.0.1:
+eth-block-tracker@^2.0.1, eth-block-tracker@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/eth-block-tracker/-/eth-block-tracker-2.1.3.tgz#ef24ab415f18445bd5c0ef49b9ac248f847e34f9"
dependencies:
@@ -3198,7 +3391,15 @@ eth-hd-keyring@^1.1.1:
ethereumjs-wallet "^0.6.0"
events "^1.1.1"
-eth-json-rpc-middleware@^1.2.7:
+eth-json-rpc-filters@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/eth-json-rpc-filters/-/eth-json-rpc-filters-1.1.0.tgz#fb2cb1d45c825f40d92c29ece5ff91a296c8f9a1"
+ dependencies:
+ await-semaphore "^0.1.1"
+ eth-json-rpc-middleware "^1.0.0"
+ lodash.flatmap "^4.5.0"
+
+eth-json-rpc-middleware@^1.0.0, eth-json-rpc-middleware@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.2.7.tgz#7c36e0972945255bdb486f18df53d4314a1c048a"
dependencies:
@@ -3241,7 +3442,7 @@ eth-simple-keyring@^1.1.1:
ethereumjs-wallet "^0.6.0"
events "^1.1.1"
-eth-token-tracker@^1.1.2:
+eth-token-tracker@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/eth-token-tracker/-/eth-token-tracker-1.1.3.tgz#c9951a214a9a30bdfc251133d1ba920743a59848"
dependencies:
@@ -3523,12 +3724,27 @@ execall@^1.0.0:
dependencies:
clone-regexp "^1.0.0"
+expand-braces@^0.1.1:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea"
+ dependencies:
+ array-slice "^0.2.3"
+ array-unique "^0.2.1"
+ braces "^0.1.2"
+
expand-brackets@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
dependencies:
is-posix-bracket "^0.1.0"
+expand-range@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-0.1.1.tgz#4cb8eda0993ca56fa4f41fc42f3cbb4ccadff044"
+ dependencies:
+ is-number "^0.1.1"
+ repeat-string "^0.2.2"
+
expand-range@^1.8.1:
version "1.8.2"
resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
@@ -3656,6 +3872,12 @@ fast-deep-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
+fast-json-patch@^2.0.4:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-2.0.5.tgz#a712e829be69ab707514440c5404bdd9b0d3c609"
+ dependencies:
+ deep-equal "^1.0.1"
+
fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
@@ -3719,7 +3941,7 @@ fill-range@^2.1.0:
repeat-element "^1.1.2"
repeat-string "^1.5.2"
-finalhandler@~1.0.4:
+finalhandler@1.0.4, finalhandler@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.4.tgz#18574f2e7c4b98b8ae3b230c21f201f31bdb3fb7"
dependencies:
@@ -3884,7 +4106,7 @@ form-data@~2.1.1:
combined-stream "^1.0.5"
mime-types "^2.1.12"
-formatio@1.2.0:
+formatio@1.2.0, formatio@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb"
dependencies:
@@ -3909,6 +4131,12 @@ from@~0:
version "0.1.7"
resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
+fs-access@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/fs-access/-/fs-access-1.0.1.tgz#d6a87f262271cefebec30c553407fb995da8777a"
+ dependencies:
+ null-check "^1.0.0"
+
fs-exists-sync@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add"
@@ -4128,7 +4356,7 @@ glob@^5.0.15, glob@^5.0.3, glob@~5.0.0:
once "^1.3.0"
path-is-absolute "^1.0.0"
-glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.2, glob@~7.1.1, glob@~7.1.2:
+glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.0.6, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1, glob@~7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
dependencies:
@@ -4162,6 +4390,10 @@ global@~4.3.0:
min-document "^2.19.0"
process "~0.5.1"
+globals@^10.0.0:
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-10.1.0.tgz#4425a1881be0d336b4a823a82a7be725d5dd987c"
+
globals@^9.17.0, globals@^9.18.0:
version "9.18.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
@@ -4632,14 +4864,7 @@ htmlparser2@^3.9.1:
inherits "^2.0.1"
readable-stream "^2.0.2"
-http-errors@~1.3.1:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942"
- dependencies:
- inherits "~2.0.1"
- statuses "1"
-
-http-errors@~1.6.2:
+http-errors@1.6.2, http-errors@~1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736"
dependencies:
@@ -4648,11 +4873,18 @@ http-errors@~1.6.2:
setprototypeof "1.0.3"
statuses ">= 1.3.1 < 2"
+http-errors@~1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942"
+ dependencies:
+ inherits "~2.0.1"
+ statuses "1"
+
http-parser-js@>=0.4.0:
version "0.4.5"
resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.5.tgz#a3ecf39a667481a38ca60882ab57a2db578b9970"
-http-proxy@^1.13.1:
+http-proxy@^1.13.0, http-proxy@^1.13.1:
version "1.16.2"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742"
dependencies:
@@ -4687,7 +4919,7 @@ iconv-lite@0.4.13:
version "0.4.13"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
-iconv-lite@^0.4.17, iconv-lite@^0.4.5, iconv-lite@~0.4.13:
+iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@^0.4.5, iconv-lite@~0.4.13:
version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
@@ -4820,7 +5052,7 @@ interpret@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90"
-invariant@^2.0.0, invariant@^2.2.2:
+invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
dependencies:
@@ -4948,6 +5180,10 @@ is-my-json-valid@^2.12.4:
jsonpointer "^4.0.0"
xtend "^4.0.0"
+is-number@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806"
+
is-number@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
@@ -5072,6 +5308,10 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+isbinaryfile@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621"
+
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -5206,6 +5446,10 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
+js-yaml@0.3.x:
+ version "0.3.7"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-0.3.7.tgz#d739d8ee86461e54b354d6a7d7d1f2ad9a167f62"
+
js-yaml@3.6.1:
version "3.6.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30"
@@ -5277,11 +5521,15 @@ jshint-stylish@~2.2.1:
string-length "^1.0.0"
text-table "^0.2.0"
+jsmin@1.x:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/jsmin/-/jsmin-1.0.1.tgz#e7bd0dcd6496c3bf4863235bf461a3d98aa3b98c"
+
json-loader@^0.5.4:
version "0.5.7"
resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d"
-json-rpc-engine@^3.0.1:
+json-rpc-engine@^3.0.1, json-rpc-engine@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-3.1.0.tgz#09285363372857569d75f61df6591b1b0afb0758"
dependencies:
@@ -5295,6 +5543,15 @@ json-rpc-error@^2.0.0:
dependencies:
inherits "^2.0.1"
+json-rpc-middleware-stream@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/json-rpc-middleware-stream/-/json-rpc-middleware-stream-1.0.0.tgz#84d0faefe123ce9cfc7a9753e6e5236b9a104522"
+ dependencies:
+ eth-block-tracker "^2.1.2"
+ ethjs-query "^0.2.9"
+ json-rpc-engine "^3.0.1"
+ readable-stream "^2.3.3"
+
json-rpc-random-id@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8"
@@ -5379,6 +5636,72 @@ jstransform@^10.1.0:
esprima-fb "13001.1001.0-dev-harmony-fb"
source-map "0.1.31"
+just-extend@^1.1.22:
+ version "1.1.22"
+ resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.22.tgz#3330af756cab6a542700c64b2e4e4aa062d52fff"
+
+jxLoader@*:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/jxLoader/-/jxLoader-0.1.1.tgz#0134ea5144e533b594fc1ff25ff194e235c53ecd"
+ dependencies:
+ js-yaml "0.3.x"
+ moo-server "1.3.x"
+ promised-io "*"
+ walker "1.x"
+
+karma-chrome-launcher@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz#cf1b9d07136cc18fe239327d24654c3dbc368acf"
+ dependencies:
+ fs-access "^1.0.0"
+ which "^1.2.1"
+
+karma-cli@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/karma-cli/-/karma-cli-1.0.1.tgz#ae6c3c58a313a1d00b45164c455b9b86ce17f960"
+ dependencies:
+ resolve "^1.1.6"
+
+karma-firefox-launcher@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/karma-firefox-launcher/-/karma-firefox-launcher-1.0.1.tgz#ce58f47c2013a88156d55a5d61337c099cf5bb51"
+
+karma-qunit@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/karma-qunit/-/karma-qunit-1.2.1.tgz#88252afd2127bc03b0cc31978ed6882b139f470a"
+
+karma@^1.7.1:
+ version "1.7.1"
+ resolved "https://registry.yarnpkg.com/karma/-/karma-1.7.1.tgz#85cc08e9e0a22d7ce9cca37c4a1be824f6a2b1ae"
+ dependencies:
+ bluebird "^3.3.0"
+ body-parser "^1.16.1"
+ chokidar "^1.4.1"
+ colors "^1.1.0"
+ combine-lists "^1.0.0"
+ connect "^3.6.0"
+ core-js "^2.2.0"
+ di "^0.0.1"
+ dom-serialize "^2.2.0"
+ expand-braces "^0.1.1"
+ glob "^7.1.1"
+ graceful-fs "^4.1.2"
+ http-proxy "^1.13.0"
+ isbinaryfile "^3.0.0"
+ lodash "^3.8.0"
+ log4js "^0.6.31"
+ mime "^1.3.4"
+ minimatch "^3.0.2"
+ optimist "^0.6.1"
+ qjobs "^1.1.4"
+ range-parser "^1.2.0"
+ rimraf "^2.6.0"
+ safe-buffer "^5.0.1"
+ socket.io "1.7.3"
+ source-map "^0.5.3"
+ tmp "0.0.31"
+ useragent "^2.1.12"
+
keccak@^1.0.2:
version "1.3.0"
resolved "https://registry.yarnpkg.com/keccak/-/keccak-1.3.0.tgz#3681bd99ad3d0354ddb29b9040c1b6560cce08ac"
@@ -5712,6 +6035,10 @@ lodash.find@^4.5.1:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1"
+lodash.flatmap@^4.5.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.flatmap/-/lodash.flatmap-4.5.0.tgz#ef8cbf408f6e48268663345305c6acc0b778702e"
+
lodash.flatten@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-3.0.2.tgz#de1cf57758f8f4479319d35c3e9cc60c4501938c"
@@ -5727,6 +6054,10 @@ lodash.foreach@^4.3.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
+lodash.get@^4.4.2:
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
+
lodash.isarguments@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
@@ -5828,7 +6159,11 @@ lodash.uniqby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302"
-lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.2, lodash@~4.17.4:
+lodash@^3.8.0:
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
+
+lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@~4.17.2, lodash@~4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
@@ -5848,6 +6183,13 @@ log-symbols@^2.0.0:
dependencies:
chalk "^2.0.1"
+log4js@^0.6.31:
+ version "0.6.38"
+ resolved "https://registry.yarnpkg.com/log4js/-/log4js-0.6.38.tgz#2c494116695d6fb25480943d3fc872e662a522fd"
+ dependencies:
+ readable-stream "~1.0.2"
+ semver "~4.3.3"
+
loglevel@^1.4.1:
version "1.5.0"
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.5.0.tgz#3863984a2c326b986fbb965f378758a6dc8a4324"
@@ -5856,6 +6198,10 @@ lolex@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6"
+lolex@^2.1.2:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.1.2.tgz#2694b953c9ea4d013e5b8bfba891c991025b2629"
+
longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
@@ -5873,6 +6219,10 @@ loud-rejection@^1.0.0:
currently-unhandled "^0.4.1"
signal-exit "^3.0.0"
+lru-cache@2.2.x:
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.2.4.tgz#6c658619becf14031d0d0b594b16042ce4dc063d"
+
lru-cache@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee"
@@ -5902,6 +6252,12 @@ make-iterator@^1.0.0:
dependencies:
kind-of "^3.1.0"
+makeerror@1.0.x:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
+ dependencies:
+ tmpl "1.0.x"
+
map-async@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/map-async/-/map-async-0.1.1.tgz#c897c0449f85864c74b5a3f196edb42156431745"
@@ -6094,6 +6450,10 @@ mime@1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53"
+mime@^1.3.4:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.0.tgz#69e9e0db51d44f2a3b56e48b7817d7d137f1a343"
+
mime@~1.2.9:
version "1.2.11"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10"
@@ -6232,6 +6592,10 @@ module-deps@^4.0.8:
through2 "^2.0.0"
xtend "^4.0.0"
+moo-server@*, moo-server@1.3.x:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/moo-server/-/moo-server-1.3.0.tgz#5dc79569565a10d6efed5439491e69d2392e58f1"
+
ms@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
@@ -6313,6 +6677,16 @@ next-tick@1:
version "1.0.0"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
+nise@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/nise/-/nise-1.1.0.tgz#37e41b9bf0041ccb83d1bf03e79440bbc0db10ad"
+ dependencies:
+ formatio "^1.2.0"
+ just-extend "^1.1.22"
+ lolex "^1.6.0"
+ path-to-regexp "^1.7.0"
+ text-encoding "^0.6.4"
+
nock@^9.0.14:
version "9.0.14"
resolved "https://registry.yarnpkg.com/nock/-/nock-9.0.14.tgz#2211550253173ce298bcd89fca825e83813ca72b"
@@ -6498,6 +6872,10 @@ nth-check@~1.0.1:
dependencies:
boolbase "~1.0.0"
+null-check@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd"
+
num2fraction@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
@@ -6553,6 +6931,14 @@ oauth-sign@~0.8.1:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
+obj-multiplex@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/obj-multiplex/-/obj-multiplex-1.0.0.tgz#2f2ae6bfd4ae11befe742ea9ea5b36636eabffc1"
+ dependencies:
+ end-of-stream "^1.4.0"
+ once "^1.4.0"
+ readable-stream "^2.3.3"
+
object-assign@3.0.0, object-assign@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2"
@@ -6743,7 +7129,7 @@ os-locale@^2.0.0:
lcid "^1.0.0"
mem "^1.1.0"
-os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1:
+os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
@@ -7234,6 +7620,10 @@ promise@^8.0.1:
dependencies:
asap "~2.0.3"
+promised-io@*:
+ version "0.3.5"
+ resolved "https://registry.yarnpkg.com/promised-io/-/promised-io-0.3.5.tgz#4ad217bb3658bcaae9946b17a8668ecd851e1356"
+
prompt@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.0.0.tgz#8e57123c396ab988897fb327fd3aedc3e735e4fe"
@@ -7320,6 +7710,10 @@ q@^1.1.2:
version "1.5.0"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1"
+qjobs@^1.1.4:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.1.5.tgz#659de9f2cf8dcc27a1481276f205377272382e73"
+
qrcode-npm@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/qrcode-npm/-/qrcode-npm-0.0.3.tgz#77ee6fbefa9c0f29fa09d4d1520807c6a6042b9a"
@@ -7332,7 +7726,7 @@ qs@6.5.0:
version "6.5.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.0.tgz#8d04954d364def3efc55b5a0793e1e2c8b1e6e49"
-qs@^6.0.2, qs@^6.2.0:
+qs@6.5.1, qs@^6.0.2, qs@^6.2.0:
version "6.5.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
@@ -7405,7 +7799,7 @@ randombytes@^2.0.0, randombytes@^2.0.1:
dependencies:
safe-buffer "^5.1.0"
-range-parser@~1.2.0:
+range-parser@^1.2.0, range-parser@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
@@ -7415,6 +7809,15 @@ raphael@^2.2.0:
dependencies:
eve-raphael "0.5.0"
+raw-body@2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"
+ dependencies:
+ bytes "3.0.0"
+ http-errors "1.6.2"
+ iconv-lite "0.4.19"
+ unpipe "1.0.0"
+
raw-body@~2.1.5:
version "2.1.7"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774"
@@ -7629,7 +8032,7 @@ read@1.0.x:
isarray "0.0.1"
string_decoder "~0.10.x"
-readable-stream@^2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.2, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9:
+readable-stream@^2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9, readable-stream@^2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
dependencies:
@@ -7760,6 +8163,10 @@ repeat-element@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
+repeat-string@^0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae"
+
repeat-string@^1.5.2:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
@@ -7954,7 +8361,7 @@ right-align@^0.1.1:
dependencies:
align-text "^0.1.1"
-rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.4.4, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1:
+rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.4.4, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
dependencies:
@@ -8082,6 +8489,10 @@ semver-greatest-satisfied-range@^1.0.0:
version "5.4.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
+semver@~4.3.3:
+ version "4.3.6"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da"
+
semver@~5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
@@ -8191,14 +8602,17 @@ simple-get@^1.4.2:
unzip-response "^1.0.0"
xtend "^4.0.0"
-sinon@^2.3.8:
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.4.1.tgz#021fd64b54cb77d9d2fb0d43cdedfae7629c3a36"
+sinon@^3.2.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/sinon/-/sinon-3.3.0.tgz#9132111b4bbe13c749c2848210864250165069b1"
dependencies:
+ build "^0.1.4"
diff "^3.1.0"
formatio "1.2.0"
- lolex "^1.6.0"
+ lodash.get "^4.4.2"
+ lolex "^2.1.2"
native-promise-only "^0.8.1"
+ nise "^1.0.1"
path-to-regexp "^1.7.0"
samsam "^1.1.3"
text-encoding "0.6.4"
@@ -8249,6 +8663,22 @@ socket.io-client@1.6.0:
socket.io-parser "2.3.1"
to-array "0.1.4"
+socket.io-client@1.7.3:
+ version "1.7.3"
+ resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-1.7.3.tgz#b30e86aa10d5ef3546601c09cde4765e381da377"
+ dependencies:
+ backo2 "1.0.2"
+ component-bind "1.0.0"
+ component-emitter "1.2.1"
+ debug "2.3.3"
+ engine.io-client "1.8.3"
+ has-binary "0.1.7"
+ indexof "0.0.1"
+ object-component "0.0.3"
+ parseuri "0.0.5"
+ socket.io-parser "2.3.1"
+ to-array "0.1.4"
+
socket.io-parser@2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-2.3.1.tgz#dd532025103ce429697326befd64005fcfe5b4a0"
@@ -8270,6 +8700,18 @@ socket.io@1.6.0:
socket.io-client "1.6.0"
socket.io-parser "2.3.1"
+socket.io@1.7.3:
+ version "1.7.3"
+ resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-1.7.3.tgz#b8af9caba00949e568e369f1327ea9be9ea2461b"
+ dependencies:
+ debug "2.3.3"
+ engine.io "1.8.3"
+ has-binary "0.1.7"
+ object-assign "4.1.0"
+ socket.io-adapter "0.5.0"
+ socket.io-client "1.7.3"
+ socket.io-parser "2.3.1"
+
solc@^0.4.2:
version "0.4.16"
resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.16.tgz#809a5b1257c7c200e11a841b377eaec274698539"
@@ -8989,7 +9431,7 @@ testem@^1.10.3:
tap-parser "^5.1.0"
xmldom "^0.1.19"
-text-encoding@0.6.4:
+text-encoding@0.6.4, text-encoding@^0.6.4:
version "0.6.4"
resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19"
@@ -9096,12 +9538,26 @@ timers-ext@^0.1.2:
es5-ext "~0.10.14"
next-tick "1"
-tmp@^0.0.31:
+timespan@2.x:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/timespan/-/timespan-2.3.0.tgz#4902ce040bd13d845c8f59b27e9d59bad6f39929"
+
+tmp@0.0.31, tmp@^0.0.31:
version "0.0.31"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7"
dependencies:
os-tmpdir "~1.0.1"
+tmp@0.0.x:
+ version "0.0.33"
+ resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
+ dependencies:
+ os-tmpdir "~1.0.2"
+
+tmpl@1.0.x:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
+
to-absolute-glob@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f"
@@ -9120,6 +9576,10 @@ to-fast-properties@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
+to-fast-properties@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
+
to-utf8@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/to-utf8/-/to-utf8-0.0.1.tgz#d17aea72ff2fba39b9e43601be7b3ff72e089852"
@@ -9233,6 +9693,10 @@ uglify-es@^3.0.15:
commander "~2.11.0"
source-map "~0.5.1"
+uglify-js@1.x:
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-1.3.5.tgz#4b5bfff9186effbaa888e4c9e94bd9fc4c94929d"
+
uglify-js@^2.6, uglify-js@^2.8.27:
version "2.8.29"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
@@ -9332,6 +9796,13 @@ user-home@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190"
+useragent@^2.1.12:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.2.1.tgz#cf593ef4f2d175875e8bb658ea92e18a4fd06d8e"
+ dependencies:
+ lru-cache "2.2.x"
+ tmp "0.0.x"
+
utf8@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96"
@@ -9488,10 +9959,20 @@ vm-browserify@0.0.4, vm-browserify@~0.0.1:
dependencies:
indexof "0.0.1"
+void-elements@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
+
vreme@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/vreme/-/vreme-3.0.2.tgz#4721376b449457fefde8a849d3340933b90b5686"
+walker@1.x:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
+ dependencies:
+ makeerror "1.0.x"
+
warning@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
@@ -9649,7 +10130,7 @@ which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
-which@1, which@^1.0.5, which@^1.1.1, which@^1.2.12, which@^1.2.4, which@^1.2.9:
+which@1, which@^1.0.5, which@^1.1.1, which@^1.2.1, which@^1.2.12, which@^1.2.4, which@^1.2.9:
version "1.3.0"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
dependencies:
@@ -9677,6 +10158,17 @@ window-size@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075"
+winston@*:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/winston/-/winston-2.3.1.tgz#0b48420d978c01804cf0230b648861598225a119"
+ dependencies:
+ async "~1.0.0"
+ colors "1.0.x"
+ cycle "1.0.x"
+ eyes "0.1.x"
+ isstream "0.1.x"
+ stack-trace "0.0.x"
+
winston@2.1.x:
version "2.1.1"
resolved "https://registry.yarnpkg.com/winston/-/winston-2.1.1.tgz#3c9349d196207fd1bdff9d4bc43ef72510e3a12e"
@@ -9719,6 +10211,10 @@ wreck@^6.3.0:
boom "2.x.x"
hoek "2.x.x"
+wrench@1.3.x:
+ version "1.3.9"
+ resolved "https://registry.yarnpkg.com/wrench/-/wrench-1.3.9.tgz#6f13ec35145317eb292ca5f6531391b244111411"
+
write-file-atomic@^1.1.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f"
@@ -9744,6 +10240,13 @@ ws@1.1.1:
options ">=0.0.5"
ultron "1.0.x"
+ws@1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.2.tgz#8a244fa052401e08c9886cf44a85189e1fd4067f"
+ dependencies:
+ options ">=0.0.5"
+ ultron "1.0.x"
+
wtf-8@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a"