aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkumavis <kumavis@users.noreply.github.com>2017-02-03 16:17:17 +0800
committerGitHub <noreply@github.com>2017-02-03 16:17:17 +0800
commit66be5ff2756e611c7af6973e704d27ce9bbd0d45 (patch)
tree43b5dcab6686e3db06218bfff17a943c72e6ddf3
parent270808c206934cf7d75fefcdd092c9595de45f29 (diff)
parent970d4fd69519bab1de972839190a4ede888914bb (diff)
downloadtangerine-wallet-browser-66be5ff2756e611c7af6973e704d27ce9bbd0d45.tar
tangerine-wallet-browser-66be5ff2756e611c7af6973e704d27ce9bbd0d45.tar.gz
tangerine-wallet-browser-66be5ff2756e611c7af6973e704d27ce9bbd0d45.tar.bz2
tangerine-wallet-browser-66be5ff2756e611c7af6973e704d27ce9bbd0d45.tar.lz
tangerine-wallet-browser-66be5ff2756e611c7af6973e704d27ce9bbd0d45.tar.xz
tangerine-wallet-browser-66be5ff2756e611c7af6973e704d27ce9bbd0d45.tar.zst
tangerine-wallet-browser-66be5ff2756e611c7af6973e704d27ce9bbd0d45.zip
Merge pull request #1083 from MetaMask/kumavis-refactor6
Refactor round 6
-rw-r--r--app/scripts/keyring-controller.js39
-rw-r--r--app/scripts/lib/config-manager.js47
-rw-r--r--app/scripts/lib/controllers/currency.js70
-rw-r--r--app/scripts/lib/eth-store.js214
-rw-r--r--app/scripts/lib/idStore.js3
-rw-r--r--app/scripts/lib/message-manager.js52
-rw-r--r--app/scripts/metamask-controller.js168
-rw-r--r--app/scripts/migrations/007.js38
-rw-r--r--app/scripts/migrations/008.js36
-rw-r--r--app/scripts/migrations/009.js40
-rw-r--r--app/scripts/migrations/index.js3
-rw-r--r--app/scripts/notice-controller.js50
-rw-r--r--app/scripts/transaction-manager.js65
-rw-r--r--package.json7
-rw-r--r--test/integration/index.html2
-rw-r--r--test/unit/config-manager-test.js75
-rw-r--r--test/unit/currency-controller-test.js87
-rw-r--r--test/unit/message-manager-test.js17
-rw-r--r--test/unit/tx-manager-test.js122
-rw-r--r--ui/app/actions.js77
20 files changed, 696 insertions, 516 deletions
diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js
index d1d706165..348f81fc9 100644
--- a/app/scripts/keyring-controller.js
+++ b/app/scripts/keyring-controller.js
@@ -29,11 +29,11 @@ class KeyringController extends EventEmitter {
this.keyringTypes = keyringTypes
this.store = new ObservableStore(initState)
this.memStore = new ObservableStore({
+ isUnlocked: false,
keyringTypes: this.keyringTypes.map(krt => krt.type),
keyrings: [],
identities: {},
})
- this.configManager = opts.configManager
this.ethStore = opts.ethStore
this.encryptor = encryptor
this.keyrings = []
@@ -53,37 +53,7 @@ class KeyringController extends EventEmitter {
// Not all methods end with this, that might be a nice refactor.
fullUpdate () {
this.emit('update')
- return Promise.resolve(this.getState())
- }
-
- // Get State
- // returns @object state
- //
- // This method returns a hash representing the current state
- // that the keyringController manages.
- //
- // It is extended in the MetamaskController along with the EthStore
- // state, and its own state, to create the metamask state branch
- // that is passed to the UI.
- //
- // This is currently a rare example of a synchronously resolving method
- // in this class, but will need to be Promisified when we move our
- // persistence to an async model.
- getState () {
-
- // old wallet
- const memState = this.memStore.getState()
- const result = {
- // computed
- isUnlocked: (!!this.password),
- // memStore
- keyringTypes: memState.keyringTypes,
- identities: memState.identities,
- keyrings: memState.keyrings,
- // configManager
- seedWords: this.configManager.getSeedWords(),
- }
- return result
+ return Promise.resolve(this.memStore.getState())
}
// Create New Vault And Keychain
@@ -147,7 +117,10 @@ class KeyringController extends EventEmitter {
//
// This method deallocates all secrets, and effectively locks metamask.
setLocked () {
+ // set locked
this.password = null
+ this.memStore.updateState({ isUnlocked: false })
+ // remove keyrings
this.keyrings = []
this._updateMemStoreKeyrings()
return this.fullUpdate()
@@ -385,6 +358,7 @@ class KeyringController extends EventEmitter {
persistAllKeyrings (password = this.password) {
if (typeof password === 'string') {
this.password = password
+ this.memStore.updateState({ isUnlocked: true })
}
return Promise.all(this.keyrings.map((keyring) => {
return Promise.all([keyring.type, keyring.serialize()])
@@ -421,6 +395,7 @@ class KeyringController extends EventEmitter {
return this.encryptor.decrypt(password, encryptedVault)
.then((vault) => {
this.password = password
+ this.memStore.updateState({ isUnlocked: true })
vault.forEach(this.restoreKeyring.bind(this))
return this.keyrings
})
diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js
index 357e081b1..a9b86ca8c 100644
--- a/app/scripts/lib/config-manager.js
+++ b/app/scripts/lib/config-manager.js
@@ -250,53 +250,6 @@ ConfigManager.prototype.getTOSHash = function () {
return data.TOSHash
}
-ConfigManager.prototype.setCurrentFiat = function (currency) {
- var data = this.getData()
- data.fiatCurrency = currency
- this.setData(data)
-}
-
-ConfigManager.prototype.getCurrentFiat = function () {
- var data = this.getData()
- return data.fiatCurrency || 'USD'
-}
-
-ConfigManager.prototype.updateConversionRate = function () {
- var data = this.getData()
- return fetch(`https://www.cryptonator.com/api/ticker/eth-${data.fiatCurrency}`)
- .then(response => response.json())
- .then((parsedResponse) => {
- this.setConversionPrice(parsedResponse.ticker.price)
- this.setConversionDate(parsedResponse.timestamp)
- }).catch((err) => {
- console.warn('MetaMask - Failed to query currency conversion.')
- this.setConversionPrice(0)
- this.setConversionDate('N/A')
- })
-}
-
-ConfigManager.prototype.setConversionPrice = function (price) {
- var data = this.getData()
- data.conversionRate = Number(price)
- this.setData(data)
-}
-
-ConfigManager.prototype.setConversionDate = function (datestring) {
- var data = this.getData()
- data.conversionDate = datestring
- this.setData(data)
-}
-
-ConfigManager.prototype.getConversionRate = function () {
- var data = this.getData()
- return (data.conversionRate) || 0
-}
-
-ConfigManager.prototype.getConversionDate = function () {
- var data = this.getData()
- return (data.conversionDate) || 'N/A'
-}
-
ConfigManager.prototype.getShapeShiftTxList = function () {
var data = this.getData()
var shapeShiftTxList = data.shapeShiftTxList ? data.shapeShiftTxList : []
diff --git a/app/scripts/lib/controllers/currency.js b/app/scripts/lib/controllers/currency.js
new file mode 100644
index 000000000..c4904f8ac
--- /dev/null
+++ b/app/scripts/lib/controllers/currency.js
@@ -0,0 +1,70 @@
+const ObservableStore = require('obs-store')
+const extend = require('xtend')
+
+// every ten minutes
+const POLLING_INTERVAL = 600000
+
+class CurrencyController {
+
+ constructor (opts = {}) {
+ const initState = extend({
+ currentCurrency: 'USD',
+ conversionRate: 0,
+ conversionDate: 'N/A',
+ }, opts.initState)
+ this.store = new ObservableStore(initState)
+ }
+
+ //
+ // PUBLIC METHODS
+ //
+
+ getCurrentCurrency () {
+ return this.store.getState().currentCurrency
+ }
+
+ setCurrentCurrency (currentCurrency) {
+ this.store.updateState({ currentCurrency })
+ }
+
+ getConversionRate () {
+ return this.store.getState().conversionRate
+ }
+
+ setConversionRate (conversionRate) {
+ this.store.updateState({ conversionRate })
+ }
+
+ getConversionDate () {
+ return this.store.getState().conversionDate
+ }
+
+ setConversionDate (conversionDate) {
+ this.store.updateState({ conversionDate })
+ }
+
+ updateConversionRate () {
+ const currentCurrency = this.getCurrentCurrency()
+ return fetch(`https://www.cryptonator.com/api/ticker/eth-${currentCurrency}`)
+ .then(response => response.json())
+ .then((parsedResponse) => {
+ this.setConversionRate(Number(parsedResponse.ticker.price))
+ this.setConversionDate(Number(parsedResponse.timestamp))
+ }).catch((err) => {
+ console.warn('MetaMask - Failed to query currency conversion.')
+ this.setConversionRate(0)
+ this.setConversionDate('N/A')
+ })
+ }
+
+ scheduleConversionInterval () {
+ if (this.conversionInterval) {
+ clearInterval(this.conversionInterval)
+ }
+ this.conversionInterval = setInterval(() => {
+ this.updateConversionRate()
+ }, POLLING_INTERVAL)
+ }
+}
+
+module.exports = CurrencyController
diff --git a/app/scripts/lib/eth-store.js b/app/scripts/lib/eth-store.js
index 7e2caf884..96b4a60f2 100644
--- a/app/scripts/lib/eth-store.js
+++ b/app/scripts/lib/eth-store.js
@@ -7,140 +7,122 @@
* on each new block.
*/
-const EventEmitter = require('events').EventEmitter
-const inherits = require('util').inherits
const async = require('async')
-const clone = require('clone')
const EthQuery = require('eth-query')
+const ObservableStore = require('obs-store')
+function noop() {}
-module.exports = EthereumStore
+class EthereumStore extends ObservableStore {
-inherits(EthereumStore, EventEmitter)
-function EthereumStore(engine) {
- const self = this
- EventEmitter.call(self)
- self._currentState = {
- accounts: {},
- transactions: {},
+ constructor (opts = {}) {
+ super({
+ accounts: {},
+ transactions: {},
+ })
+ this._provider = opts.provider
+ this._query = new EthQuery(this._provider)
+ this._blockTracker = opts.blockTracker
+ // subscribe to latest block
+ this._blockTracker.on('block', this._updateForBlock.bind(this))
}
- self._query = new EthQuery(engine)
-
- engine.on('block', self._updateForBlock.bind(self))
-}
-
-//
-// public
-//
-EthereumStore.prototype.getState = function () {
- const self = this
- return clone(self._currentState)
-}
-
-EthereumStore.prototype.addAccount = function (address) {
- const self = this
- self._currentState.accounts[address] = {}
- self._didUpdate()
- if (!self.currentBlockNumber) return
- self._updateAccount(address, () => {
- self._didUpdate()
- })
-}
+ //
+ // public
+ //
-EthereumStore.prototype.removeAccount = function (address) {
- const self = this
- delete self._currentState.accounts[address]
- self._didUpdate()
-}
+ addAccount (address) {
+ const accounts = this.getState().accounts
+ accounts[address] = {}
+ this.updateState({ accounts })
+ if (!this._currentBlockNumber) return
+ this._updateAccount(address)
+ }
-EthereumStore.prototype.addTransaction = function (txHash) {
- const self = this
- self._currentState.transactions[txHash] = {}
- self._didUpdate()
- if (!self.currentBlockNumber) return
- self._updateTransaction(self.currentBlockNumber, txHash, noop)
-}
+ removeAccount (address) {
+ const accounts = this.getState().accounts
+ delete accounts[address]
+ this.updateState({ accounts })
+ }
-EthereumStore.prototype.removeTransaction = function (address) {
- const self = this
- delete self._currentState.transactions[address]
- self._didUpdate()
-}
+ addTransaction (txHash) {
+ const transactions = this.getState().transactions
+ transactions[txHash] = {}
+ this.updateState({ transactions })
+ if (!this._currentBlockNumber) return
+ this._updateTransaction(this._currentBlockNumber, txHash, noop)
+ }
+ removeTransaction (txHash) {
+ const transactions = this.getState().transactions
+ delete transactions[txHash]
+ this.updateState({ transactions })
+ }
-//
-// private
-//
-EthereumStore.prototype._didUpdate = function () {
- const self = this
- var state = self.getState()
- self.emit('update', state)
-}
+ //
+ // private
+ //
+
+ _updateForBlock (block) {
+ const blockNumber = '0x' + block.number.toString('hex')
+ this._currentBlockNumber = blockNumber
+ async.parallel([
+ this._updateAccounts.bind(this),
+ this._updateTransactions.bind(this, blockNumber),
+ ], (err) => {
+ if (err) return console.error(err)
+ this.emit('block', this.getState())
+ })
+ }
-EthereumStore.prototype._updateForBlock = function (block) {
- const self = this
- var blockNumber = '0x' + block.number.toString('hex')
- self.currentBlockNumber = blockNumber
- async.parallel([
- self._updateAccounts.bind(self),
- self._updateTransactions.bind(self, blockNumber),
- ], function (err) {
- if (err) return console.error(err)
- self.emit('block', self.getState())
- self._didUpdate()
- })
-}
+ _updateAccounts (cb = noop) {
+ const accounts = this.getState().accounts
+ const addresses = Object.keys(accounts)
+ async.each(addresses, this._updateAccount.bind(this), cb)
+ }
-EthereumStore.prototype._updateAccounts = function (cb) {
- var accountsState = this._currentState.accounts
- var addresses = Object.keys(accountsState)
- async.each(addresses, this._updateAccount.bind(this), cb)
-}
+ _updateAccount (address, cb = noop) {
+ const accounts = this.getState().accounts
+ this._getAccount(address, (err, result) => {
+ if (err) return cb(err)
+ result.address = address
+ // only populate if the entry is still present
+ if (accounts[address]) {
+ accounts[address] = result
+ }
+ cb(null, result)
+ })
+ }
-EthereumStore.prototype._updateAccount = function (address, cb) {
- var accountsState = this._currentState.accounts
- this.getAccount(address, function (err, result) {
- if (err) return cb(err)
- result.address = address
- // only populate if the entry is still present
- if (accountsState[address]) {
- accountsState[address] = result
- }
- cb(null, result)
- })
-}
+ _updateTransactions (block, cb = noop) {
+ const transactions = this.getState().transactions
+ const txHashes = Object.keys(transactions)
+ async.each(txHashes, this._updateTransaction.bind(this, block), cb)
+ }
-EthereumStore.prototype.getAccount = function (address, cb) {
- const query = this._query
- async.parallel({
- balance: query.getBalance.bind(query, address),
- nonce: query.getTransactionCount.bind(query, address),
- code: query.getCode.bind(query, address),
- }, cb)
-}
+ _updateTransaction (block, txHash, cb = noop) {
+ // would use the block here to determine how many confirmations the tx has
+ const transactions = this.getState().transactions
+ this._query.getTransaction(txHash, (err, result) => {
+ if (err) return cb(err)
+ // only populate if the entry is still present
+ if (transactions[txHash]) {
+ transactions[txHash] = result
+ }
+ cb(null, result)
+ })
+ }
-EthereumStore.prototype._updateTransactions = function (block, cb) {
- const self = this
- var transactionsState = self._currentState.transactions
- var txHashes = Object.keys(transactionsState)
- async.each(txHashes, self._updateTransaction.bind(self, block), cb)
-}
+ _getAccount (address, cb = noop) {
+ const query = this._query
+ async.parallel({
+ balance: query.getBalance.bind(query, address),
+ nonce: query.getTransactionCount.bind(query, address),
+ code: query.getCode.bind(query, address),
+ }, cb)
+ }
-EthereumStore.prototype._updateTransaction = function (block, txHash, cb) {
- const self = this
- // would use the block here to determine how many confirmations the tx has
- var transactionsState = self._currentState.transactions
- self._query.getTransaction(txHash, function (err, result) {
- if (err) return cb(err)
- // only populate if the entry is still present
- if (transactionsState[txHash]) {
- transactionsState[txHash] = result
- self._didUpdate()
- }
- cb(null, result)
- })
}
-function noop() {}
+module.exports = EthereumStore \ No newline at end of file
diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js
index e4cbca456..ac395440d 100644
--- a/app/scripts/lib/idStore.js
+++ b/app/scripts/lib/idStore.js
@@ -97,9 +97,6 @@ IdentityStore.prototype.getState = function () {
isDisclaimerConfirmed: configManager.getConfirmedDisclaimer(),
selectedAddress: configManager.getSelectedAccount(),
shapeShiftTxList: configManager.getShapeShiftTxList(),
- currentFiat: configManager.getCurrentFiat(),
- conversionRate: configManager.getConversionRate(),
- conversionDate: configManager.getConversionDate(),
gasMultiplier: configManager.getGasMultiplier(),
}))
}
diff --git a/app/scripts/lib/message-manager.js b/app/scripts/lib/message-manager.js
index 18bf54ae1..38fa42017 100644
--- a/app/scripts/lib/message-manager.js
+++ b/app/scripts/lib/message-manager.js
@@ -6,18 +6,11 @@ const createId = require('./random-id')
module.exports = class MessageManager extends EventEmitter{
constructor (opts) {
super()
- this.memStore = new ObservableStore({ messages: [] })
- }
-
- getState() {
- return {
- unapprovedMsgs: this.getUnapprovedMsgs(),
- messages: this.getMsgList(),
- }
- }
-
- getMsgList () {
- return this.memStore.getState().messages
+ this.memStore = new ObservableStore({
+ unapprovedMsgs: {},
+ unapprovedMsgCount: 0,
+ })
+ this.messages = []
}
get unapprovedMsgCount () {
@@ -25,8 +18,7 @@ module.exports = class MessageManager extends EventEmitter{
}
getUnapprovedMsgs () {
- let messages = this.getMsgList()
- return messages.filter(msg => msg.status === 'unapproved')
+ return this.messages.filter(msg => msg.status === 'unapproved')
.reduce((result, msg) => { result[msg.id] = msg; return result }, {})
}
@@ -41,10 +33,6 @@ module.exports = class MessageManager extends EventEmitter{
status: 'unapproved',
}
this.addMsg(msgData)
- console.log('addUnapprovedMessage:', msgData)
-
- // keep the cb around for after approval (requires user interaction)
- // This cb fires completion to the Dapp's write operation.
// signal update
this.emit('update')
@@ -52,15 +40,12 @@ module.exports = class MessageManager extends EventEmitter{
}
addMsg (msg) {
- let messages = this.getMsgList()
- messages.push(msg)
- this._saveMsgList(messages)
+ this.messages.push(msg)
+ this._saveMsgList()
}
getMsg (msgId) {
- let messages = this.getMsgList()
- let matching = messages.filter(msg => msg.id === msgId)
- return matching.length > 0 ? matching[0] : null
+ return this.messages.find(msg => msg.id === msgId)
}
approveMessage (msgParams) {
@@ -85,7 +70,10 @@ module.exports = class MessageManager extends EventEmitter{
brodcastMessage (rawSig, msgId, status) {
this.emit(`${msgId}:finished`, {status, rawSig})
}
-// PRIVATE METHODS
+
+ //
+ // PRIVATE METHODS
+ //
_setMsgStatus (msgId, status) {
let msg = this.getMsg(msgId)
@@ -94,18 +82,18 @@ module.exports = class MessageManager extends EventEmitter{
}
_updateMsg (msg) {
- let messages = this.getMsgList()
- let index = messages.findIndex((message) => message.id === msg.id)
+ let index = this.messages.findIndex((message) => message.id === msg.id)
if (index !== -1) {
- messages[index] = msg
+ this.messages[index] = msg
}
- this._saveMsgList(messages)
+ this._saveMsgList()
}
- _saveMsgList (msgList) {
+ _saveMsgList () {
+ const unapprovedMsgs = this.getUnapprovedMsgs()
+ const unapprovedMsgCount = Object.keys(unapprovedMsgs).length
+ this.memStore.updateState({ unapprovedMsgs, unapprovedMsgCount })
this.emit('updateBadge')
- this.memStore.updateState({ messages: msgList })
}
-
}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index a56203a88..c0910014f 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -12,6 +12,7 @@ const MetaMaskProvider = require('web3-provider-engine/zero.js')
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
const KeyringController = require('./keyring-controller')
const PreferencesController = require('./lib/controllers/preferences')
+const CurrencyController = require('./lib/controllers/currency')
const NoticeController = require('./notice-controller')
const MessageManager = require('./lib/message-manager')
const TxManager = require('./transaction-manager')
@@ -29,38 +30,48 @@ module.exports = class MetamaskController extends EventEmitter {
constructor (opts) {
super()
this.opts = opts
- this.state = { network: 'loading' }
let initState = opts.initState || {}
// observable state store
this.store = new ObservableStore(initState)
+ // network store
+ this.networkStore = new ObservableStore({ network: 'loading' })
+
// config manager
this.configManager = new ConfigManager({
store: this.store,
})
- this.configManager.updateConversionRate()
// preferences controller
this.preferencesController = new PreferencesController({
initState: initState.PreferencesController,
})
+ // currency controller
+ this.currencyController = new CurrencyController({
+ initState: initState.CurrencyController,
+ })
+ this.currencyController.updateConversionRate()
+ this.currencyController.scheduleConversionInterval()
+
// rpc provider
this.provider = this.initializeProvider(opts)
this.provider.on('block', this.logBlock.bind(this))
- this.provider.on('error', this.getNetwork.bind(this))
+ this.provider.on('error', this.verifyNetwork.bind(this))
// eth data query tools
this.ethQuery = new EthQuery(this.provider)
- this.ethStore = new EthStore(this.provider)
+ this.ethStore = new EthStore({
+ provider: this.provider,
+ blockTracker: this.provider,
+ })
// key mgmt
this.keyringController = new KeyringController({
initState: initState.KeyringController,
ethStore: this.ethStore,
- configManager: this.configManager,
- getNetwork: this.getStateNetwork.bind(this),
+ getNetwork: this.getNetworkState.bind(this),
})
this.keyringController.on('newAccount', (address) => {
this.preferencesController.setSelectedAddress(address)
@@ -69,12 +80,11 @@ module.exports = class MetamaskController extends EventEmitter {
// tx mgmt
this.txManager = new TxManager({
- txList: this.configManager.getTxList(),
+ initState: initState.TransactionManager,
+ networkStore: this.networkStore,
+ preferencesStore: this.preferencesController.store,
txHistoryLimit: 40,
- setTxList: this.configManager.setTxList.bind(this.configManager),
- getSelectedAddress: this.preferencesController.getSelectedAddress.bind(this.preferencesController),
- getGasMultiplier: this.configManager.getGasMultiplier.bind(this.configManager),
- getNetwork: this.getStateNetwork.bind(this),
+ getNetwork: this.getNetworkState.bind(this),
signTransaction: this.keyringController.signTransaction.bind(this.keyringController),
provider: this.provider,
blockTracker: this.provider,
@@ -82,36 +92,49 @@ module.exports = class MetamaskController extends EventEmitter {
// notices
this.noticeController = new NoticeController({
- configManager: this.configManager,
+ initState: initState.NoticeController,
})
this.noticeController.updateNoticesList()
// to be uncommented when retrieving notices from a remote server.
// this.noticeController.startPolling()
- this.getNetwork()
+ this.lookupNetwork()
this.messageManager = new MessageManager()
this.publicConfigStore = this.initPublicConfigStore()
this.checkTOSChange()
- this.scheduleConversionInterval()
-
// TEMPORARY UNTIL FULL DEPRECATION:
this.idStoreMigrator = new IdStoreMigrator({
configManager: this.configManager,
})
- // manual state subscriptions
- this.ethStore.on('update', this.sendUpdate.bind(this))
- this.keyringController.on('update', this.sendUpdate.bind(this))
- this.txManager.on('update', this.sendUpdate.bind(this))
- this.messageManager.on('update', this.sendUpdate.bind(this))
+ // manual disk state subscriptions
+ this.txManager.store.subscribe((state) => {
+ this.store.updateState({ TransactionManager: state })
+ })
this.keyringController.store.subscribe((state) => {
this.store.updateState({ KeyringController: state })
})
this.preferencesController.store.subscribe((state) => {
this.store.updateState({ PreferencesController: state })
})
+ this.currencyController.store.subscribe((state) => {
+ this.store.updateState({ CurrencyController: state })
+ })
+ this.noticeController.store.subscribe((state) => {
+ this.store.updateState({ NoticeController: state })
+ })
+
+ // manual mem state subscriptions
+ this.networkStore.subscribe(this.sendUpdate.bind(this))
+ this.ethStore.subscribe(this.sendUpdate.bind(this))
+ this.txManager.memStore.subscribe(this.sendUpdate.bind(this))
+ this.messageManager.memStore.subscribe(this.sendUpdate.bind(this))
+ this.keyringController.memStore.subscribe(this.sendUpdate.bind(this))
+ this.preferencesController.store.subscribe(this.sendUpdate.bind(this))
+ this.currencyController.store.subscribe(this.sendUpdate.bind(this))
+ this.noticeController.memStore.subscribe(this.sendUpdate.bind(this))
}
//
@@ -174,22 +197,21 @@ module.exports = class MetamaskController extends EventEmitter {
{
isInitialized,
},
- this.state,
+ this.networkStore.getState(),
this.ethStore.getState(),
- this.txManager.getState(),
- this.messageManager.getState(),
- this.keyringController.getState(),
+ this.txManager.memStore.getState(),
+ this.messageManager.memStore.getState(),
+ this.keyringController.memStore.getState(),
this.preferencesController.store.getState(),
- this.noticeController.getState(),
+ this.currencyController.store.getState(),
+ this.noticeController.memStore.getState(),
// config manager
this.configManager.getConfig(),
{
shapeShiftTxList: this.configManager.getShapeShiftTxList(),
lostAccounts: this.configManager.getLostAccounts(),
- currentFiat: this.configManager.getCurrentFiat(),
- conversionRate: this.configManager.getConversionRate(),
- conversionDate: this.configManager.getConversionDate(),
isDisclaimerConfirmed: this.configManager.getConfirmedDisclaimer(),
+ seedWords: this.configManager.getSeedWords(),
}
)
}
@@ -213,7 +235,7 @@ module.exports = class MetamaskController extends EventEmitter {
useEtherscanProvider: this.useEtherscanProvider.bind(this),
agreeToDisclaimer: this.agreeToDisclaimer.bind(this),
resetDisclaimer: this.resetDisclaimer.bind(this),
- setCurrentFiat: this.setCurrentFiat.bind(this),
+ setCurrentCurrency: this.setCurrentCurrency.bind(this),
setTOSHash: this.setTOSHash.bind(this),
checkTOSChange: this.checkTOSChange.bind(this),
setGasMultiplier: this.setGasMultiplier.bind(this),
@@ -243,11 +265,13 @@ module.exports = class MetamaskController extends EventEmitter {
saveAccountLabel: nodeify(keyringController.saveAccountLabel).bind(keyringController),
exportAccount: nodeify(keyringController.exportAccount).bind(keyringController),
- // signing methods
+ // txManager
approveTransaction: txManager.approveTransaction.bind(txManager),
cancelTransaction: txManager.cancelTransaction.bind(txManager),
- signMessage: this.signMessage.bind(this),
- cancelMessage: messageManager.rejectMsg.bind(messageManager),
+
+ // messageManager
+ signMessage: this.signMessage.bind(this),
+ cancelMessage: messageManager.rejectMsg.bind(messageManager),
// notices
checkNotices: noticeController.updateNoticesList.bind(noticeController),
@@ -339,7 +363,7 @@ module.exports = class MetamaskController extends EventEmitter {
.then((serialized) => {
const seedWords = serialized.mnemonic
this.configManager.setSeedWords(seedWords)
- promiseToCallback(this.keyringController.fullUpdate())(cb)
+ cb()
})
}
@@ -538,44 +562,38 @@ module.exports = class MetamaskController extends EventEmitter {
this.verifyNetwork()
}
- setCurrentFiat (fiat, cb) {
+ setCurrentCurrency (currencyCode, cb) {
try {
- this.configManager.setCurrentFiat(fiat)
- this.configManager.updateConversionRate()
- this.scheduleConversionInterval()
+ this.currencyController.setCurrentCurrency(currencyCode)
+ this.currencyController.updateConversionRate()
const data = {
- conversionRate: this.configManager.getConversionRate(),
- currentFiat: this.configManager.getCurrentFiat(),
- conversionDate: this.configManager.getConversionDate(),
+ conversionRate: this.currencyController.getConversionRate(),
+ currentFiat: this.currencyController.getCurrentCurrency(),
+ conversionDate: this.currencyController.getConversionDate(),
}
- cb(data)
+ cb(null, data)
} catch (err) {
- cb(null, err)
- }
- }
-
- scheduleConversionInterval () {
- if (this.conversionInterval) {
- clearInterval(this.conversionInterval)
+ cb(err)
}
- this.conversionInterval = setInterval(() => {
- this.configManager.updateConversionRate()
- }, 300000)
}
buyEth (address, amount) {
if (!amount) amount = '5'
- var network = this.state.network
- var url = `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`
+ const network = this.getNetworkState()
+ let url
+
+ switch (network) {
+ case '1':
+ url = `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`
+ break
- if (network === '3') {
- url = 'https://faucet.metamask.io/'
+ case '3':
+ url = 'https://faucet.metamask.io/'
+ break
}
- extension.tabs.create({
- url,
- })
+ if (url) extension.tabs.create({ url })
}
createShapeShiftTx (depositAddress, depositType) {
@@ -584,7 +602,7 @@ module.exports = class MetamaskController extends EventEmitter {
setGasMultiplier (gasMultiplier, cb) {
try {
- this.configManager.setGasMultiplier(gasMultiplier)
+ this.txManager.setGasMultiplier(gasMultiplier)
cb()
} catch (err) {
cb(err)
@@ -597,21 +615,19 @@ module.exports = class MetamaskController extends EventEmitter {
verifyNetwork () {
// Check network when restoring connectivity:
- if (this.state.network === 'loading') {
- this.getNetwork()
- }
+ if (this.isNetworkLoading()) this.lookupNetwork()
}
setRpcTarget (rpcTarget) {
this.configManager.setRpcTarget(rpcTarget)
extension.runtime.reload()
- this.getNetwork()
+ this.lookupNetwork()
}
setProviderType (type) {
this.configManager.setProviderType(type)
extension.runtime.reload()
- this.getNetwork()
+ this.lookupNetwork()
}
useEtherscanProvider () {
@@ -619,26 +635,32 @@ module.exports = class MetamaskController extends EventEmitter {
extension.runtime.reload()
}
- getStateNetwork () {
- return this.state.network
+ getNetworkState () {
+ return this.networkStore.getState().network
+ }
+
+ setNetworkState (network) {
+ return this.networkStore.updateState({ network })
+ }
+
+ isNetworkLoading () {
+ return this.getNetworkState() === 'loading'
}
- getNetwork (err) {
+ lookupNetwork (err) {
if (err) {
- this.state.network = 'loading'
- this.sendUpdate()
+ this.setNetworkState('loading')
}
this.ethQuery.sendAsync({ method: 'net_version' }, (err, network) => {
if (err) {
- this.state.network = 'loading'
- return this.sendUpdate()
+ this.setNetworkState('loading')
+ return
}
if (global.METAMASK_DEBUG) {
console.log('web3.getNetwork returned ' + network)
}
- this.state.network = network
- this.sendUpdate()
+ this.setNetworkState(network)
})
}
diff --git a/app/scripts/migrations/007.js b/app/scripts/migrations/007.js
new file mode 100644
index 000000000..3ae8cdc2d
--- /dev/null
+++ b/app/scripts/migrations/007.js
@@ -0,0 +1,38 @@
+const version = 7
+
+/*
+
+This migration breaks out the TransactionManager substate
+
+*/
+
+const extend = require('xtend')
+
+module.exports = {
+ version,
+
+ migrate: function (versionedData) {
+ 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 = extend(state, {
+ TransactionManager: {
+ transactions: state.transactions || [],
+ gasMultiplier: state.gasMultiplier || 1,
+ },
+ })
+ delete newState.transactions
+ delete newState.gasMultiplier
+
+ return newState
+}
diff --git a/app/scripts/migrations/008.js b/app/scripts/migrations/008.js
new file mode 100644
index 000000000..7f6e72ee6
--- /dev/null
+++ b/app/scripts/migrations/008.js
@@ -0,0 +1,36 @@
+const version = 8
+
+/*
+
+This migration breaks out the NoticeController substate
+
+*/
+
+const extend = require('xtend')
+
+module.exports = {
+ version,
+
+ migrate: function (versionedData) {
+ 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 = extend(state, {
+ NoticeController: {
+ noticesList: state.noticesList || [],
+ },
+ })
+ delete newState.noticesList
+
+ return newState
+}
diff --git a/app/scripts/migrations/009.js b/app/scripts/migrations/009.js
new file mode 100644
index 000000000..61b8b7fa2
--- /dev/null
+++ b/app/scripts/migrations/009.js
@@ -0,0 +1,40 @@
+const version = 9
+
+/*
+
+This migration breaks out the CurrencyController substate
+
+*/
+
+const merge = require('deep-merge')
+
+module.exports = {
+ version,
+
+ migrate: function (versionedData) {
+ 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 = merge(state, {
+ CurrencyController: {
+ currentCurrency: state.currentFiat || 'USD',
+ conversionRate: state.conversionRate,
+ conversionDate: state.conversionDate,
+ },
+ })
+ delete newState.currentFiat
+ delete newState.conversionRate
+ delete newState.conversionDate
+
+ return newState
+}
diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js
index 17c191448..22bf008ba 100644
--- a/app/scripts/migrations/index.js
+++ b/app/scripts/migrations/index.js
@@ -17,4 +17,7 @@ module.exports = [
require('./004'),
require('./005'),
require('./006'),
+ require('./007'),
+ require('./008'),
+ require('./009'),
]
diff --git a/app/scripts/notice-controller.js b/app/scripts/notice-controller.js
index c3777b4b1..ba7c68df4 100644
--- a/app/scripts/notice-controller.js
+++ b/app/scripts/notice-controller.js
@@ -1,36 +1,37 @@
const EventEmitter = require('events').EventEmitter
+const extend = require('xtend')
+const ObservableStore = require('obs-store')
const hardCodedNotices = require('../../notices/notices.json')
module.exports = class NoticeController extends EventEmitter {
constructor (opts) {
super()
- this.configManager = opts.configManager
this.noticePoller = null
+ const initState = extend({
+ noticesList: [],
+ }, opts.initState)
+ this.store = new ObservableStore(initState)
+ this.memStore = new ObservableStore({})
+ this.store.subscribe(() => this._updateMemstore())
}
- getState () {
- var lastUnreadNotice = this.getLatestUnreadNotice()
+ getNoticesList () {
+ return this.store.getState().noticesList
+ }
- return {
- lastUnreadNotice: lastUnreadNotice,
- noActiveNotices: !lastUnreadNotice,
- }
+ getUnreadNotices () {
+ const notices = this.getNoticesList()
+ return notices.filter((notice) => notice.read === false)
}
- getNoticesList () {
- var data = this.configManager.getData()
- if ('noticesList' in data) {
- return data.noticesList
- } else {
- return []
- }
+ getLatestUnreadNotice () {
+ const unreadNotices = this.getUnreadNotices()
+ return unreadNotices[unreadNotices.length - 1]
}
- setNoticesList (list) {
- var data = this.configManager.getData()
- data.noticesList = list
- this.configManager.setData(data)
+ setNoticesList (noticesList) {
+ this.store.updateState({ noticesList })
return Promise.resolve(true)
}
@@ -56,14 +57,6 @@ module.exports = class NoticeController extends EventEmitter {
})
}
- getLatestUnreadNotice () {
- var notices = this.getNoticesList()
- var filteredNotices = notices.filter((notice) => {
- return notice.read === false
- })
- return filteredNotices[filteredNotices.length - 1]
- }
-
startPolling () {
if (this.noticePoller) {
clearInterval(this.noticePoller)
@@ -92,5 +85,10 @@ module.exports = class NoticeController extends EventEmitter {
return Promise.resolve(hardCodedNotices)
}
+ _updateMemstore () {
+ const lastUnreadNotice = this.getLatestUnreadNotice()
+ const noActiveNotices = !lastUnreadNotice
+ this.memStore.updateState({ lastUnreadNotice, noActiveNotices })
+ }
}
diff --git a/app/scripts/transaction-manager.js b/app/scripts/transaction-manager.js
index 6fecdba39..6299091f2 100644
--- a/app/scripts/transaction-manager.js
+++ b/app/scripts/transaction-manager.js
@@ -2,6 +2,7 @@ const EventEmitter = require('events')
const async = require('async')
const extend = require('xtend')
const Semaphore = require('semaphore')
+const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util')
const BN = require('ethereumjs-util').BN
const TxProviderUtil = require('./lib/tx-utils')
@@ -10,33 +11,53 @@ const createId = require('./lib/random-id')
module.exports = class TransactionManager extends EventEmitter {
constructor (opts) {
super()
- this.txList = opts.txList || []
- this._setTxList = opts.setTxList
+ this.store = new ObservableStore(extend({
+ transactions: [],
+ gasMultiplier: 1,
+ }, opts.initState))
+ this.memStore = new ObservableStore({})
+ this.networkStore = opts.networkStore || new ObservableStore({})
+ this.preferencesStore = opts.preferencesStore || new ObservableStore({})
this.txHistoryLimit = opts.txHistoryLimit
- this.getSelectedAddress = opts.getSelectedAddress
this.provider = opts.provider
this.blockTracker = opts.blockTracker
this.txProviderUtils = new TxProviderUtil(this.provider)
this.blockTracker.on('block', this.checkForTxInBlock.bind(this))
- this.getGasMultiplier = opts.getGasMultiplier
- this.getNetwork = opts.getNetwork
this.signEthTx = opts.signTransaction
this.nonceLock = Semaphore(1)
+
+ // memstore is computed from a few different stores
+ this._updateMemstore()
+ this.store.subscribe(() => this._updateMemstore() )
+ this.networkStore.subscribe(() => this._updateMemstore() )
+ this.preferencesStore.subscribe(() => this._updateMemstore() )
}
getState () {
- var selectedAddress = this.getSelectedAddress()
- return {
- transactions: this.getTxList(),
- unapprovedTxs: this.getUnapprovedTxList(),
- selectedAddressTxList: this.getFilteredTxList({metamaskNetworkId: this.getNetwork(), from: selectedAddress}),
- }
+ return this.memStore.getState()
+ }
+
+ getNetwork () {
+ return this.networkStore.getState().network
}
-// Returns the tx list
+ getSelectedAddress () {
+ return this.preferencesStore.getState().selectedAddress
+ }
+
+ // Returns the tx list
getTxList () {
let network = this.getNetwork()
- return this.txList.filter(txMeta => txMeta.metamaskNetworkId === network)
+ let fullTxList = this.store.getState().transactions
+ return fullTxList.filter(txMeta => txMeta.metamaskNetworkId === network)
+ }
+
+ getGasMultiplier () {
+ return this.store.getState().gasMultiplier
+ }
+
+ setGasMultiplier (gasMultiplier) {
+ return this.store.updateState({ gasMultiplier })
}
// Adds a tx to the txlist
@@ -108,7 +129,7 @@ module.exports = class TransactionManager extends EventEmitter {
id: txId,
time: time,
status: 'unapproved',
- gasMultiplier: this.getGasMultiplier() || 1,
+ gasMultiplier: this.getGasMultiplier(),
metamaskNetworkId: this.getNetwork(),
txParams: txParams,
}
@@ -239,7 +260,7 @@ module.exports = class TransactionManager extends EventEmitter {
getTxsByMetaData (key, value, txList = this.getTxList()) {
return txList.filter((txMeta) => {
- if (key in txMeta.txParams) {
+ if (txMeta.txParams[key]) {
return txMeta.txParams[key] === value
} else {
return txMeta[key] === value
@@ -351,9 +372,17 @@ module.exports = class TransactionManager extends EventEmitter {
// Saves the new/updated txList.
// Function is intended only for internal use
- _saveTxList (txList) {
- this.txList = txList
- this._setTxList(txList)
+ _saveTxList (transactions) {
+ this.store.updateState({ transactions })
+ }
+
+ _updateMemstore () {
+ const unapprovedTxs = this.getUnapprovedTxList()
+ const selectedAddressTxList = this.getFilteredTxList({
+ from: this.getSelectedAddress(),
+ metamaskNetworkId: this.getNetwork(),
+ })
+ this.memStore.updateState({ unapprovedTxs, selectedAddressTxList })
}
}
diff --git a/package.json b/package.json
index ecf906684..ed0be3d4b 100644
--- a/package.json
+++ b/package.json
@@ -11,8 +11,8 @@
"disc": "gulp disc --debug",
"dist": "gulp dist --disableLiveReload",
"test": "npm run lint && npm run fastTest && npm run ci",
- "fastTest": "METAMASK_ENV=test mocha --require test/helper.js --compilers js:babel-register --recursive \"test/unit/**/*.js\"",
- "watch": "mocha watch --compilers js:babel-register --recursive \"test/unit/**/*.js\"",
+ "fastTest": "METAMASK_ENV=test mocha --require test/helper.js --recursive \"test/unit/**/*.js\"",
+ "watch": "mocha watch --recursive \"test/unit/**/*.js\"",
"genStates": "node development/genStates.js",
"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 ./",
@@ -45,6 +45,7 @@
"clone": "^1.0.2",
"copy-to-clipboard": "^2.0.0",
"debounce": "^1.0.0",
+ "deep-merge": "^1.0.0",
"denodeify": "^1.2.1",
"disc": "^1.3.2",
"dnode": "^1.2.2",
@@ -71,7 +72,7 @@
"mississippi": "^1.2.0",
"mkdirp": "^0.5.1",
"multiplex": "^6.7.0",
- "obs-store": "^2.3.0",
+ "obs-store": "^2.3.1",
"once": "^1.3.3",
"ping-pong-stream": "^1.0.0",
"pojo-migrator": "^2.1.0",
diff --git a/test/integration/index.html b/test/integration/index.html
index 8a54cb829..430814a8a 100644
--- a/test/integration/index.html
+++ b/test/integration/index.html
@@ -15,7 +15,7 @@
<script src="bundle.js"></script>
<script src="/testem.js"></script>
- <iframe src="/development/test.html" height="500px" width="360px">
+ <iframe src="/development/test.html" height="800px" width="500px">
<p>Your browser does not support iframes</p>
</iframe>
</body>
diff --git a/test/unit/config-manager-test.js b/test/unit/config-manager-test.js
index acc73ebb4..c6f60192f 100644
--- a/test/unit/config-manager-test.js
+++ b/test/unit/config-manager-test.js
@@ -14,81 +14,6 @@ describe('config-manager', function() {
configManager = configManagerGen()
})
- describe('currency conversions', function() {
-
- describe('#setCurrentFiat', function() {
- it('should return USD as default', function() {
- assert.equal(configManager.getCurrentFiat(), 'USD')
- })
-
- it('should be able to set to other currency', function() {
- assert.equal(configManager.getCurrentFiat(), 'USD')
- configManager.setCurrentFiat('JPY')
- var result = configManager.getCurrentFiat()
- assert.equal(result, 'JPY')
- })
- })
-
- describe('#getConversionRate', function() {
- it('should return undefined if non-existent', function() {
- var result = configManager.getConversionRate()
- assert.ok(!result)
- })
- })
-
- describe('#updateConversionRate', function() {
- it('should retrieve an update for ETH to USD and set it in memory', function(done) {
- this.timeout(15000)
- var usdMock = nock('https://www.cryptonator.com')
- .get('/api/ticker/eth-USD')
- .reply(200, '{"ticker":{"base":"ETH","target":"USD","price":"11.02456145","volume":"44948.91745289","change":"-0.01472534"},"timestamp":1472072136,"success":true,"error":""}')
-
- assert.equal(configManager.getConversionRate(), 0)
- var promise = new Promise(
- function (resolve, reject) {
- configManager.setCurrentFiat('USD')
- configManager.updateConversionRate().then(function() {
- resolve()
- })
- })
-
- promise.then(function() {
- var result = configManager.getConversionRate()
- assert.equal(typeof result, 'number')
- done()
- }).catch(function(err) {
- console.log(err)
- })
-
- })
-
- it('should work for JPY as well.', function() {
- this.timeout(15000)
- assert.equal(configManager.getConversionRate(), 0)
-
- var jpyMock = nock('https://www.cryptonator.com')
- .get('/api/ticker/eth-JPY')
- .reply(200, '{"ticker":{"base":"ETH","target":"JPY","price":"11.02456145","volume":"44948.91745289","change":"-0.01472534"},"timestamp":1472072136,"success":true,"error":""}')
-
-
- var promise = new Promise(
- function (resolve, reject) {
- configManager.setCurrentFiat('JPY')
- configManager.updateConversionRate().then(function() {
- resolve()
- })
- })
-
- promise.then(function() {
- var result = configManager.getConversionRate()
- assert.equal(typeof result, 'number')
- }).catch(function(err) {
- console.log(err)
- })
- })
- })
- })
-
describe('confirmation', function() {
describe('#getConfirmedDisclaimer', function() {
diff --git a/test/unit/currency-controller-test.js b/test/unit/currency-controller-test.js
new file mode 100644
index 000000000..c57b522c7
--- /dev/null
+++ b/test/unit/currency-controller-test.js
@@ -0,0 +1,87 @@
+// polyfill fetch
+global.fetch = global.fetch || require('isomorphic-fetch')
+
+const assert = require('assert')
+const extend = require('xtend')
+const rp = require('request-promise')
+const nock = require('nock')
+const CurrencyController = require('../../app/scripts/lib/controllers/currency')
+
+describe('config-manager', function() {
+ var currencyController
+
+ beforeEach(function() {
+ currencyController = new CurrencyController()
+ })
+
+ describe('currency conversions', function() {
+
+ describe('#setCurrentCurrency', function() {
+ it('should return USD as default', function() {
+ assert.equal(currencyController.getCurrentCurrency(), 'USD')
+ })
+
+ it('should be able to set to other currency', function() {
+ assert.equal(currencyController.getCurrentCurrency(), 'USD')
+ currencyController.setCurrentCurrency('JPY')
+ var result = currencyController.getCurrentCurrency()
+ assert.equal(result, 'JPY')
+ })
+ })
+
+ describe('#getConversionRate', function() {
+ it('should return undefined if non-existent', function() {
+ var result = currencyController.getConversionRate()
+ assert.ok(!result)
+ })
+ })
+
+ describe('#updateConversionRate', function() {
+ it('should retrieve an update for ETH to USD and set it in memory', function(done) {
+ this.timeout(15000)
+ var usdMock = nock('https://www.cryptonator.com')
+ .get('/api/ticker/eth-USD')
+ .reply(200, '{"ticker":{"base":"ETH","target":"USD","price":"11.02456145","volume":"44948.91745289","change":"-0.01472534"},"timestamp":1472072136,"success":true,"error":""}')
+
+ assert.equal(currencyController.getConversionRate(), 0)
+ currencyController.setCurrentCurrency('USD')
+ currencyController.updateConversionRate()
+ .then(function() {
+ var result = currencyController.getConversionRate()
+ console.log('currencyController.getConversionRate:', result)
+ assert.equal(typeof result, 'number')
+ done()
+ }).catch(function(err) {
+ done(err)
+ })
+
+ })
+
+ it('should work for JPY as well.', function() {
+ this.timeout(15000)
+ assert.equal(currencyController.getConversionRate(), 0)
+
+ var jpyMock = nock('https://www.cryptonator.com')
+ .get('/api/ticker/eth-JPY')
+ .reply(200, '{"ticker":{"base":"ETH","target":"JPY","price":"11.02456145","volume":"44948.91745289","change":"-0.01472534"},"timestamp":1472072136,"success":true,"error":""}')
+
+
+ var promise = new Promise(
+ function (resolve, reject) {
+ currencyController.setCurrentCurrency('JPY')
+ currencyController.updateConversionRate().then(function() {
+ resolve()
+ })
+ })
+
+ promise.then(function() {
+ var result = currencyController.getConversionRate()
+ assert.equal(typeof result, 'number')
+ }).catch(function(err) {
+ done(err)
+ })
+ })
+ })
+ })
+
+})
diff --git a/test/unit/message-manager-test.js b/test/unit/message-manager-test.js
index 68b977058..faf7429d4 100644
--- a/test/unit/message-manager-test.js
+++ b/test/unit/message-manager-test.js
@@ -13,7 +13,7 @@ describe('Transaction Manager', function() {
describe('#getMsgList', function() {
it('when new should return empty array', function() {
- var result = messageManager.getMsgList()
+ var result = messageManager.messages
assert.ok(Array.isArray(result))
assert.equal(result.length, 0)
})
@@ -22,20 +22,11 @@ describe('Transaction Manager', function() {
})
})
- describe('#_saveMsgList', function() {
- it('saves the submitted data to the Msg list', function() {
- var target = [{ foo: 'bar', metamaskNetworkId: 'unit test' }]
- messageManager._saveMsgList(target)
- var result = messageManager.getMsgList()
- assert.equal(result[0].foo, 'bar')
- })
- })
-
describe('#addMsg', function() {
it('adds a Msg returned in getMsgList', function() {
var Msg = { id: 1, status: 'approved', metamaskNetworkId: 'unit test' }
messageManager.addMsg(Msg)
- var result = messageManager.getMsgList()
+ var result = messageManager.messages
assert.ok(Array.isArray(result))
assert.equal(result.length, 1)
assert.equal(result[0].id, 1)
@@ -47,7 +38,7 @@ describe('Transaction Manager', function() {
var Msg = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' }
messageManager.addMsg(Msg)
messageManager.setMsgStatusApproved(1)
- var result = messageManager.getMsgList()
+ var result = messageManager.messages
assert.ok(Array.isArray(result))
assert.equal(result.length, 1)
assert.equal(result[0].status, 'approved')
@@ -59,7 +50,7 @@ describe('Transaction Manager', function() {
var Msg = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' }
messageManager.addMsg(Msg)
messageManager.rejectMsg(1)
- var result = messageManager.getMsgList()
+ var result = messageManager.messages
assert.ok(Array.isArray(result))
assert.equal(result.length, 1)
assert.equal(result[0].status, 'rejected')
diff --git a/test/unit/tx-manager-test.js b/test/unit/tx-manager-test.js
index a66003f85..f64f048e3 100644
--- a/test/unit/tx-manager-test.js
+++ b/test/unit/tx-manager-test.js
@@ -1,21 +1,19 @@
const assert = require('assert')
const extend = require('xtend')
const EventEmitter = require('events')
+const ObservableStore = require('obs-store')
const STORAGE_KEY = 'metamask-persistance-key'
const TransactionManager = require('../../app/scripts/transaction-manager')
+const noop = () => true
describe('Transaction Manager', function() {
let txManager
- const onTxDoneCb = () => true
beforeEach(function() {
- txManager = new TransactionManager ({
- txList: [],
- setTxList: () => {},
- provider: "testnet",
+ txManager = new TransactionManager({
+ networkStore: new ObservableStore({ network: 'unit test' }),
txHistoryLimit: 10,
blockTracker: new EventEmitter(),
- getNetwork: function(){ return 'unit test' }
})
})
@@ -51,19 +49,10 @@ describe('Transaction Manager', function() {
})
})
- describe('#_saveTxList', function() {
- it('saves the submitted data to the tx list', function() {
- var target = [{ foo: 'bar', metamaskNetworkId: 'unit test' }]
- txManager._saveTxList(target)
- var result = txManager.getTxList()
- assert.equal(result[0].foo, 'bar')
- })
- })
-
describe('#addTx', function() {
it('adds a tx returned in getTxList', function() {
- var tx = { id: 1, status: 'confirmed', metamaskNetworkId: 'unit test' }
- txManager.addTx(tx, onTxDoneCb)
+ var tx = { id: 1, status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} }
+ txManager.addTx(tx, noop)
var result = txManager.getTxList()
assert.ok(Array.isArray(result))
assert.equal(result.length, 1)
@@ -73,8 +62,8 @@ describe('Transaction Manager', function() {
it('cuts off early txs beyond a limit', function() {
const limit = txManager.txHistoryLimit
for (let i = 0; i < limit + 1; i++) {
- let tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: 'unit test' }
- txManager.addTx(tx, onTxDoneCb)
+ let tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} }
+ txManager.addTx(tx, noop)
}
var result = txManager.getTxList()
assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
@@ -84,8 +73,8 @@ describe('Transaction Manager', function() {
it('cuts off early txs beyond a limit whether or not it is confirmed or rejected', function() {
const limit = txManager.txHistoryLimit
for (let i = 0; i < limit + 1; i++) {
- let tx = { id: i, time: new Date(), status: 'rejected', metamaskNetworkId: 'unit test' }
- txManager.addTx(tx, onTxDoneCb)
+ let tx = { id: i, time: new Date(), status: 'rejected', metamaskNetworkId: 'unit test', txParams: {} }
+ txManager.addTx(tx, noop)
}
var result = txManager.getTxList()
assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
@@ -93,12 +82,12 @@ describe('Transaction Manager', function() {
})
it('cuts off early txs beyond a limit but does not cut unapproved txs', function() {
- var unconfirmedTx = { id: 0, time: new Date(), status: 'unapproved', metamaskNetworkId: 'unit test' }
- txManager.addTx(unconfirmedTx, onTxDoneCb)
+ var unconfirmedTx = { id: 0, time: new Date(), status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} }
+ txManager.addTx(unconfirmedTx, noop)
const limit = txManager.txHistoryLimit
for (let i = 1; i < limit + 1; i++) {
- let tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: 'unit test' }
- txManager.addTx(tx, onTxDoneCb)
+ let tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} }
+ txManager.addTx(tx, noop)
}
var result = txManager.getTxList()
assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
@@ -110,8 +99,8 @@ describe('Transaction Manager', function() {
describe('#setTxStatusSigned', function() {
it('sets the tx status to signed', function() {
- var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' }
- txManager.addTx(tx, onTxDoneCb)
+ var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} }
+ txManager.addTx(tx, noop)
txManager.setTxStatusSigned(1)
var result = txManager.getTxList()
assert.ok(Array.isArray(result))
@@ -121,20 +110,20 @@ describe('Transaction Manager', function() {
it('should emit a signed event to signal the exciton of callback', (done) => {
this.timeout(10000)
- var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' }
- let onTxDoneCb = function () {
- assert(true, 'event listener has been triggered and onTxDoneCb executed')
+ var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} }
+ let noop = function () {
+ assert(true, 'event listener has been triggered and noop executed')
done()
}
txManager.addTx(tx)
- txManager.on('1:signed', onTxDoneCb)
+ txManager.on('1:signed', noop)
txManager.setTxStatusSigned(1)
})
})
describe('#setTxStatusRejected', function() {
it('sets the tx status to rejected', function() {
- var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' }
+ var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} }
txManager.addTx(tx)
txManager.setTxStatusRejected(1)
var result = txManager.getTxList()
@@ -145,13 +134,13 @@ describe('Transaction Manager', function() {
it('should emit a rejected event to signal the exciton of callback', (done) => {
this.timeout(10000)
- var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' }
+ var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} }
txManager.addTx(tx)
- let onTxDoneCb = function (err, txId) {
- assert(true, 'event listener has been triggered and onTxDoneCb executed')
+ let noop = function (err, txId) {
+ assert(true, 'event listener has been triggered and noop executed')
done()
}
- txManager.on('1:rejected', onTxDoneCb)
+ txManager.on('1:rejected', noop)
txManager.setTxStatusRejected(1)
})
@@ -159,9 +148,9 @@ describe('Transaction Manager', function() {
describe('#updateTx', function() {
it('replaces the tx with the same id', function() {
- txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test' }, onTxDoneCb)
- txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test' }, onTxDoneCb)
- txManager.updateTx({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: 'unit test' })
+ txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} }, noop)
+ txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} }, noop)
+ txManager.updateTx({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: 'unit test', txParams: {} })
var result = txManager.getTx('1')
assert.equal(result.hash, 'foo')
})
@@ -169,8 +158,8 @@ describe('Transaction Manager', function() {
describe('#getUnapprovedTxList', function() {
it('returns unapproved txs in a hash', function() {
- txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test' }, onTxDoneCb)
- txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test' }, onTxDoneCb)
+ txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} }, noop)
+ txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} }, noop)
let result = txManager.getUnapprovedTxList()
assert.equal(typeof result, 'object')
assert.equal(result['1'].status, 'unapproved')
@@ -180,8 +169,8 @@ describe('Transaction Manager', function() {
describe('#getTx', function() {
it('returns a tx with the requested id', function() {
- txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test' }, onTxDoneCb)
- txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test' }, onTxDoneCb)
+ txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test', txParams: {} }, noop)
+ txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test', txParams: {} }, noop)
assert.equal(txManager.getTx('1').status, 'unapproved')
assert.equal(txManager.getTx('2').status, 'confirmed')
})
@@ -189,26 +178,33 @@ describe('Transaction Manager', function() {
describe('#getFilteredTxList', function() {
it('returns a tx with the requested data', function() {
- var foop = 0
- var zoop = 0
- for (let i = 0; i < 10; ++i ){
- let everyOther = i % 2
- txManager.addTx({ id: i,
- status: everyOther ? 'unapproved' : 'confirmed',
- metamaskNetworkId: 'unit test',
- txParams: {
- from: everyOther ? 'foop' : 'zoop',
- to: everyOther ? 'zoop' : 'foop',
- }
- }, onTxDoneCb)
- everyOther ? ++foop : ++zoop
- }
- assert.equal(txManager.getFilteredTxList({status: 'confirmed', from: 'zoop'}).length, zoop)
- assert.equal(txManager.getFilteredTxList({status: 'confirmed', to: 'foop'}).length, zoop)
- assert.equal(txManager.getFilteredTxList({status: 'confirmed', from: 'foop'}).length, 0)
- assert.equal(txManager.getFilteredTxList({status: 'confirmed'}).length, zoop)
- assert.equal(txManager.getFilteredTxList({from: 'foop'}).length, foop)
- assert.equal(txManager.getFilteredTxList({from: 'zoop'}).length, zoop)
+ let txMetas = [
+ { id: 0, status: 'unapproved', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: 'unit test' },
+ { id: 1, status: 'unapproved', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: 'unit test' },
+ { id: 2, status: 'unapproved', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: 'unit test' },
+ { id: 3, status: 'unapproved', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: 'unit test' },
+ { id: 4, status: 'unapproved', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: 'unit test' },
+ { id: 5, status: 'confirmed', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: 'unit test' },
+ { id: 6, status: 'confirmed', txParams: { from: '0xaa', to: '0xbb' }, metamaskNetworkId: 'unit test' },
+ { id: 7, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: 'unit test' },
+ { id: 8, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: 'unit test' },
+ { id: 9, status: 'confirmed', txParams: { from: '0xbb', to: '0xaa' }, metamaskNetworkId: 'unit test' },
+ ]
+ txMetas.forEach((txMeta) => txManager.addTx(txMeta, noop))
+ let filterParams
+
+ filterParams = { status: 'unapproved', from: '0xaa' }
+ assert.equal(txManager.getFilteredTxList(filterParams).length, 3, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
+ filterParams = { status: 'unapproved', to: '0xaa' }
+ assert.equal(txManager.getFilteredTxList(filterParams).length, 2, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
+ filterParams = { status: 'confirmed', from: '0xbb' }
+ assert.equal(txManager.getFilteredTxList(filterParams).length, 3, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
+ filterParams = { status: 'confirmed' }
+ assert.equal(txManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
+ filterParams = { from: '0xaa' }
+ assert.equal(txManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
+ filterParams = { to: '0xaa' }
+ assert.equal(txManager.getFilteredTxList(filterParams).length, 5, `getFilteredTxList - ${JSON.stringify(filterParams)}`)
})
})
diff --git a/ui/app/actions.js b/ui/app/actions.js
index fa1e0deb5..c153a55a6 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -158,6 +158,7 @@ var actions = {
showNewKeychain: showNewKeychain,
callBackgroundThenUpdate,
+ forceUpdateMetamaskState,
}
module.exports = actions
@@ -179,13 +180,14 @@ function tryUnlockMetamask (password) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
dispatch(actions.unlockInProgress())
- background.submitPassword(password, (err, newState) => {
+ if (global.METAMASK_DEBUG) console.log(`background.submitPassword`)
+ background.submitPassword(password, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) {
dispatch(actions.unlockFailed(err.message))
} else {
dispatch(actions.transitionForward())
- dispatch(actions.updateMetamaskState(newState))
+ forceUpdateMetamaskState(dispatch)
}
})
}
@@ -206,6 +208,7 @@ function transitionBackward () {
function confirmSeedWords () {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.clearSeedWordCache`)
background.clearSeedWordCache((err, account) => {
dispatch(actions.hideLoadingIndication())
if (err) {
@@ -221,6 +224,7 @@ function confirmSeedWords () {
function createNewVaultAndRestore (password, seed) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.createNewVaultAndRestore`)
background.createNewVaultAndRestore(password, seed, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) return dispatch(actions.displayWarning(err.message))
@@ -232,16 +236,18 @@ function createNewVaultAndRestore (password, seed) {
function createNewVaultAndKeychain (password) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- background.createNewVaultAndKeychain(password, (err, newState) => {
+ if (global.METAMASK_DEBUG) console.log(`background.createNewVaultAndKeychain`)
+ background.createNewVaultAndKeychain(password, (err) => {
if (err) {
return dispatch(actions.displayWarning(err.message))
}
- background.placeSeedWords((err, newState) => {
+ if (global.METAMASK_DEBUG) console.log(`background.placeSeedWords`)
+ background.placeSeedWords((err) => {
if (err) {
return dispatch(actions.displayWarning(err.message))
}
dispatch(actions.hideLoadingIndication())
- dispatch(actions.updateMetamaskState(newState))
+ forceUpdateMetamaskState(dispatch)
})
})
}
@@ -256,8 +262,10 @@ function revealSeedConfirmation () {
function requestRevealSeed (password) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.submitPassword`)
background.submitPassword(password, (err) => {
if (err) return dispatch(actions.displayWarning(err.message))
+ if (global.METAMASK_DEBUG) console.log(`background.placeSeedWords`)
background.placeSeedWords((err) => {
if (err) return dispatch(actions.displayWarning(err.message))
dispatch(actions.hideLoadingIndication())
@@ -269,6 +277,7 @@ function requestRevealSeed (password) {
function addNewKeyring (type, opts) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.addNewKeyring`)
background.addNewKeyring(type, opts, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) return dispatch(actions.displayWarning(err.message))
@@ -280,13 +289,20 @@ function addNewKeyring (type, opts) {
function importNewAccount (strategy, args) {
return (dispatch) => {
dispatch(actions.showLoadingIndication('This may take a while, be patient.'))
- background.importAccountWithStrategy(strategy, args, (err, newState) => {
+ if (global.METAMASK_DEBUG) console.log(`background.importAccountWithStrategy`)
+ background.importAccountWithStrategy(strategy, args, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) return dispatch(actions.displayWarning(err.message))
- dispatch(actions.updateMetamaskState(newState))
- dispatch({
- type: actions.SHOW_ACCOUNT_DETAIL,
- value: newState.selectedAddress,
+ if (global.METAMASK_DEBUG) console.log(`background.getState`)
+ background.getState((err, newState) => {
+ if (err) {
+ return dispatch(actions.displayWarning(err.message))
+ }
+ dispatch(actions.updateMetamaskState(newState))
+ dispatch({
+ type: actions.SHOW_ACCOUNT_DETAIL,
+ value: newState.selectedAddress,
+ })
})
})
}
@@ -299,6 +315,7 @@ function navigateToNewAccountScreen() {
}
function addNewAccount () {
+ if (global.METAMASK_DEBUG) console.log(`background.addNewAccount`)
return callBackgroundThenUpdate(background.addNewAccount)
}
@@ -308,11 +325,16 @@ function showInfoPage () {
}
}
-function setCurrentFiat (fiat) {
+function setCurrentFiat (currencyCode) {
return (dispatch) => {
dispatch(this.showLoadingIndication())
- background.setCurrentFiat(fiat, (data, err) => {
+ if (global.METAMASK_DEBUG) console.log(`background.setCurrentFiat`)
+ background.setCurrentCurrency(currencyCode, (err, data) => {
dispatch(this.hideLoadingIndication())
+ if (err) {
+ console.error(err.stack)
+ return dispatch(actions.displayWarning(err.message))
+ }
dispatch({
type: this.SET_CURRENT_FIAT,
value: {
@@ -329,6 +351,7 @@ function signMsg (msgData) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.signMessage`)
background.signMessage(msgData, (err) => {
dispatch(actions.hideLoadingIndication())
@@ -340,6 +363,7 @@ function signMsg (msgData) {
function signTx (txData) {
return (dispatch) => {
+ if (global.METAMASK_DEBUG) console.log(`background.setGasMultiplier`)
background.setGasMultiplier(txData.gasMultiplier, (err) => {
if (err) return dispatch(actions.displayWarning(err.message))
web3.eth.sendTransaction(txData, (err, data) => {
@@ -355,6 +379,7 @@ function signTx (txData) {
function sendTx (txData) {
return (dispatch) => {
+ if (global.METAMASK_DEBUG) console.log(`background.approveTransaction`)
background.approveTransaction(txData.id, (err) => {
if (err) {
alert(err.message)
@@ -381,11 +406,13 @@ function txError (err) {
}
function cancelMsg (msgData) {
+ if (global.METAMASK_DEBUG) console.log(`background.cancelMessage`)
background.cancelMessage(msgData.id)
return actions.completedTx(msgData.id)
}
function cancelTx (txData) {
+ if (global.METAMASK_DEBUG) console.log(`background.cancelTransaction`)
background.cancelTransaction(txData.id)
return actions.completedTx(txData.id)
}
@@ -427,6 +454,7 @@ function showImportPage () {
function agreeToDisclaimer () {
return (dispatch) => {
dispatch(this.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.agreeToDisclaimer`)
background.agreeToDisclaimer((err) => {
if (err) {
return dispatch(actions.displayWarning(err.message))
@@ -497,12 +525,14 @@ function updateMetamaskState (newState) {
}
function lockMetamask () {
+ if (global.METAMASK_DEBUG) console.log(`background.setLocked`)
return callBackgroundThenUpdate(background.setLocked)
}
function showAccountDetail (address) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.setSelectedAddress`)
background.setSelectedAddress(address, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) {
@@ -575,6 +605,7 @@ function goBackToInitView () {
function markNoticeRead (notice) {
return (dispatch) => {
dispatch(this.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.markNoticeRead`)
background.markNoticeRead(notice, (err, notice) => {
dispatch(this.hideLoadingIndication())
if (err) {
@@ -606,6 +637,7 @@ function clearNotices () {
}
function markAccountsFound() {
+ if (global.METAMASK_DEBUG) console.log(`background.markAccountsFound`)
return callBackgroundThenUpdate(background.markAccountsFound)
}
@@ -614,6 +646,7 @@ function markAccountsFound() {
//
function setRpcTarget (newRpc) {
+ if (global.METAMASK_DEBUG) console.log(`background.setRpcTarget`)
background.setRpcTarget(newRpc)
return {
type: actions.SET_RPC_TARGET,
@@ -622,6 +655,7 @@ function setRpcTarget (newRpc) {
}
function setProviderType (type) {
+ if (global.METAMASK_DEBUG) console.log(`background.setProviderType`)
background.setProviderType(type)
return {
type: actions.SET_PROVIDER_TYPE,
@@ -630,6 +664,7 @@ function setProviderType (type) {
}
function useEtherscanProvider () {
+ if (global.METAMASK_DEBUG) console.log(`background.useEtherscanProvider`)
background.useEtherscanProvider()
return {
type: actions.USE_ETHERSCAN_PROVIDER,
@@ -686,6 +721,7 @@ function exportAccount (address) {
return function (dispatch) {
dispatch(self.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.exportAccount`)
background.exportAccount(address, function (err, result) {
dispatch(self.hideLoadingIndication())
@@ -709,6 +745,7 @@ function showPrivateKey (key) {
function saveAccountLabel (account, label) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
+ if (global.METAMASK_DEBUG) console.log(`background.saveAccountLabel`)
background.saveAccountLabel(account, label, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) {
@@ -730,6 +767,7 @@ function showSendPage () {
function buyEth (address, amount) {
return (dispatch) => {
+ if (global.METAMASK_DEBUG) console.log(`background.buyEth`)
background.buyEth(address, amount)
dispatch({
type: actions.BUY_ETH,
@@ -808,6 +846,7 @@ function coinShiftRquest (data, marketData) {
if (response.error) return dispatch(actions.displayWarning(response.error))
var message = `
Deposit your ${response.depositType} to the address bellow:`
+ if (global.METAMASK_DEBUG) console.log(`background.createShapeShiftTx`)
background.createShapeShiftTx(response.deposit, response.depositType)
dispatch(actions.showQrView(response.deposit, [message].concat(marketData)))
})
@@ -876,12 +915,22 @@ function shapeShiftRequest (query, options, cb) {
function callBackgroundThenUpdate (method, ...args) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- method.call(background, ...args, (err, newState) => {
+ method.call(background, ...args, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) {
return dispatch(actions.displayWarning(err.message))
}
- dispatch(actions.updateMetamaskState(newState))
+ forceUpdateMetamaskState(dispatch)
})
}
}
+
+function forceUpdateMetamaskState(dispatch){
+ if (global.METAMASK_DEBUG) console.log(`background.getState`)
+ background.getState((err, newState) => {
+ if (err) {
+ return dispatch(actions.displayWarning(err.message))
+ }
+ dispatch(actions.updateMetamaskState(newState))
+ })
+} \ No newline at end of file