aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'app/scripts/controllers')
-rw-r--r--app/scripts/controllers/balance.js70
-rw-r--r--app/scripts/controllers/computed-balances.js66
-rw-r--r--app/scripts/controllers/currency.js6
-rw-r--r--app/scripts/controllers/network.js79
-rw-r--r--app/scripts/controllers/preferences.js2
-rw-r--r--app/scripts/controllers/transactions.js372
6 files changed, 264 insertions, 331 deletions
diff --git a/app/scripts/controllers/balance.js b/app/scripts/controllers/balance.js
new file mode 100644
index 000000000..4fa4c78fe
--- /dev/null
+++ b/app/scripts/controllers/balance.js
@@ -0,0 +1,70 @@
+const ObservableStore = require('obs-store')
+const PendingBalanceCalculator = require('../lib/pending-balance-calculator')
+const BN = require('ethereumjs-util').BN
+
+class BalanceController {
+
+ constructor (opts = {}) {
+ const { address, accountTracker, txController, blockTracker } = opts
+ this.address = address
+ this.accountTracker = accountTracker
+ this.txController = txController
+ this.blockTracker = blockTracker
+
+ const initState = {
+ ethBalance: undefined,
+ }
+ this.store = new ObservableStore(initState)
+
+ this.balanceCalc = new PendingBalanceCalculator({
+ getBalance: () => this._getBalance(),
+ getPendingTransactions: this._getPendingTransactions.bind(this),
+ })
+
+ this._registerUpdates()
+ }
+
+ async updateBalance () {
+ const balance = await this.balanceCalc.getBalance()
+ this.store.updateState({
+ ethBalance: balance,
+ })
+ }
+
+ _registerUpdates () {
+ const update = this.updateBalance.bind(this)
+
+ this.txController.on('tx:status-update', (txId, status) => {
+ switch (status) {
+ case 'submitted':
+ case 'confirmed':
+ case 'failed':
+ update()
+ return
+ default:
+ return
+ }
+ })
+ this.accountTracker.store.subscribe(update)
+ this.blockTracker.on('block', update)
+ }
+
+ async _getBalance () {
+ const { accounts } = this.accountTracker.store.getState()
+ const entry = accounts[this.address]
+ const balance = entry.balance
+ return balance ? new BN(balance.substring(2), 16) : undefined
+ }
+
+ async _getPendingTransactions () {
+ const pending = this.txController.getFilteredTxList({
+ from: this.address,
+ status: 'submitted',
+ err: undefined,
+ })
+ return pending
+ }
+
+}
+
+module.exports = BalanceController
diff --git a/app/scripts/controllers/computed-balances.js b/app/scripts/controllers/computed-balances.js
new file mode 100644
index 000000000..2479e1b3a
--- /dev/null
+++ b/app/scripts/controllers/computed-balances.js
@@ -0,0 +1,66 @@
+const ObservableStore = require('obs-store')
+const extend = require('xtend')
+const BalanceController = require('./balance')
+
+class ComputedbalancesController {
+
+ constructor (opts = {}) {
+ const { accountTracker, txController, blockTracker } = opts
+ this.accountTracker = accountTracker
+ this.txController = txController
+ this.blockTracker = blockTracker
+
+ const initState = extend({
+ computedBalances: {},
+ }, opts.initState)
+ this.store = new ObservableStore(initState)
+ this.balances = {}
+
+ this._initBalanceUpdating()
+ }
+
+ updateAllBalances () {
+ for (let address in this.accountTracker.store.getState().accounts) {
+ this.balances[address].updateBalance()
+ }
+ }
+
+ _initBalanceUpdating () {
+ const store = this.accountTracker.store.getState()
+ this.addAnyAccountsFromStore(store)
+ this.accountTracker.store.subscribe(this.addAnyAccountsFromStore.bind(this))
+ }
+
+ addAnyAccountsFromStore(store) {
+ const balances = store.accounts
+
+ for (let address in balances) {
+ this.trackAddressIfNotAlready(address)
+ }
+ }
+
+ trackAddressIfNotAlready (address) {
+ const state = this.store.getState()
+ if (!(address in state.computedBalances)) {
+ this.trackAddress(address)
+ }
+ }
+
+ trackAddress (address) {
+ let updater = new BalanceController({
+ address,
+ accountTracker: this.accountTracker,
+ txController: this.txController,
+ blockTracker: this.blockTracker,
+ })
+ updater.store.subscribe((accountBalance) => {
+ let newState = this.store.getState()
+ newState.computedBalances[address] = accountBalance
+ this.store.updateState(newState)
+ })
+ this.balances[address] = updater
+ updater.updateBalance()
+ }
+}
+
+module.exports = ComputedbalancesController
diff --git a/app/scripts/controllers/currency.js b/app/scripts/controllers/currency.js
index 1f20dc005..9e696ce55 100644
--- a/app/scripts/controllers/currency.js
+++ b/app/scripts/controllers/currency.js
@@ -8,7 +8,7 @@ class CurrencyController {
constructor (opts = {}) {
const initState = extend({
- currentCurrency: 'USD',
+ currentCurrency: 'usd',
conversionRate: 0,
conversionDate: 'N/A',
}, opts.initState)
@@ -45,10 +45,10 @@ class CurrencyController {
updateConversionRate () {
const currentCurrency = this.getCurrentCurrency()
- return fetch(`https://api.cryptonator.com/api/ticker/eth-${currentCurrency}`)
+ return fetch(`https://api.infura.io/v1/ticker/eth${currentCurrency}`)
.then(response => response.json())
.then((parsedResponse) => {
- this.setConversionRate(Number(parsedResponse.ticker.price))
+ this.setConversionRate(Number(parsedResponse.bid))
this.setConversionDate(Number(parsedResponse.timestamp))
}).catch((err) => {
if (err) {
diff --git a/app/scripts/controllers/network.js b/app/scripts/controllers/network.js
index 0a3e5e26b..2a17cdae8 100644
--- a/app/scripts/controllers/network.js
+++ b/app/scripts/controllers/network.js
@@ -4,66 +4,43 @@ const ObservableStore = require('obs-store')
const ComposedStore = require('obs-store/lib/composed')
const extend = require('xtend')
const EthQuery = require('eth-query')
+const createEventEmitterProxy = require('../lib/events-proxy.js')
const RPC_ADDRESS_LIST = require('../config.js').network
const DEFAULT_RPC = RPC_ADDRESS_LIST['rinkeby']
module.exports = class NetworkController extends EventEmitter {
constructor (config) {
super()
- this.networkStore = new ObservableStore('loading')
config.provider.rpcTarget = this.getRpcAddressForType(config.provider.type, config.provider)
+ this.networkStore = new ObservableStore('loading')
this.providerStore = new ObservableStore(config.provider)
this.store = new ComposedStore({ provider: this.providerStore, network: this.networkStore })
- this._providerListeners = {}
+ this._proxy = createEventEmitterProxy()
this.on('networkDidChange', this.lookupNetwork)
- this.providerStore.subscribe((state) => this.switchNetwork({rpcUrl: state.rpcTarget}))
- }
-
- get provider () {
- return this._proxy
- }
-
- set provider (provider) {
- this._provider = provider
+ this.providerStore.subscribe((state) => this.switchNetwork({ rpcUrl: state.rpcTarget }))
}
initializeProvider (opts, providerContructor = MetaMaskProvider) {
- this.providerInit = opts
- this._provider = providerContructor(opts)
- this._proxy = new Proxy(this._provider, {
- get: (obj, name) => {
- if (name === 'on') return this._on.bind(this)
- return this._provider[name]
- },
- set: (obj, name, value) => {
- this._provider[name] = value
- return value
- },
- })
- this.provider.on('block', this._logBlock.bind(this))
- this.provider.on('error', this.verifyNetwork.bind(this))
- this.ethQuery = new EthQuery(this.provider)
+ this._baseProviderParams = opts
+ const provider = providerContructor(opts)
+ this._setProvider(provider)
+ this._proxy.on('block', this._logBlock.bind(this))
+ this._proxy.on('error', this.verifyNetwork.bind(this))
+ this.ethQuery = new EthQuery(this._proxy)
this.lookupNetwork()
- return this.provider
+ return this._proxy
}
- switchNetwork (providerInit) {
+ switchNetwork (opts) {
this.setNetworkState('loading')
- const newInit = extend(this.providerInit, providerInit)
- this.providerInit = newInit
-
- this._provider.removeAllListeners()
- this._provider.stop()
- this.provider = MetaMaskProvider(newInit)
- // apply the listners created by other controllers
- Object.keys(this._providerListeners).forEach((key) => {
- this._providerListeners[key].forEach((handler) => this._provider.addListener(key, handler))
- })
+ const providerParams = extend(this._baseProviderParams, opts)
+ this._baseProviderParams = providerParams
+ const provider = MetaMaskProvider(providerParams)
+ this._setProvider(provider)
this.emit('networkDidChange')
}
-
verifyNetwork () {
// Check network when restoring connectivity:
if (this.isNetworkLoading()) this.lookupNetwork()
@@ -117,14 +94,26 @@ module.exports = class NetworkController extends EventEmitter {
return provider && provider.rpcTarget ? provider.rpcTarget : DEFAULT_RPC
}
+ _setProvider (provider) {
+ // collect old block tracker events
+ const oldProvider = this._provider
+ let blockTrackerHandlers
+ if (oldProvider) {
+ // capture old block handlers
+ blockTrackerHandlers = oldProvider._blockTracker.proxyEventHandlers
+ // tear down
+ oldProvider.removeAllListeners()
+ oldProvider.stop()
+ }
+ // override block tracler
+ provider._blockTracker = createEventEmitterProxy(provider._blockTracker, blockTrackerHandlers)
+ // set as new provider
+ this._provider = provider
+ this._proxy.setTarget(provider)
+ }
+
_logBlock (block) {
log.info(`BLOCK CHANGED: #${block.number.toString('hex')} 0x${block.hash.toString('hex')}`)
this.verifyNetwork()
}
-
- _on (event, handler) {
- if (!this._providerListeners[event]) this._providerListeners[event] = []
- this._providerListeners[event].push(handler)
- this._provider.on(event, handler)
- }
}
diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js
index e45224593..bc4848421 100644
--- a/app/scripts/controllers/preferences.js
+++ b/app/scripts/controllers/preferences.js
@@ -22,7 +22,7 @@ class PreferencesController {
})
}
- getSelectedAddress (_address) {
+ getSelectedAddress () {
return this.store.getState().selectedAddress
}
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index fb3be6073..4f5c94675 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -1,86 +1,97 @@
const EventEmitter = require('events')
-const extend = require('xtend')
const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util')
+const Transaction = require('ethereumjs-tx')
const EthQuery = require('ethjs-query')
-const TxProviderUtil = require('../lib/tx-utils')
+const TransactionStateManger = require('../lib/tx-state-manager')
+const TxGasUtil = require('../lib/tx-gas-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')
+
+/*
+ Transaction Controller is an aggregate of sub-controllers and trackers
+ composing them in a way to be exposed to the metamask controller
+ - txStateManager
+ responsible for the state of a transaction and
+ storing the transaction
+ - pendingTxTracker
+ watching blocks for transactions to be include
+ and emitting confirmed events
+ - txGasUtil
+ gas calculations and safety buffering
+ - nonceTracker
+ calculating nonces
+*/
module.exports = class TransactionController extends EventEmitter {
constructor (opts) {
super()
- this.store = new ObservableStore(extend({
- transactions: [],
- }, opts.initState))
- this.memStore = new ObservableStore({})
this.networkStore = opts.networkStore || new ObservableStore({})
this.preferencesStore = opts.preferencesStore || new ObservableStore({})
- this.txHistoryLimit = opts.txHistoryLimit
this.provider = opts.provider
this.blockTracker = opts.blockTracker
this.signEthTx = opts.signTransaction
- this.ethStore = opts.ethStore
+ this.accountTracker = opts.accountTracker
+
+ this.memStore = new ObservableStore({})
+ this.query = new EthQuery(this.provider)
+ this.txGasUtil = new TxGasUtil(this.provider)
+ this.txStateManager = new TransactionStateManger({
+ initState: opts.initState,
+ txHistoryLimit: opts.txHistoryLimit,
+ getNetwork: this.getNetwork.bind(this),
+ })
+ this.store = this.txStateManager.store
+ this.txStateManager.on('tx:status-update', this.emit.bind(this, 'tx:status-update'))
this.nonceTracker = new NonceTracker({
provider: this.provider,
- getPendingTransactions: (address) => {
- return this.getFilteredTxList({
- from: address,
- status: 'submitted',
- err: undefined,
- })
- },
+ getPendingTransactions: this.txStateManager.getPendingTransactions.bind(this.txStateManager),
getConfirmedTransactions: (address) => {
- return this.getFilteredTxList({
+ return this.txStateManager.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)
this.pendingTxTracker = new PendingTransactionTracker({
provider: this.provider,
nonceTracker: this.nonceTracker,
+ retryLimit: 3500, // Retry 3500 blocks, or about 1 day.
getBalance: (address) => {
- const account = this.ethStore.getState().accounts[address]
+ const account = this.accountTracker.store.getState().accounts[address]
if (!account) return
return account.balance
},
- publishTransaction: this.txProviderUtil.publishTransaction.bind(this.txProviderUtil),
- getPendingTransactions: () => {
- const network = this.getNetwork()
- return this.getFilteredTxList({
- status: 'submitted',
- metamaskNetworkId: network,
- })
- },
+ publishTransaction: (rawTx) => this.query.sendRawTransaction(rawTx),
+ getPendingTransactions: this.txStateManager.getPendingTransactions.bind(this.txStateManager),
})
- this.pendingTxTracker.on('txWarning', this.updateTx.bind(this))
- this.pendingTxTracker.on('txFailed', this.setTxStatusFailed.bind(this))
- this.pendingTxTracker.on('txConfirmed', this.setTxStatusConfirmed.bind(this))
+ this.txStateManager.store.subscribe(() => this.emit('update:badge'))
- this.blockTracker.on('rawBlock', this.pendingTxTracker.checkForTxInBlock.bind(this.pendingTxTracker))
+ this.pendingTxTracker.on('tx:warning', this.txStateManager.updateTx.bind(this.txStateManager))
+ this.pendingTxTracker.on('tx:failed', this.txStateManager.setTxStatusFailed.bind(this.txStateManager))
+ this.pendingTxTracker.on('tx:confirmed', this.txStateManager.setTxStatusConfirmed.bind(this.txStateManager))
+ this.pendingTxTracker.on('tx:retry', (txMeta) => {
+ if (!('retryCount' in txMeta)) txMeta.retryCount = 0
+ txMeta.retryCount++
+ this.txStateManager.updateTx(txMeta)
+ })
+
+ this.blockTracker.on('block', this.pendingTxTracker.checkForTxInBlock.bind(this.pendingTxTracker))
// this is a little messy but until ethstore has been either
// removed or redone this is to guard against the race condition
- // where ethStore hasent been populated by the results yet
+ // where accountTracker hasent been populated by the results yet
this.blockTracker.once('latest', () => {
this.blockTracker.on('latest', this.pendingTxTracker.resubmitPendingTxs.bind(this.pendingTxTracker))
})
this.blockTracker.on('sync', this.pendingTxTracker.queryPendingTxs.bind(this.pendingTxTracker))
// memstore is computed from a few different stores
this._updateMemstore()
- this.store.subscribe(() => this._updateMemstore())
+ this.txStateManager.store.subscribe(() => this._updateMemstore())
this.networkStore.subscribe(() => this._updateMemstore())
this.preferencesStore.subscribe(() => this._updateMemstore())
}
@@ -97,98 +108,31 @@ module.exports = class TransactionController extends EventEmitter {
return this.preferencesStore.getState().selectedAddress
}
- // Returns the number of txs for the current network.
- getTxCount () {
- return this.getTxList().length
- }
-
- // Returns the full tx list across all networks
- getFullTxList () {
- return this.store.getState().transactions
- }
-
getUnapprovedTxCount () {
- return Object.keys(this.getUnapprovedTxList()).length
- }
-
- getPendingTxCount () {
- return this.getTxsByMetaData('status', 'signed').length
+ return Object.keys(this.txStateManager.getUnapprovedTxList()).length
}
- // Returns the tx list
- getTxList () {
- const network = this.getNetwork()
- const fullTxList = this.getFullTxList()
- return this.getTxsByMetaData('metamaskNetworkId', network, fullTxList)
+ getPendingTxCount (account) {
+ return this.txStateManager.getPendingTransactions(account).length
}
- // gets tx by Id and returns it
- getTx (txId) {
- const txList = this.getTxList()
- const txMeta = txList.find(txData => txData.id === txId)
- return txMeta
- }
- getUnapprovedTxList () {
- const txList = this.getTxList()
- return txList.filter((txMeta) => txMeta.status === 'unapproved')
- .reduce((result, tx) => {
- result[tx.id] = tx
- return result
- }, {})
+ getFilteredTxList (opts) {
+ return this.txStateManager.getFilteredTxList(opts)
}
- updateTx (txMeta) {
- // create txMeta snapshot for history
- 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)
- txList[index] = txMeta
- this._saveTxList(txList)
- this.emit('update')
+ getChainId () {
+ const networkState = this.networkStore.getState()
+ const getChainId = parseInt(networkState)
+ if (Number.isNaN(getChainId)) {
+ return 0
+ } else {
+ return getChainId
+ }
}
// Adds a tx to the txlist
addTx (txMeta) {
- // 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)
- }
- fullTxList.push(txMeta)
- this._saveTxList(fullTxList)
- this.emit('update')
-
- this.once(`${txMeta.id}:signed`, function (txId) {
- this.removeAllListeners(`${txMeta.id}:rejected`)
- })
- this.once(`${txMeta.id}:rejected`, function (txId) {
- this.removeAllListeners(`${txMeta.id}:signed`)
- })
-
- this.emit('updateBadge')
+ this.txStateManager.addTx(txMeta)
this.emit(`${txMeta.id}:unapproved`, txMeta)
}
@@ -198,7 +142,7 @@ module.exports = class TransactionController extends EventEmitter {
this.emit('newUnaprovedTx', txMeta)
// listen for tx completion (success, fail)
return new Promise((resolve, reject) => {
- this.once(`${txMeta.id}:finished`, (completedTx) => {
+ this.txStateManager.once(`${txMeta.id}:finished`, (completedTx) => {
switch (completedTx.status) {
case 'submitted':
return resolve(completedTx.hash)
@@ -213,7 +157,7 @@ module.exports = class TransactionController extends EventEmitter {
async addUnapprovedTransaction (txParams) {
// validate
- await this.txProviderUtil.validateTxParams(txParams)
+ await this.txGasUtil.validateTxParams(txParams)
// construct txMeta
const txMeta = {
id: createId(),
@@ -232,17 +176,15 @@ module.exports = class TransactionController extends EventEmitter {
async addTxDefaults (txMeta) {
const txParams = txMeta.txParams
// ensure value
+ const gasPrice = txParams.gasPrice || await this.query.gasPrice()
txParams.value = txParams.value || '0x0'
- if (!txParams.gasPrice) {
- const gasPrice = await this.query.gasPrice()
- txParams.gasPrice = gasPrice
- }
+ txParams.gasPrice = ethUtil.addHexPrefix(gasPrice.toString(16))
// set gasLimit
- return await this.txProviderUtil.analyzeGasUsage(txMeta)
+ return await this.txGasUtil.analyzeGasUsage(txMeta)
}
async updateAndApproveTransaction (txMeta) {
- this.updateTx(txMeta)
+ this.txStateManager.updateTx(txMeta)
await this.approveTransaction(txMeta.id)
}
@@ -250,24 +192,24 @@ module.exports = class TransactionController extends EventEmitter {
let nonceLock
try {
// approve
- this.setTxStatusApproved(txId)
+ this.txStateManager.setTxStatusApproved(txId)
// get next nonce
- const txMeta = this.getTx(txId)
+ const txMeta = this.txStateManager.getTx(txId)
const fromAddress = txMeta.txParams.from
// wait for a nonce
nonceLock = await this.nonceTracker.getNonceLock(fromAddress)
// add nonce to txParams
- txMeta.txParams.nonce = nonceLock.nextNonce
+ txMeta.txParams.nonce = ethUtil.addHexPrefix(nonceLock.nextNonce.toString(16))
// add nonce debugging information to txMeta
txMeta.nonceDetails = nonceLock.nonceDetails
- this.updateTx(txMeta)
+ this.txStateManager.updateTx(txMeta)
// sign transaction
const rawTx = await this.signTransaction(txId)
await this.publishTransaction(txId, rawTx)
// must set transaction to submitted/failed before releasing lock
nonceLock.releaseLock()
} catch (err) {
- this.setTxStatusFailed(txId, err)
+ this.txStateManager.setTxStatusFailed(txId, err)
// must set transaction to submitted/failed before releasing lock
if (nonceLock) nonceLock.releaseLock()
// continue with error chain
@@ -276,180 +218,46 @@ module.exports = class TransactionController extends EventEmitter {
}
async signTransaction (txId) {
- const txMeta = this.getTx(txId)
+ const txMeta = this.txStateManager.getTx(txId)
const txParams = txMeta.txParams
const fromAddress = txParams.from
// add network/chain id
- txParams.chainId = this.getChainId()
- const ethTx = this.txProviderUtil.buildEthTxFromParams(txParams)
+ txParams.chainId = ethUtil.addHexPrefix(this.getChainId().toString(16))
+ const ethTx = new Transaction(txParams)
await this.signEthTx(ethTx, fromAddress)
- this.setTxStatusSigned(txMeta.id)
+ this.txStateManager.setTxStatusSigned(txMeta.id)
const rawTx = ethUtil.bufferToHex(ethTx.serialize())
return rawTx
}
async publishTransaction (txId, rawTx) {
- const txMeta = this.getTx(txId)
+ const txMeta = this.txStateManager.getTx(txId)
txMeta.rawTx = rawTx
- this.updateTx(txMeta)
- const txHash = await this.txProviderUtil.publishTransaction(rawTx)
+ this.txStateManager.updateTx(txMeta)
+ const txHash = await this.query.sendRawTransaction(rawTx)
this.setTxHash(txId, txHash)
- this.setTxStatusSubmitted(txId)
+ this.txStateManager.setTxStatusSubmitted(txId)
}
async cancelTransaction (txId) {
- this.setTxStatusRejected(txId)
- }
-
-
- getChainId () {
- const networkState = this.networkStore.getState()
- const getChainId = parseInt(networkState)
- if (Number.isNaN(getChainId)) {
- return 0
- } else {
- return getChainId
- }
+ this.txStateManager.setTxStatusRejected(txId)
}
// receives a txHash records the tx as signed
setTxHash (txId, txHash) {
// Add the tx hash to the persisted meta-tx object
- const txMeta = this.getTx(txId)
+ const txMeta = this.txStateManager.getTx(txId)
txMeta.hash = txHash
- this.updateTx(txMeta)
- }
-
- /*
- Takes an object of fields to search for eg:
- let thingsToLookFor = {
- to: '0x0..',
- from: '0x0..',
- status: 'signed',
- err: undefined,
- }
- and returns a list of tx with all
- options matching
-
- ****************HINT****************
- | `err: undefined` is like looking |
- | for a tx with no err |
- | so you can also search txs that |
- | dont have something as well by |
- | setting the value as undefined |
- ************************************
-
- this is for things like filtering a the tx list
- for only tx's from 1 account
- or for filltering for all txs from one account
- and that have been 'confirmed'
- */
- getFilteredTxList (opts) {
- let filteredTxList
- Object.keys(opts).forEach((key) => {
- filteredTxList = this.getTxsByMetaData(key, opts[key], filteredTxList)
- })
- return filteredTxList
- }
-
- getTxsByMetaData (key, value, txList = this.getTxList()) {
- return txList.filter((txMeta) => {
- if (txMeta.txParams[key]) {
- return txMeta.txParams[key] === value
- } else {
- return txMeta[key] === value
- }
- })
- }
-
- // STATUS METHODS
- // get::set status
-
- // should return the status of the tx.
- getTxStatus (txId) {
- const txMeta = this.getTx(txId)
- return txMeta.status
+ this.txStateManager.updateTx(txMeta)
}
- // should update the status of the tx to 'rejected'.
- setTxStatusRejected (txId) {
- this._setTxStatus(txId, 'rejected')
- }
-
- // should update the status of the tx to 'approved'.
- setTxStatusApproved (txId) {
- this._setTxStatus(txId, 'approved')
- }
-
- // should update the status of the tx to 'signed'.
- setTxStatusSigned (txId) {
- this._setTxStatus(txId, 'signed')
- }
-
- // should update the status of the tx to 'submitted'.
- setTxStatusSubmitted (txId) {
- this._setTxStatus(txId, 'submitted')
- }
-
- // should update the status of the tx to 'confirmed'.
- setTxStatusConfirmed (txId) {
- this._setTxStatus(txId, 'confirmed')
- }
-
- setTxStatusFailed (txId, err) {
- const txMeta = this.getTx(txId)
- txMeta.err = {
- message: err.toString(),
- stack: err.stack,
- }
- this.updateTx(txMeta)
- this._setTxStatus(txId, 'failed')
- }
-
- // merges txParams obj onto txData.txParams
- // use extend to ensure that all fields are filled
- updateTxParams (txId, txParams) {
- const txMeta = this.getTx(txId)
- txMeta.txParams = extend(txMeta.txParams, txParams)
- this.updateTx(txMeta)
- }
-
-/* _____________________________________
-| |
-| PRIVATE METHODS |
-|______________________________________*/
-
-
- // Should find the tx in the tx list and
- // update it.
- // should set the status in txData
- // - `'unapproved'` the user has not responded
- // - `'rejected'` the user has responded no!
- // - `'approved'` the user has approved the tx
- // - `'signed'` the tx is signed
- // - `'submitted'` the tx is sent to a server
- // - `'confirmed'` the tx has been included in a block.
- // - `'failed'` the tx failed for some reason, included on tx data.
- _setTxStatus (txId, status) {
- const txMeta = this.getTx(txId)
- txMeta.status = status
- this.emit(`${txMeta.id}:${status}`, txId)
- if (status === 'submitted' || status === 'rejected') {
- this.emit(`${txMeta.id}:finished`, txMeta)
- }
- this.updateTx(txMeta)
- this.emit('updateBadge')
- }
-
- // Saves the new/updated txList.
- // Function is intended only for internal use
- _saveTxList (transactions) {
- this.store.updateState({ transactions })
- }
+//
+// PRIVATE METHODS
+//
_updateMemstore () {
- const unapprovedTxs = this.getUnapprovedTxList()
- const selectedAddressTxList = this.getFilteredTxList({
+ const unapprovedTxs = this.txStateManager.getUnapprovedTxList()
+ const selectedAddressTxList = this.txStateManager.getFilteredTxList({
from: this.getSelectedAddress(),
metamaskNetworkId: this.getNetwork(),
})