aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'ui/app/helpers')
-rw-r--r--ui/app/helpers/confirm-transaction/util.js27
-rw-r--r--ui/app/helpers/confirm-transaction/util.test.js6
-rw-r--r--ui/app/helpers/conversions.util.js63
-rw-r--r--ui/app/helpers/tests/transactions.util.test.js22
-rw-r--r--ui/app/helpers/transactions.util.js122
-rw-r--r--ui/app/helpers/with-token-tracker.js108
6 files changed, 213 insertions, 135 deletions
diff --git a/ui/app/helpers/confirm-transaction/util.js b/ui/app/helpers/confirm-transaction/util.js
index 76e80a8ac..bcac22500 100644
--- a/ui/app/helpers/confirm-transaction/util.js
+++ b/ui/app/helpers/confirm-transaction/util.js
@@ -1,15 +1,8 @@
import currencyFormatter from 'currency-formatter'
import currencies from 'currency-formatter/currencies'
-import abi from 'human-standard-token-abi'
-import abiDecoder from 'abi-decoder'
import ethUtil from 'ethereumjs-util'
import BigNumber from 'bignumber.js'
-abiDecoder.addABI(abi)
-
-import MethodRegistry from 'eth-method-registry'
-const registry = new MethodRegistry({ provider: global.ethereumProvider })
-
import {
conversionUtil,
addCurrencies,
@@ -19,22 +12,6 @@ import {
import { unconfirmedTransactionsCountSelector } from '../../selectors/confirm-transaction'
-export function getTokenData (data = {}) {
- return abiDecoder.decodeMethod(data)
-}
-
-export async function getMethodData (data = {}) {
- const prefixedData = ethUtil.addHexPrefix(data)
- const fourBytePrefix = prefixedData.slice(0, 10)
- const sig = await registry.lookup(fourBytePrefix)
- const parsedResult = registry.parse(sig)
-
- return {
- name: parsedResult.name,
- params: parsedResult.args,
- }
-}
-
export function increaseLastGasPrice (lastGasPrice) {
return ethUtil.addHexPrefix(multiplyCurrencies(lastGasPrice, 1.1, {
multiplicandBase: 16,
@@ -76,11 +53,12 @@ export function addFiat (...args) {
})
}
-export function getTransactionAmount ({
+export function getValueFromWeiHex ({
value,
toCurrency,
conversionRate,
numberOfDecimals,
+ toDenomination,
}) {
return conversionUtil(value, {
fromNumericBase: 'hex',
@@ -89,6 +67,7 @@ export function getTransactionAmount ({
toCurrency,
numberOfDecimals,
fromDenomination: 'WEI',
+ toDenomination,
conversionRate,
})
}
diff --git a/ui/app/helpers/confirm-transaction/util.test.js b/ui/app/helpers/confirm-transaction/util.test.js
index a9c8fae34..4c1a3e16b 100644
--- a/ui/app/helpers/confirm-transaction/util.test.js
+++ b/ui/app/helpers/confirm-transaction/util.test.js
@@ -92,9 +92,9 @@ describe('Confirm Transaction utils', () => {
})
})
- describe('getTransactionAmount', () => {
+ describe('getValueFromWeiHex', () => {
it('should get the transaction amount in ETH', () => {
- const ethTransactionAmount = utils.getTransactionAmount({
+ const ethTransactionAmount = utils.getValueFromWeiHex({
value: '0xde0b6b3a7640000', toCurrency: 'ETH', conversionRate: 468.58, numberOfDecimals: 6,
})
@@ -102,7 +102,7 @@ describe('Confirm Transaction utils', () => {
})
it('should get the transaction amount in fiat', () => {
- const fiatTransactionAmount = utils.getTransactionAmount({
+ const fiatTransactionAmount = utils.getValueFromWeiHex({
value: '0xde0b6b3a7640000', toCurrency: 'usd', conversionRate: 468.58, numberOfDecimals: 2,
})
diff --git a/ui/app/helpers/conversions.util.js b/ui/app/helpers/conversions.util.js
new file mode 100644
index 000000000..20ef9e35b
--- /dev/null
+++ b/ui/app/helpers/conversions.util.js
@@ -0,0 +1,63 @@
+import ethUtil from 'ethereumjs-util'
+import { conversionUtil } from '../conversion-util'
+import { ETH, GWEI, WEI } from '../constants/common'
+
+export function bnToHex (inputBn) {
+ return ethUtil.addHexPrefix(inputBn.toString(16))
+}
+
+export function hexToDecimal (hexValue) {
+ return conversionUtil(hexValue, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ })
+}
+
+export function decimalToHex (decimal) {
+ return conversionUtil(decimal, {
+ fromNumericBase: 'dec',
+ toNumericBase: 'hex',
+ })
+}
+
+export function getEthConversionFromWeiHex ({ value, conversionRate, numberOfDecimals = 6 }) {
+ const denominations = [ETH, GWEI, WEI]
+
+ let nonZeroDenomination
+
+ for (let i = 0; i < denominations.length; i++) {
+ const convertedValue = getValueFromWeiHex({
+ value,
+ conversionRate,
+ toCurrency: ETH,
+ numberOfDecimals,
+ toDenomination: denominations[i],
+ })
+
+ if (convertedValue !== '0' || i === denominations.length - 1) {
+ nonZeroDenomination = `${convertedValue} ${denominations[i]}`
+ break
+ }
+ }
+
+ return nonZeroDenomination
+}
+
+export function getValueFromWeiHex ({
+ value,
+ toCurrency,
+ conversionRate,
+ numberOfDecimals,
+ toDenomination,
+}) {
+ return conversionUtil(value, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromCurrency: ETH,
+ toCurrency,
+ numberOfDecimals,
+ fromDenomination: WEI,
+ toDenomination,
+ conversionRate,
+ })
+}
diff --git a/ui/app/helpers/tests/transactions.util.test.js b/ui/app/helpers/tests/transactions.util.test.js
new file mode 100644
index 000000000..103a84a8c
--- /dev/null
+++ b/ui/app/helpers/tests/transactions.util.test.js
@@ -0,0 +1,22 @@
+import * as utils from '../transactions.util'
+import assert from 'assert'
+
+describe('Transactions utils', () => {
+ describe('getTokenData', () => {
+ it('should return token data', () => {
+ const tokenData = utils.getTokenData('0xa9059cbb00000000000000000000000050a9d56c2b8ba9a5c7f2c08c3d26e0499f23a7060000000000000000000000000000000000000000000000000000000000004e20')
+ assert.ok(tokenData)
+ const { name, params } = tokenData
+ assert.equal(name, 'transfer')
+ const [to, value] = params
+ assert.equal(to.name, '_to')
+ assert.equal(to.type, 'address')
+ assert.equal(value.name, '_value')
+ assert.equal(value.type, 'uint256')
+ })
+
+ it('should not throw errors when called without arguments', () => {
+ assert.doesNotThrow(() => utils.getTokenData())
+ })
+ })
+})
diff --git a/ui/app/helpers/transactions.util.js b/ui/app/helpers/transactions.util.js
new file mode 100644
index 000000000..8b87bb538
--- /dev/null
+++ b/ui/app/helpers/transactions.util.js
@@ -0,0 +1,122 @@
+import ethUtil from 'ethereumjs-util'
+import MethodRegistry from 'eth-method-registry'
+import abi from 'human-standard-token-abi'
+import abiDecoder from 'abi-decoder'
+
+import {
+ TOKEN_METHOD_TRANSFER,
+ TOKEN_METHOD_APPROVE,
+ TOKEN_METHOD_TRANSFER_FROM,
+ SEND_ETHER_ACTION_KEY,
+ DEPLOY_CONTRACT_ACTION_KEY,
+ APPROVE_ACTION_KEY,
+ SEND_TOKEN_ACTION_KEY,
+ TRANSFER_FROM_ACTION_KEY,
+ SIGNATURE_REQUEST_KEY,
+ UNKNOWN_FUNCTION_KEY,
+ CANCEL_ATTEMPT_ACTION_KEY,
+} from '../constants/transactions'
+
+import { addCurrencies } from '../conversion-util'
+
+abiDecoder.addABI(abi)
+
+export function getTokenData (data = '') {
+ return abiDecoder.decodeMethod(data)
+}
+
+const registry = new MethodRegistry({ provider: global.ethereumProvider })
+
+export async function getMethodData (data = '') {
+ const prefixedData = ethUtil.addHexPrefix(data)
+ const fourBytePrefix = prefixedData.slice(0, 10)
+ const sig = await registry.lookup(fourBytePrefix)
+ const parsedResult = registry.parse(sig)
+
+ return {
+ name: parsedResult.name,
+ params: parsedResult.args,
+ }
+}
+
+export function isConfirmDeployContract (txData = {}) {
+ const { txParams = {} } = txData
+ return !txParams.to
+}
+
+export async function getTransactionActionKey (transaction, methodData) {
+ const { txParams: { data, to } = {}, msgParams, type } = transaction
+
+ if (type === 'cancel') {
+ return CANCEL_ATTEMPT_ACTION_KEY
+ }
+
+ if (msgParams) {
+ return SIGNATURE_REQUEST_KEY
+ }
+
+ if (isConfirmDeployContract(transaction)) {
+ return DEPLOY_CONTRACT_ACTION_KEY
+ }
+
+ if (data) {
+ const toSmartContract = await isSmartContractAddress(to)
+
+ if (!toSmartContract) {
+ return SEND_ETHER_ACTION_KEY
+ }
+
+ const { name } = methodData
+ const methodName = name && name.toLowerCase()
+
+ if (!methodName) {
+ return UNKNOWN_FUNCTION_KEY
+ }
+
+ switch (methodName) {
+ case TOKEN_METHOD_TRANSFER:
+ return SEND_TOKEN_ACTION_KEY
+ case TOKEN_METHOD_APPROVE:
+ return APPROVE_ACTION_KEY
+ case TOKEN_METHOD_TRANSFER_FROM:
+ return TRANSFER_FROM_ACTION_KEY
+ default:
+ return name
+ }
+ } else {
+ return SEND_ETHER_ACTION_KEY
+ }
+}
+
+export function getLatestSubmittedTxWithNonce (transactions = [], nonce = '0x0') {
+ if (!transactions.length) {
+ return {}
+ }
+
+ return transactions.reduce((acc, current) => {
+ const { submittedTime, txParams: { nonce: currentNonce } = {} } = current
+
+ if (currentNonce === nonce) {
+ return acc.submittedTime
+ ? submittedTime > acc.submittedTime ? current : acc
+ : current
+ } else {
+ return acc
+ }
+ }, {})
+}
+
+export async function isSmartContractAddress (address) {
+ const code = await global.eth.getCode(address)
+ return code && code !== '0x'
+}
+
+export function sumHexes (...args) {
+ const total = args.reduce((acc, base) => {
+ return addCurrencies(acc, base, {
+ toNumericBase: 'hex',
+ })
+ })
+
+ return ethUtil.addHexPrefix(total)
+}
diff --git a/ui/app/helpers/with-token-tracker.js b/ui/app/helpers/with-token-tracker.js
deleted file mode 100644
index 8608b15f4..000000000
--- a/ui/app/helpers/with-token-tracker.js
+++ /dev/null
@@ -1,108 +0,0 @@
-import React, { Component } from 'react'
-import PropTypes from 'prop-types'
-import TokenTracker from 'eth-token-tracker'
-
-const withTokenTracker = WrappedComponent => {
- return class TokenTrackerWrappedComponent extends Component {
- static propTypes = {
- userAddress: PropTypes.string.isRequired,
- token: PropTypes.object.isRequired,
- }
-
- constructor (props) {
- super(props)
-
- this.state = {
- string: '',
- symbol: '',
- error: null,
- }
-
- this.tracker = null
- this.updateBalance = this.updateBalance.bind(this)
- this.setError = this.setError.bind(this)
- }
-
- componentDidMount () {
- this.createFreshTokenTracker()
- }
-
- componentDidUpdate (prevProps) {
- const { userAddress: newAddress, token: { address: newTokenAddress } } = this.props
- const { userAddress: oldAddress, token: { address: oldTokenAddress } } = prevProps
-
- if ((oldAddress === newAddress) && (oldTokenAddress === newTokenAddress)) {
- return
- }
-
- if ((!oldAddress || !newAddress) && (!oldTokenAddress || !newTokenAddress)) {
- return
- }
-
- this.createFreshTokenTracker()
- }
-
- componentWillUnmount () {
- this.removeListeners()
- }
-
- createFreshTokenTracker () {
- this.removeListeners()
-
- if (!global.ethereumProvider) {
- return
- }
-
- const { userAddress, token } = this.props
-
- this.tracker = new TokenTracker({
- userAddress,
- provider: global.ethereumProvider,
- tokens: [token],
- pollingInterval: 8000,
- })
-
- this.tracker.on('update', this.updateBalance)
- this.tracker.on('error', this.setError)
-
- this.tracker.updateBalances()
- .then(() => this.updateBalance(this.tracker.serialize()))
- .catch(error => this.setState({ error: error.message }))
- }
-
- setError (error) {
- this.setState({ error })
- }
-
- updateBalance (tokens = []) {
- if (!this.tracker.running) {
- return
- }
- const [{ string, symbol }] = tokens
- this.setState({ string, symbol, error: null })
- }
-
- removeListeners () {
- if (this.tracker) {
- this.tracker.stop()
- this.tracker.removeListener('update', this.updateBalance)
- this.tracker.removeListener('error', this.setError)
- }
- }
-
- render () {
- const { string, symbol, error } = this.state
-
- return (
- <WrappedComponent
- { ...this.props }
- string={string}
- symbol={symbol}
- error={error}
- />
- )
- }
- }
-}
-
-module.exports = withTokenTracker