1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 19:26:13 +02:00
metamask-extension/app/scripts/transaction-manager.js
Frances Pangilinan 090935f90a Create a TxManager
2016-12-14 12:55:41 -08:00

180 lines
4.4 KiB
JavaScript

const EventEmitter = require('events')
const extend = require('xtend')
const TxProviderUtil = require('./lib/provider-utils')
module.exports = class TransactionManager extends EventEmitter {
constructor (opts) {
super()
this.txList = opts.TxListFromStore || []
this._persistTxList = opts.setTxList
this._unconfTxCbs = {}
this.txLimit = opts.txLimit
this.provider = opts.provider
}
// Returns the tx list
getTxList () {
return this.txList
}
// Saves the new/updated txList.
// Function is intended only for internal use
_saveTxList (txList) {
this.txList = txList
this._persistTxList(txList)
}
// Adds a tx to the txlist
addTx (txData, onTxDoneCb) {
var txList = this.getTxList()
var txLimit = this.txLimit
if (txList.length > txLimit - 1) {
txList.shift()
}
txList.push(txData)
this._saveTxList(txList)
this.addOnTxDoneCb(txData.id, onTxDoneCb)
this.emit('unapproved', txData)
this.emit('update')
}
getTx (txId, cb) {
var txList = this.getTxList()
var tx = txList.find((tx) => tx.id === txId)
return cb ? cb(tx) : tx
}
updateTx (txData) {
var txId = txData.id
var txList = this.getTxList()
var updatedTxList = txList.map((tx) => {
if (tx.id === txId) {
tx = txData
}
return tx
})
this._saveTxList(updatedTxList)
}
get unConftxCount () {
return Object.keys(this.getUnapprovedTxList()).length
}
get pendingTxCount () {
return this.getTxsByMetaData('status', 'signed').length
}
getUnapprovedTxList () {
var txList = this.getTxList()
return txList.filter((tx) => {
return tx.status === 'unapproved'
}).reduce((result, tx) => {
result[tx.id] = tx
return result
}, {})
}
getFilterdTxList (opts) {
var filteredTxList
Object.keys(opts).forEach((key) => {
filteredTxList = this.getTxsByMetaData(key, opts[key], filteredTxList)
})
return filteredTxList
}
getTxsByMetaData (key, value, txList = this.getTxList()) {
return txList.filter((tx) => {
if (key in tx.txParams) {
return tx.txParams[key] === value
} else {
return tx[key] === value
}
})
}
addOnTxDoneCb (txId, cb) {
this._unconfTxCbs[txId] = cb || noop
}
// should return the tx
// 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!
// // - `'signed'` the tx is signed
// // - `'submitted'` the tx is sent to a server
// // - `'confirmed'` the tx has been included in a block.
setTxStatus (txId, status) {
var txData = this.getTx(txId)
txData.status = status
this.emit(status, txId)
this.updateTx(txData, status)
}
// should return the status of the tx.
getTxStatus (txId, cb) {
const txData = this.getTx(txId)
return cb ? cb(txData.staus) : txData.status
}
// should update the status of the tx to 'signed'.
setTxStatusSigned (txId) {
this.setTxStatus(txId, 'signed')
this.emit('update')
}
// should update the status of the tx to 'rejected'.
setTxStatusRejected (txId) {
this.setTxStatus(txId, 'rejected')
this.emit('update')
}
setTxStatusConfirmed (txId) {
this.setTxStatus(txId, 'confirmed')
// this.removeListener(`check${txId}`, this.checkForTxInBlock)
}
// merges txParams obj onto txData.txParams
// use extend to ensure that all fields are filled
updateTxParams (txId, txParams) {
var txData = this.getTx(txId)
txData.txParams = extend(txData, txParams)
this.updateTx(txData)
}
setProvider (provider) {
this.provider = provider
this.txProviderUtils = new TxProviderUtil(provider)
this.provider.on('block', this.checkForTxInBlock.bind(this))
}
checkForTxInBlock () {
var signedTxList = this.getFilterdTxList({status: 'signed'})
if (!signedTxList.length) return
var self = this
signedTxList.forEach((tx) => {
var txHash = tx.hash
var txId = tx.id
if (!txHash) return
// var d
this.txProviderUtils.query.getTransactionByHash(txHash, (err, txData) => {
if (err) {
tx
return console.error(err)
}
if (txData.blockNumber !== null) {
self.setTxStatusConfirmed(txId)
}
})
})
}
}
function noop () {}