aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/selectors
diff options
context:
space:
mode:
authorDan Miller <danjm.com@gmail.com>2018-08-16 20:28:27 +0800
committerDan Miller <danjm.com@gmail.com>2018-12-04 11:36:04 +0800
commit0a7dfcd55d02a7204d8f0773ff9d91f325aabea8 (patch)
treea4c7d3e219ca926f17f26d020fddc78854a23b53 /ui/app/selectors
parent112d18e316df312a648b8c8ac17c201314fc9ed6 (diff)
downloadtangerine-wallet-browser-0a7dfcd55d02a7204d8f0773ff9d91f325aabea8.tar
tangerine-wallet-browser-0a7dfcd55d02a7204d8f0773ff9d91f325aabea8.tar.gz
tangerine-wallet-browser-0a7dfcd55d02a7204d8f0773ff9d91f325aabea8.tar.bz2
tangerine-wallet-browser-0a7dfcd55d02a7204d8f0773ff9d91f325aabea8.tar.lz
tangerine-wallet-browser-0a7dfcd55d02a7204d8f0773ff9d91f325aabea8.tar.xz
tangerine-wallet-browser-0a7dfcd55d02a7204d8f0773ff9d91f325aabea8.tar.zst
tangerine-wallet-browser-0a7dfcd55d02a7204d8f0773ff9d91f325aabea8.zip
Connect the gas-button-group component to redux and a live api.
Diffstat (limited to 'ui/app/selectors')
-rw-r--r--ui/app/selectors/custom-gas.js186
-rw-r--r--ui/app/selectors/tests/custom-gas.test.js140
2 files changed, 319 insertions, 7 deletions
diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js
index 97280190f..ff2fd0e05 100644
--- a/ui/app/selectors/custom-gas.js
+++ b/ui/app/selectors/custom-gas.js
@@ -1,19 +1,191 @@
+import { pipe, partialRight } from 'ramda'
+import {
+ getConversionRate,
+ getGasLimit,
+} from '../components/send/send.selectors'
+import {
+ conversionUtil,
+ multiplyCurrencies,
+} from '../conversion-util'
+import {
+ getCurrentCurrency,
+} from '../selectors'
+import {
+ formatCurrency,
+} from '../helpers/confirm-transaction/util'
+import {
+ calcGasTotal,
+} from '../components/send/send.utils'
+import { addHexPrefix } from 'ethereumjs-util'
+
const selectors = {
- getCustomGasPrice,
- getCustomGasLimit,
getCustomGasErrors,
+ getCustomGasLimit,
+ getCustomGasPrice,
+ getCustomGasTotal,
+ getRenderableBasicEstimateData,
+ getBasicGasEstimateLoadingStatus,
}
module.exports = selectors
-function getCustomGasPrice (state) {
- return state.customGas.price
+function getCustomGasErrors (state) {
+ return state.gas.errors
}
function getCustomGasLimit (state) {
- return state.customGas.limit
+ return state.gas.customData.limit
}
-function getCustomGasErrors (state) {
- return state.customGas.errors
+function getCustomGasPrice (state) {
+ return state.gas.customData.price
+}
+
+function getCustomGasTotal (state) {
+ return state.gas.customData.total
+}
+
+function getBasicGasEstimateLoadingStatus (state) {
+ return state.gas.basicEstimateIsLoading
+}
+
+
+function apiEstimateModifiedToGWEI (estimate) {
+ return multiplyCurrencies(estimate, 0.10, {
+ toNumericBase: 'hex',
+ multiplicandBase: 10,
+ multiplierBase: 10,
+ numberOfDecimals: 9,
+ })
+}
+
+function basicPriceEstimateToETHTotal (estimate, gasLimit) {
+ return conversionUtil(calcGasTotal(gasLimit, estimate), {
+ fromNumericBase: 'hex',
+ toNumericBase: 'dec',
+ fromDenomination: 'GWEI',
+ numberOfDecimals: 9,
+ })
+}
+
+function ethTotalToConvertedCurrency (ethTotal, convertedCurrency, conversionRate) {
+ return conversionUtil(ethTotal, {
+ fromNumericBase: 'dec',
+ toNumericBase: 'dec',
+ fromCurrency: 'ETH',
+ toCurrency: convertedCurrency,
+ numberOfDecimals: 2,
+ conversionRate,
+ })
+}
+
+function formatETHFee (ethFee) {
+ return ethFee + ' ETH'
+}
+
+function getRenderableEthFee (estimate, gasLimit) {
+ return pipe(
+ apiEstimateModifiedToGWEI,
+ partialRight(basicPriceEstimateToETHTotal, [gasLimit]),
+ formatETHFee
+ )(estimate, gasLimit)
+}
+
+function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate) {
+ return pipe(
+ apiEstimateModifiedToGWEI,
+ partialRight(basicPriceEstimateToETHTotal, [gasLimit]),
+ partialRight(ethTotalToConvertedCurrency, [convertedCurrency, conversionRate]),
+ partialRight(formatCurrency, [convertedCurrency])
+ )(estimate, gasLimit, convertedCurrency, conversionRate)
+}
+
+function getTimeEstimateInSeconds (blockWaitEstimate, currentBlockTime) {
+ return multiplyCurrencies(blockWaitEstimate, currentBlockTime, {
+ toNumericBase: 'dec',
+ multiplicandBase: 10,
+ multiplierBase: 10,
+ numberOfDecimals: 1,
+ })
+}
+
+function formatTimeEstimate (totalSeconds) {
+ const minutes = Math.floor(totalSeconds / 60)
+ const seconds = Math.floor(totalSeconds % 60)
+ const formattedMin = `${minutes ? minutes + ' min' : ''}`
+ const formattedSec = `${seconds ? seconds + ' sec' : ''}`
+ const formattedCombined = formattedMin && formattedSec
+ ? `~${formattedMin} ${formattedSec}`
+ : '~' + [formattedMin, formattedSec].find(t => t)
+
+ return formattedCombined
+}
+
+function getRenderableTimeEstimate (blockWaitEstimate, currentBlockTime) {
+ return pipe(
+ getTimeEstimateInSeconds,
+ formatTimeEstimate
+ )(blockWaitEstimate, currentBlockTime)
+}
+
+function priceEstimateToWei (priceEstimate) {
+ return conversionUtil(priceEstimate, {
+ fromNumericBase: 'hex',
+ toNumericBase: 'hex',
+ fromDenomination: 'GWEI',
+ toDenomination: 'WEI',
+ numberOfDecimals: 9,
+ })
+}
+
+function getGasPriceInHexWei (price) {
+ return pipe(
+ apiEstimateModifiedToGWEI,
+ priceEstimateToWei,
+ addHexPrefix
+ )(price)
+}
+
+function getRenderableBasicEstimateData (state) {
+ if (getBasicGasEstimateLoadingStatus(state)) {
+ return []
+ }
+
+ const gasLimit = getGasLimit(state)
+ const conversionRate = getConversionRate(state)
+ const currentCurrency = getCurrentCurrency(state)
+ const {
+ gas: {
+ basicEstimates: {
+ safeLow,
+ average,
+ fast,
+ blockTime,
+ safeLowWait,
+ avgWait,
+ fastWait,
+ },
+ },
+ } = state
+
+ return [
+ {
+ feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate),
+ feeInSecondaryCurrency: getRenderableEthFee(fast, gasLimit),
+ timeEstimate: getRenderableTimeEstimate(fastWait, blockTime),
+ priceInHexWei: getGasPriceInHexWei(fast),
+ },
+ {
+ feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(average, gasLimit, currentCurrency, conversionRate),
+ feeInSecondaryCurrency: getRenderableEthFee(average, gasLimit),
+ timeEstimate: getRenderableTimeEstimate(avgWait, blockTime),
+ priceInHexWei: getGasPriceInHexWei(average),
+ },
+ {
+ feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate),
+ feeInSecondaryCurrency: getRenderableEthFee(safeLow, gasLimit),
+ timeEstimate: getRenderableTimeEstimate(safeLowWait, blockTime),
+ priceInHexWei: getGasPriceInHexWei(safeLow),
+ },
+ ]
}
diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/tests/custom-gas.test.js
new file mode 100644
index 000000000..d53c1ec98
--- /dev/null
+++ b/ui/app/selectors/tests/custom-gas.test.js
@@ -0,0 +1,140 @@
+import assert from 'assert'
+import proxyquire from 'proxyquire'
+
+const {
+ getCustomGasErrors,
+ getCustomGasLimit,
+ getCustomGasPrice,
+ getCustomGasTotal,
+ getRenderableBasicEstimateData,
+} = proxyquire('../custom-gas', {})
+
+describe('custom-gas selectors', () => {
+
+ describe('getCustomGasPrice()', () => {
+ it('should return gas.customData.price', () => {
+ const mockState = { gas: { customData: { price: 'mockPrice' } } }
+ assert.equal(getCustomGasPrice(mockState), 'mockPrice')
+ })
+ })
+
+ describe('getCustomGasLimit()', () => {
+ it('should return gas.customData.limit', () => {
+ const mockState = { gas: { customData: { limit: 'mockLimit' } } }
+ assert.equal(getCustomGasLimit(mockState), 'mockLimit')
+ })
+ })
+
+ describe('getCustomGasTotal()', () => {
+ it('should return gas.customData.total', () => {
+ const mockState = { gas: { customData: { total: 'mockTotal' } } }
+ assert.equal(getCustomGasTotal(mockState), 'mockTotal')
+ })
+ })
+
+ describe('getCustomGasErrors()', () => {
+ it('should return gas.errors', () => {
+ const mockState = { gas: { errors: 'mockErrors' } }
+ assert.equal(getCustomGasErrors(mockState), 'mockErrors')
+ })
+ })
+
+ describe('getRenderableBasicEstimateData()', () => {
+ const tests = [
+ {
+ expectedResult: [
+ {
+ feeInPrimaryCurrency: '$0.05',
+ feeInSecondaryCurrency: '0.00021 ETH',
+ timeEstimate: '~7 sec',
+ priceInHexWei: '0x2540be400',
+ },
+ {
+ feeInPrimaryCurrency: '$0.03',
+ feeInSecondaryCurrency: '0.000105 ETH',
+ timeEstimate: '~46 sec',
+ priceInHexWei: '0x12a05f200',
+ },
+ {
+ feeInPrimaryCurrency: '$0.01',
+ feeInSecondaryCurrency: '0.0000525 ETH',
+ timeEstimate: '~1 min 33 sec',
+ priceInHexWei: '0x9502f900',
+ },
+ ],
+ mockState: {
+ metamask: {
+ conversionRate: 255.71,
+ currentCurrency: 'usd',
+ send: {
+ gasLimit: '0x5208',
+ },
+ },
+ gas: {
+ basicEstimates: {
+ blockTime: 14.16326530612245,
+ safeLow: 25,
+ safeLowWait: 6.6,
+ average: 50,
+ avgWait: 3.3,
+ fast: 100,
+ fastWait: 0.5,
+ },
+ },
+ },
+ },
+ {
+ expectedResult: [
+ {
+ feeInPrimaryCurrency: '$1.07',
+ feeInSecondaryCurrency: '0.00042 ETH',
+ timeEstimate: '~14 sec',
+ priceInHexWei: '0x4a817c800',
+ },
+ {
+ feeInPrimaryCurrency: '$0.54',
+ feeInSecondaryCurrency: '0.00021 ETH',
+ timeEstimate: '~1 min 33 sec',
+ priceInHexWei: '0x2540be400',
+ },
+ {
+ feeInPrimaryCurrency: '$0.27',
+ feeInSecondaryCurrency: '0.000105 ETH',
+ timeEstimate: '~3 min 7 sec',
+ priceInHexWei: '0x12a05f200',
+ },
+ ],
+ mockState: {
+ metamask: {
+ conversionRate: 2557.1,
+ currentCurrency: 'usd',
+ send: {
+ gasLimit: '0x5208',
+ },
+ },
+ gas: {
+ basicEstimates: {
+ blockTime: 14.16326530612245,
+ safeLow: 50,
+ safeLowWait: 13.2,
+ average: 100,
+ avgWait: 6.6,
+ fast: 200,
+ fastWait: 1.0,
+ },
+ },
+ },
+ },
+ ]
+ it('should return renderable data about basic estimates', () => {
+ tests.forEach(test => {
+ assert.deepEqual(
+ getRenderableBasicEstimateData(test.mockState),
+ test.expectedResult
+ )
+ })
+ })
+
+ })
+
+})