|
|
|
import { BN } from 'ethereumjs-util'
|
|
|
|
import { normalize } from 'eth-sig-util'
|
|
|
|
|
|
|
|
class PendingBalanceCalculator {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used for calculating a users "pending balance": their current balance minus the total possible cost of all their
|
|
|
|
* pending transactions.
|
|
|
|
*
|
|
|
|
* @typedef {Object} PendingBalanceCalculator
|
|
|
|
* @param {Function} getBalance - Returns a promise of a BN of the current balance in Wei
|
|
|
|
* @param {Function} getPendingTransactions - Returns an array of TxMeta Objects, which have txParams properties,
|
|
|
|
* which include value, gasPrice, and gas, all in a base=16 hex format.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
constructor ({ getBalance, getPendingTransactions }) {
|
|
|
|
this.getPendingTransactions = getPendingTransactions
|
|
|
|
this.getNetworkBalance = getBalance
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the users "pending balance": their current balance minus the total possible cost of all their
|
|
|
|
* pending transactions.
|
|
|
|
*
|
|
|
|
* @returns {Promise<string>} - Promises a base 16 hex string that contains the user's "pending balance"
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
async getBalance () {
|
|
|
|
const results = await Promise.all([
|
|
|
|
this.getNetworkBalance(),
|
|
|
|
this.getPendingTransactions(),
|
|
|
|
])
|
|
|
|
|
|
|
|
const [ balance, pending ] = results
|
|
|
|
if (!balance) {
|
|
|
|
return undefined
|
|
|
|
}
|
|
|
|
|
|
|
|
const pendingValue = pending.reduce((total, tx) => {
|
|
|
|
return total.add(this.calculateMaxCost(tx))
|
|
|
|
}, new BN(0))
|
|
|
|
|
|
|
|
return `0x${balance.sub(pendingValue).toString(16)}`
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculates the maximum possible cost of a single transaction, based on the value, gas price and gas limit.
|
|
|
|
*
|
|
|
|
* @param {Object} tx - Contains all that data about a transaction.
|
|
|
|
* @property {object} tx.txParams Contains data needed to calculate the maximum cost of the transaction: gas,
|
|
|
|
* gasLimit and value.
|
|
|
|
*
|
|
|
|
* @returns {string} - Returns a base 16 hex string that contains the maximum possible cost of the transaction.
|
|
|
|
*/
|
|
|
|
calculateMaxCost (tx) {
|
|
|
|
const txValue = tx.txParams.value
|
|
|
|
const value = this.hexToBn(txValue)
|
|
|
|
const gasPrice = this.hexToBn(tx.txParams.gasPrice)
|
|
|
|
|
|
|
|
const gas = tx.txParams.gas
|
|
|
|
const gasLimit = tx.txParams.gasLimit
|
|
|
|
const gasLimitBn = this.hexToBn(gas || gasLimit)
|
|
|
|
|
|
|
|
const gasCost = gasPrice.mul(gasLimitBn)
|
|
|
|
return value.add(gasCost)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts a hex string to a BN object
|
|
|
|
*
|
|
|
|
* @param {string} hex - A number represented as a hex string
|
|
|
|
* @returns {Object} - A BN object
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
hexToBn (hex) {
|
|
|
|
return new BN(normalize(hex).substring(2), 16)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export default PendingBalanceCalculator
|