aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfrankiebee <frankie.diamond@gmail.com>2018-04-20 02:29:26 +0800
committerfrankiebee <frankie.diamond@gmail.com>2018-04-20 02:46:15 +0800
commiteeb9390de81ce6fc92247d5c499e991dce8330bd (patch)
tree400f07cb6028e6e1f8ae5328d1c5544277de837f
parent943eea043cc40ea42ffe757a7115ccbc5585b37b (diff)
downloadtangerine-wallet-browser-eeb9390de81ce6fc92247d5c499e991dce8330bd.tar
tangerine-wallet-browser-eeb9390de81ce6fc92247d5c499e991dce8330bd.tar.gz
tangerine-wallet-browser-eeb9390de81ce6fc92247d5c499e991dce8330bd.tar.bz2
tangerine-wallet-browser-eeb9390de81ce6fc92247d5c499e991dce8330bd.tar.lz
tangerine-wallet-browser-eeb9390de81ce6fc92247d5c499e991dce8330bd.tar.xz
tangerine-wallet-browser-eeb9390de81ce6fc92247d5c499e991dce8330bd.tar.zst
tangerine-wallet-browser-eeb9390de81ce6fc92247d5c499e991dce8330bd.zip
meta - transactions - docs yo!
-rw-r--r--app/scripts/controllers/transactions/README.md92
-rw-r--r--app/scripts/controllers/transactions/index.js27
-rw-r--r--app/scripts/controllers/transactions/lib/tx-state-history-helper.js27
-rw-r--r--app/scripts/controllers/transactions/lib/util.js37
-rw-r--r--app/scripts/controllers/transactions/nonce-tracker.js28
-rw-r--r--app/scripts/controllers/transactions/pending-tx-tracker.js10
-rw-r--r--app/scripts/controllers/transactions/tx-gas-utils.js1
-rw-r--r--app/scripts/controllers/transactions/tx-state-manager.js202
-rw-r--r--docs/transaction-flow.pngbin0 -> 141125 bytes
9 files changed, 351 insertions, 73 deletions
diff --git a/app/scripts/controllers/transactions/README.md b/app/scripts/controllers/transactions/README.md
new file mode 100644
index 000000000..ea38b5ae6
--- /dev/null
+++ b/app/scripts/controllers/transactions/README.md
@@ -0,0 +1,92 @@
+# Transaction Controller
+
+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
+
+## flow digram of processing a transaction
+
+![transaction-flow](../../../../docs/transaction-flow.png)
+
+## txMeta's && txParams
+
+A txMeta is the "meta" object it has all the random bits of info we need about a transaction on it. txParams are sacred every thing on txParams gets signed so it must
+be a valid key and be hex prefixed except for the network number. Extra stuff must go on the txMeta!
+
+Here is a txMeta too look at:
+
+```js
+txMeta = {
+ "id": 2828415030114568, // unique id for this txMeta used for look ups
+ "time": 1524094064821, // time of creation
+ "status": "confirmed",
+ "metamaskNetworkId": "1524091532133", //the network id for the transaction
+ "loadingDefaults": false, // used to tell the ui when we are done calculatyig gass defaults
+ "txParams": { // the txParams object
+ "from": "0x8acce2391c0d510a6c5e5d8f819a678f79b7e675",
+ "to": "0x8acce2391c0d510a6c5e5d8f819a678f79b7e675",
+ "value": "0x0",
+ "gasPrice": "0x3b9aca00",
+ "gas": "0x7b0c",
+ "nonce": "0x0"
+ },
+ "history": [{ //debug
+ "id": 2828415030114568,
+ "time": 1524094064821,
+ "status": "unapproved",
+ "metamaskNetworkId": "1524091532133",
+ "loadingDefaults": true,
+ "txParams": {
+ "from": "0x8acce2391c0d510a6c5e5d8f819a678f79b7e675",
+ "to": "0x8acce2391c0d510a6c5e5d8f819a678f79b7e675",
+ "value": "0x0"
+ }
+ },
+ [
+ {
+ "op": "add",
+ "path": "/txParams/gasPrice",
+ "value": "0x3b9aca00"
+ },
+ ...], // I've removed most of history for this
+ "gasPriceSpecified": false, //weather or not the user/dapp has specified gasPrice
+ "gasLimitSpecified": false, //weather or not the user/dapp has specified gas
+ "estimatedGas": "5208",
+ "origin": "MetaMask", //debug
+ "nonceDetails": {
+ "params": {
+ "highestLocallyConfirmed": 0,
+ "highestSuggested": 0,
+ "nextNetworkNonce": 0
+ },
+ "local": {
+ "name": "local",
+ "nonce": 0,
+ "details": {
+ "startPoint": 0,
+ "highest": 0
+ }
+ },
+ "network": {
+ "name": "network",
+ "nonce": 0,
+ "details": {
+ "baseCount": 0
+ }
+ }
+ },
+ "rawTx": "0xf86980843b9aca00827b0c948acce2391c0d510a6c5e5d8f819a678f79b7e67580808602c5b5de66eea05c01a320b96ac730cb210ca56d2cb71fa360e1fc2c21fa5cf333687d18eb323fa02ed05987a6e5fd0f2459fcff80710b76b83b296454ad9a37594a0ccb4643ea90", // used for rebroadcast
+ "hash": "0xa45ba834b97c15e6ff4ed09badd04ecd5ce884b455eb60192cdc73bcc583972a",
+ "submittedTime": 1524094077902 // time of the attempt to submit the raw tx to the network, used in the ui to show the retry button
+}
+```
diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js
index c81251cd2..d7287450b 100644
--- a/app/scripts/controllers/transactions/index.js
+++ b/app/scripts/controllers/transactions/index.js
@@ -25,14 +25,15 @@ const txUtils = require('./lib/util')
@param {object} opts -
- - initState, initial transaction list default is an empty array<br>
- - networkStore, an observable store for network number<br>
- - blockTracker,<br>
- - provider,<br>
- - signTransaction, function the signs an ethereumjs-tx<br>
- - getGasPrice, optional gas price calculator<br>
- - txHistoryLimit, number *optional* for limiting how many transactions are in state <br>
- - preferencesStore,
+ @property {object} opts.initState initial transaction list default is an empty array
+ @property {Object} opts.networkStore an observable store for network number
+ @property {Object} opts.blockTracker
+ @property {Object} opts.provider
+ @property {Object} opts.signTransaction function the signs an ethereumjs-tx
+ @property {function} opts.getGasPrice optional gas price calculator
+ @property {function} opts.signTransaction ethTx signer that returns a rawTx
+ @property {number} opts.txHistoryLimit number *optional* for limiting how many transactions are in state
+ @property {Object} opts.preferencesStore
@class
*/
@@ -50,12 +51,12 @@ class TransactionController extends EventEmitter {
this.query = new EthQuery(this.provider)
this.txGasUtil = new TxGasUtil(this.provider)
+ this._mapMethods()
this.txStateManager = new TransactionStateManager({
initState: opts.initState,
txHistoryLimit: opts.txHistoryLimit,
getNetwork: this.getNetwork.bind(this),
})
- this._mapMethods()
this._onBootCleanUp()
this.store = this.txStateManager.store
@@ -92,7 +93,10 @@ class TransactionController extends EventEmitter {
}
}
-/** Adds a tx to the txlist */
+/**
+ Adds a tx to the txlist
+ @emits ${txMeta.id}:unapproved
+*/
addTx (txMeta) {
this.txStateManager.addTx(txMeta)
this.emit(`${txMeta.id}:unapproved`, txMeta)
@@ -172,6 +176,7 @@ add a new unapproved transaction to the pipeline
async addTxGasDefaults (txMeta) {
const txParams = txMeta.txParams
// ensure value
+ txParams.value = txParams.value ? ethUtil.addHexPrefix(value) : '0x0',
txMeta.gasPriceSpecified = Boolean(txParams.gasPrice)
let gasPrice = txParams.gasPrice
if (!gasPrice) {
@@ -412,4 +417,4 @@ add a new unapproved transaction to the pipeline
}
}
-module.exports = TransactionController \ No newline at end of file
+module.exports = TransactionController
diff --git a/app/scripts/controllers/transactions/lib/tx-state-history-helper.js b/app/scripts/controllers/transactions/lib/tx-state-history-helper.js
index 94c7b6792..7a57e3cb5 100644
--- a/app/scripts/controllers/transactions/lib/tx-state-history-helper.js
+++ b/app/scripts/controllers/transactions/lib/tx-state-history-helper.js
@@ -1,6 +1,6 @@
const jsonDiffer = require('fast-json-patch')
const clone = require('clone')
-
+/** @module*/
module.exports = {
generateHistoryEntry,
replayHistory,
@@ -8,7 +8,11 @@ module.exports = {
migrateFromSnapshotsToDiffs,
}
-
+/**
+ converts non-initial history entries into diffs
+ @param longHistory {array}
+ @returns {array}
+*/
function migrateFromSnapshotsToDiffs (longHistory) {
return (
longHistory
@@ -20,6 +24,17 @@ function migrateFromSnapshotsToDiffs (longHistory) {
)
}
+/**
+ generates an array of history objects sense the previous state.
+ The object has the keys opp(the operation preformed),
+ path(the key and if a nested object then each key will be seperated with a `/`)
+ value
+ with the first entry having the note
+ @param previousState {object} - the previous state of the object
+ @param newState {object} - the update object
+ @param note {string} - a optional note for the state change
+ @reurns {array}
+*/
function generateHistoryEntry (previousState, newState, note) {
const entry = jsonDiffer.compare(previousState, newState)
// Add a note to the first op, since it breaks if we append it to the entry
@@ -27,11 +42,19 @@ function generateHistoryEntry (previousState, newState, note) {
return entry
}
+/**
+ Recovers previous txMeta state obj
+ @return {object}
+*/
function replayHistory (_shortHistory) {
const shortHistory = clone(_shortHistory)
return shortHistory.reduce((val, entry) => jsonDiffer.applyPatch(val, entry).newDocument)
}
+/**
+ @param txMeta {object}
+ @returns {object} a clone object of the txMeta with out history
+*/
function snapshotFromTxMeta (txMeta) {
// create txMeta snapshot for history
const snapshot = clone(txMeta)
diff --git a/app/scripts/controllers/transactions/lib/util.js b/app/scripts/controllers/transactions/lib/util.js
index b18283997..84f7592a0 100644
--- a/app/scripts/controllers/transactions/lib/util.js
+++ b/app/scripts/controllers/transactions/lib/util.js
@@ -3,11 +3,15 @@ const {
isValidAddress,
} = require('ethereumjs-util')
+/**
+@module
+*/
module.exports = {
normalizeTxParams,
validateTxParams,
validateFrom,
validateRecipient,
+ getFinalStates,
}
@@ -16,22 +20,30 @@ const normalizers = {
from: from => addHexPrefix(from).toLowerCase(),
to: to => addHexPrefix(to).toLowerCase(),
nonce: nonce => addHexPrefix(nonce),
- value: value => value ? addHexPrefix(value) : '0x0',
+ value: value => addHexPrefix(value),
data: data => addHexPrefix(data),
gas: gas => addHexPrefix(gas),
gasPrice: gasPrice => addHexPrefix(gasPrice),
}
+
/**
+ normalizes txParams
+ @param txParams {object}
+ @returns {object} normalized txParams
*/
function normalizeTxParams (txParams) {
// apply only keys in the normalizers
const normalizedTxParams = {}
- for (let key in normalizers) {
+ for (const key in normalizers) {
if (txParams[key]) normalizedTxParams[key] = normalizers[key](txParams[key])
}
return normalizedTxParams
}
+ /**
+ validates txParams
+ @param txParams {object}
+ */
function validateTxParams (txParams) {
validateFrom(txParams)
validateRecipient(txParams)
@@ -47,11 +59,19 @@ function validateTxParams (txParams) {
}
}
+ /**
+ validates the from field in txParams
+ @param txParams {object}
+ */
function validateFrom (txParams) {
if (!(typeof txParams.from === 'string')) throw new Error(`Invalid from address ${txParams.from} not a string`)
if (!isValidAddress(txParams.from)) throw new Error('Invalid from address')
}
+ /**
+ validates the to field in txParams
+ @param txParams {object}
+ */
function validateRecipient (txParams) {
if (txParams.to === '0x' || txParams.to === null) {
if (txParams.data) {
@@ -64,3 +84,16 @@ function validateRecipient (txParams) {
}
return txParams
}
+
+ /**
+ @returns an {array} of states that can be considered final
+ */
+function getFinalStates () {
+ return [
+ 'rejected', // the user has responded no!
+ 'confirmed', // the tx has been included in a block.
+ 'failed', // the tx failed for some reason, included on tx data.
+ 'dropped', // the tx nonce was already used
+ ]
+}
+
diff --git a/app/scripts/controllers/transactions/nonce-tracker.js b/app/scripts/controllers/transactions/nonce-tracker.js
index 5b1cd7f43..e0f4d0fe3 100644
--- a/app/scripts/controllers/transactions/nonce-tracker.js
+++ b/app/scripts/controllers/transactions/nonce-tracker.js
@@ -1,7 +1,15 @@
const EthQuery = require('ethjs-query')
const assert = require('assert')
const Mutex = require('await-semaphore').Mutex
-
+/**
+ @param opts {object} -
+ @property {Object} opts.provider a ethereum provider
+ @property {function} opts.getPendingTransactions a function that returns an array of txMeta
+ whos status is `submitted`
+ @property {function} opts.getConfirmedTransactions a function that returns an array of txMeta
+ whos status is `confirmed`
+ @class
+*/
class NonceTracker {
constructor ({ provider, getPendingTransactions, getConfirmedTransactions }) {
@@ -12,6 +20,9 @@ class NonceTracker {
this.lockMap = {}
}
+ /**
+ @returns {object} with the key releaseLock (the gloabl mutex)
+ */
async getGlobalLock () {
const globalMutex = this._lookupMutex('global')
// await global mutex free
@@ -19,8 +30,19 @@ class NonceTracker {
return { releaseLock }
}
- // releaseLock must be called
- // releaseLock must be called after adding signed tx to pending transactions (or discarding)
+ /**
+ this will return an object with the `nextNonce` `nonceDetails` which is an
+ object with:
+ highestLocallyConfirmed (nonce),
+ highestSuggested (either the network nonce or the highestLocallyConfirmed nonce),
+ nextNetworkNonce (the nonce suggested by the network),
+ and the releaseLock
+ <br>note: releaseLock must be called after adding signed tx to pending transactions
+ (or discarding)<br>
+
+ @param address {string} the hex string for the address whos nonce we are calculating
+ @returns {object}
+ */
async getNonceLock (address) {
// await global mutex free
await this._globalMutexFree()
diff --git a/app/scripts/controllers/transactions/pending-tx-tracker.js b/app/scripts/controllers/transactions/pending-tx-tracker.js
index 503343e22..98b3d2b08 100644
--- a/app/scripts/controllers/transactions/pending-tx-tracker.js
+++ b/app/scripts/controllers/transactions/pending-tx-tracker.js
@@ -8,10 +8,10 @@ const EthQuery = require('ethjs-query')
As well as continues broadcast while in the pending state
<br>
@param config {object} - non optional configuration object consists of:
- <br>provider
- <br>nonceTracker: see nonce tracker
- <br>getPendingTransactions: a function for getting an array of transactions,
- <br>publishTransaction: a async function for publishing raw transactions,
+ @property {Object} config.provider
+ @property {Object} config.nonceTracker see nonce tracker
+ @property {function} config.getPendingTransactions a function for getting an array of transactions,
+ @property {function} config.publishTransaction a async function for publishing raw transactions,
@class
@@ -220,4 +220,4 @@ class PendingTransactionTracker extends EventEmitter {
}
}
-module.exports = PendingTransactionTracker \ No newline at end of file
+module.exports = PendingTransactionTracker
diff --git a/app/scripts/controllers/transactions/tx-gas-utils.js b/app/scripts/controllers/transactions/tx-gas-utils.js
index 1a7ff5b54..31a5bfcf4 100644
--- a/app/scripts/controllers/transactions/tx-gas-utils.js
+++ b/app/scripts/controllers/transactions/tx-gas-utils.js
@@ -11,6 +11,7 @@ const SIMPLE_GAS_COST = '0x5208' // Hex for 21000, cost of a simple send.
tx-utils are utility methods for Transaction manager
its passed ethquery
and used to do things like calculate gas of a tx.
+@param provider {object}
*/
module.exports = class TxGasUtil {
diff --git a/app/scripts/controllers/transactions/tx-state-manager.js b/app/scripts/controllers/transactions/tx-state-manager.js
index f898cc44a..328024925 100644
--- a/app/scripts/controllers/transactions/tx-state-manager.js
+++ b/app/scripts/controllers/transactions/tx-state-manager.js
@@ -1,22 +1,33 @@
const extend = require('xtend')
const EventEmitter = require('events')
const ObservableStore = require('obs-store')
-const createId = require('../../lib/random-id')
const ethUtil = require('ethereumjs-util')
const txStateHistoryHelper = require('./lib/tx-state-history-helper')
-
-// STATUS METHODS
- // statuses:
- // - `'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.
- // - `'dropped'` the tx nonce was already used
-
-module.exports = class TransactionStateManager extends EventEmitter {
+const createId = require('../../lib/random-id')
+const { getFinalStates } = require('./lib/util')
+/**
+ TransactionStateManager is responsible for the state of a transaction and
+ storing the transaction
+ it also has some convenience methods for finding subsets of transactions
+ *
+ *STATUS METHODS
+ <br>statuses:
+ <br> - `'unapproved'` the user has not responded
+ <br> - `'rejected'` the user has responded no!
+ <br> - `'approved'` the user has approved the tx
+ <br> - `'signed'` the tx is signed
+ <br> - `'submitted'` the tx is sent to a server
+ <br> - `'confirmed'` the tx has been included in a block.
+ <br> - `'failed'` the tx failed for some reason, included on tx data.
+ <br> - `'dropped'` the tx nonce was already used
+ @param opts {object} -
+ @property {object} opts.initState with the key transaction {array}
+ @property {number} opts.txHistoryLimit limit for how many finished
+ transactions can hang around in state
+ @property {function} opts.getNetwork return network number
+ @class
+*/
+class TransactionStateManager extends EventEmitter {
constructor ({ initState, txHistoryLimit, getNetwork }) {
super()
@@ -28,6 +39,10 @@ module.exports = class TransactionStateManager extends EventEmitter {
this.getNetwork = getNetwork
}
+ /**
+ @param opts {object} - the object to use when overwriting defaults
+ @returns {txMeta} the default txMeta object
+ */
generateTxMeta (opts) {
return extend({
id: createId(),
@@ -38,17 +53,25 @@ module.exports = class TransactionStateManager extends EventEmitter {
}, opts)
}
+ /**
+ @returns {array} of txMetas that have been filtered for only the current network
+ */
getTxList () {
const network = this.getNetwork()
const fullTxList = this.getFullTxList()
return fullTxList.filter((txMeta) => txMeta.metamaskNetworkId === network)
}
+ /**
+ @returns {array} of all the txMetas in store
+ */
getFullTxList () {
return this.store.getState().transactions
}
- // Returns the tx list
+ /**
+ @returns {array} the tx list whos status is unapproved
+ */
getUnapprovedTxList () {
const txList = this.getTxsByMetaData('status', 'unapproved')
return txList.reduce((result, tx) => {
@@ -57,18 +80,35 @@ module.exports = class TransactionStateManager extends EventEmitter {
}, {})
}
+ /**
+ @param address {string} - hex prefixed address to sort the txMetas for [optional]
+ @returns {array} the tx list whos status is submitted
+ */
getPendingTransactions (address) {
const opts = { status: 'submitted' }
if (address) opts.from = address
return this.getFilteredTxList(opts)
}
+ /**
+ @param address {string} - hex prefixed address to sort the txMetas for [optional]
+ @returns {array} the tx list whos status is confirmed
+ */
getConfirmedTransactions (address) {
const opts = { status: 'confirmed' }
if (address) opts.from = address
return this.getFilteredTxList(opts)
}
+ /**
+ Adds the txMeta to the list of transactions in the store.
+ if the list is over txHistoryLimit it will remove a transaction that
+ is in its final state
+ it will allso add the key `history` to the txMeta with the snap shot of the original
+ object
+ @param txMeta {object}
+ @returns {object} the txMeta
+ */
addTx (txMeta) {
this.once(`${txMeta.id}:signed`, function (txId) {
this.removeAllListeners(`${txMeta.id}:rejected`)
@@ -93,7 +133,7 @@ module.exports = class TransactionStateManager extends EventEmitter {
// not tx's that are pending or unapproved
if (txCount > txHistoryLimit - 1) {
const index = transactions.findIndex((metaTx) => {
- return this.getFinalStates().includes(metaTx.status)
+ return getFinalStates().includes(metaTx.status)
})
if (index !== -1) {
transactions.splice(index, 1)
@@ -103,12 +143,21 @@ module.exports = class TransactionStateManager extends EventEmitter {
this._saveTxList(transactions)
return txMeta
}
- // gets tx by Id and returns it
+ /**
+ @param txId {number}
+ @returns {object} the txMeta who matches the given id if none found
+ for the network returns undefined
+ */
getTx (txId) {
const txMeta = this.getTxsByMetaData('id', txId)[0]
return txMeta
}
+ /**
+ updates the txMeta in the list and adds a history entry
+ @param txMeta {object} - the txMeta to update
+ @param note {string} - a not about the update for history
+ */
updateTx (txMeta, note) {
// validate txParams
if (txMeta.txParams) {
@@ -136,15 +185,22 @@ module.exports = class TransactionStateManager extends EventEmitter {
}
- // merges txParams obj onto txData.txParams
- // use extend to ensure that all fields are filled
+ /**
+ merges txParams obj onto txMeta.txParams
+ use extend to ensure that all fields are filled
+ @param txId {number} - the id of the txMeta
+ @param txParams {object} - the updated txParams
+ */
updateTxParams (txId, txParams) {
const txMeta = this.getTx(txId)
txMeta.txParams = extend(txMeta.txParams, txParams)
this.updateTx(txMeta, `txStateManager#updateTxParams`)
}
- // validates txParams members by type
+ /**
+ validates txParams members by type
+ @param txParams {object} - txParams to validate
+ */
validateTxParams (txParams) {
Object.keys(txParams).forEach((key) => {
const value = txParams[key]
@@ -161,17 +217,18 @@ module.exports = class TransactionStateManager extends EventEmitter {
})
}
-/*
- 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
+/**
+ @param opts {object} - an object of fields to search for eg:<br>
+ let <code>thingsToLookFor = {<br>
+ to: '0x0..',<br>
+ from: '0x0..',<br>
+ status: 'signed',<br>
+ err: undefined,<br>
+ }<br></code>
+ @returns a {array} of txMeta with all
options matching
-
+ */
+ /*
****************HINT****************
| `err: undefined` is like looking |
| for a tx with no err |
@@ -192,7 +249,14 @@ module.exports = class TransactionStateManager extends EventEmitter {
})
return filteredTxList
}
+ /**
+ @param key {string} - the key to check
+ @param value - the value your looking for
+ @param txList {array} - [optional] the list to search. default is the txList
+ from txStateManager#getTxList
+ @returns {array} a list of txMetas who matches the search params
+ */
getTxsByMetaData (key, value, txList = this.getTxList()) {
return txList.filter((txMeta) => {
if (txMeta.txParams[key]) {
@@ -205,33 +269,51 @@ module.exports = class TransactionStateManager extends EventEmitter {
// get::set status
- // should return the status of the tx.
+ /**
+ @param txId {number} - the txMeta Id
+ @return {string} the status of the tx.
+ */
getTxStatus (txId) {
const txMeta = this.getTx(txId)
return txMeta.status
}
- // should update the status of the tx to 'rejected'.
+ /**
+ should update the status of the tx to 'rejected'.
+ @param txId {number} - the txMeta Id
+ */
setTxStatusRejected (txId) {
this._setTxStatus(txId, 'rejected')
}
- // should update the status of the tx to 'unapproved'.
+ /**
+ should update the status of the tx to 'unapproved'.
+ @param txId {number} - the txMeta Id
+ */
setTxStatusUnapproved (txId) {
this._setTxStatus(txId, 'unapproved')
}
- // should update the status of the tx to 'approved'.
+ /**
+ should update the status of the tx to 'approved'.
+ @param txId {number} - the txMeta Id
+ */
setTxStatusApproved (txId) {
this._setTxStatus(txId, 'approved')
}
- // should update the status of the tx to 'signed'.
+ /**
+ should update the status of the tx to 'signed'.
+ @param txId {number} - the txMeta Id
+ */
setTxStatusSigned (txId) {
this._setTxStatus(txId, 'signed')
}
- // should update the status of the tx to 'submitted'.
- // and add a time stamp for when it was called
+ /**
+ should update the status of the tx to 'submitted'.
+ and add a time stamp for when it was called
+ @param txId {number} - the txMeta Id
+ */
setTxStatusSubmitted (txId) {
const txMeta = this.getTx(txId)
txMeta.submittedTime = (new Date()).getTime()
@@ -239,17 +321,29 @@ module.exports = class TransactionStateManager extends EventEmitter {
this._setTxStatus(txId, 'submitted')
}
- // should update the status of the tx to 'confirmed'.
+ /**
+ should update the status of the tx to 'confirmed'.
+ @param txId {number} - the txMeta Id
+ */
setTxStatusConfirmed (txId) {
this._setTxStatus(txId, 'confirmed')
}
- // should update the status dropped
+ /**
+ should update the status of the tx to 'dropped'.
+ @param txId {number} - the txMeta Id
+ */
setTxStatusDropped (txId) {
this._setTxStatus(txId, 'dropped')
}
+ /**
+ should update the status of the tx to 'failed'.
+ and put the error on the txMeta
+ @param txId {number} - the txMeta Id
+ @param err {erroObject} - error object
+ */
setTxStatusFailed (txId, err) {
const txMeta = this.getTx(txId)
txMeta.err = {
@@ -260,16 +354,11 @@ module.exports = class TransactionStateManager extends EventEmitter {
this._setTxStatus(txId, 'failed')
}
- // returns an array of states that can be considered final
- getFinalStates () {
- return [
- 'rejected', // the user has responded no!
- 'confirmed', // the tx has been included in a block.
- 'failed', // the tx failed for some reason, included on tx data.
- 'dropped', // the tx nonce was already used
- ]
- }
-
+ /**
+ Removes transaction from the given address for the current network
+ from the txList
+ @param address {string} - hex string of the from address on the txParams to remove
+ */
wipeTransactions (address) {
// network only tx
const txs = this.getFullTxList()
@@ -295,6 +384,14 @@ module.exports = class TransactionStateManager extends EventEmitter {
// - `'confirmed'` the tx has been included in a block.
// - `'failed'` the tx failed for some reason, included on tx data.
// - `'dropped'` the tx nonce was already used
+
+ /**
+ @param txId {number} - the txMeta Id
+ @param status {string} - the status to set on the txMeta
+ @emits tx:status-update - passes txId and status
+ @emits ${txMeta.id}:finished - if it is a finished state. Passes the txMeta
+ @emits update:badge
+ */
_setTxStatus (txId, status) {
const txMeta = this.getTx(txId)
txMeta.status = status
@@ -307,9 +404,14 @@ module.exports = class TransactionStateManager extends EventEmitter {
this.emit('update:badge')
}
- // Saves the new/updated txList.
+ /**
+ Saves the new/updated txList.
+ @param transactions {array} - the list of transactions to save
+ */
// Function is intended only for internal use
_saveTxList (transactions) {
this.store.updateState({ transactions })
}
}
+
+module.exports = TransactionStateManager
diff --git a/docs/transaction-flow.png b/docs/transaction-flow.png
new file mode 100644
index 000000000..1059b60d8
--- /dev/null
+++ b/docs/transaction-flow.png
Binary files differ