aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Klebanoff <steve@0xproject.com>2018-10-31 06:58:18 +0800
committerGitHub <noreply@github.com>2018-10-31 06:58:18 +0800
commit5d6fde356a19658ae91114df68fa507d93ff8049 (patch)
tree5b7abdb49e1afeb82ce260596e2a0c0c17e2a30c
parent48ff13e3e22bf9f71bc1a367f86aaa0ae89989ae (diff)
parent5901ee7e963a4413f49fffdd9477085229e7623f (diff)
downloaddexon-0x-contracts-5d6fde356a19658ae91114df68fa507d93ff8049.tar
dexon-0x-contracts-5d6fde356a19658ae91114df68fa507d93ff8049.tar.gz
dexon-0x-contracts-5d6fde356a19658ae91114df68fa507d93ff8049.tar.bz2
dexon-0x-contracts-5d6fde356a19658ae91114df68fa507d93ff8049.tar.lz
dexon-0x-contracts-5d6fde356a19658ae91114df68fa507d93ff8049.tar.xz
dexon-0x-contracts-5d6fde356a19658ae91114df68fa507d93ff8049.tar.zst
dexon-0x-contracts-5d6fde356a19658ae91114df68fa507d93ff8049.zip
Merge pull request #1198 from 0xProject/feature/instant/gas-estimate
[instant] Gas price estimate
-rw-r--r--packages/instant/src/components/buy_button.tsx7
-rw-r--r--packages/instant/src/components/zero_ex_instant.tsx7
-rw-r--r--packages/instant/src/constants.ts2
-rw-r--r--packages/instant/src/util/coinbase_api.ts7
-rw-r--r--packages/instant/src/util/gas_price_estimator.ts44
5 files changed, 61 insertions, 6 deletions
diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx
index e65e62e47..93bd8e635 100644
--- a/packages/instant/src/components/buy_button.tsx
+++ b/packages/instant/src/components/buy_button.tsx
@@ -2,11 +2,12 @@ import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer';
import * as _ from 'lodash';
import * as React from 'react';
-import { DEFAULT_GAS_PRICE, WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants';
+import { WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants';
import { ColorOption } from '../style/theme';
import { ZeroExInstantError } from '../types';
import { getBestAddress } from '../util/address';
import { balanceUtil } from '../util/balance';
+import { gasPriceEstimator } from '../util/gas_price_estimator';
import { util } from '../util/util';
import { web3Wrapper } from '../util/web3_wrapper';
@@ -56,9 +57,9 @@ export class BuyButton extends React.Component<BuyButtonProps> {
}
let txHash: string | undefined;
+ const gasPrice = await gasPriceEstimator.getFastAmountInWeiAsync();
try {
- const gasPrice = DEFAULT_GAS_PRICE;
- txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { gasPrice, takerAddress });
+ txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { takerAddress, gasPrice });
} catch (e) {
if (e instanceof Error) {
if (e.message === AssetBuyerError.SignatureRequestDenied) {
diff --git a/packages/instant/src/components/zero_ex_instant.tsx b/packages/instant/src/components/zero_ex_instant.tsx
index 19a2d6b9b..d54dfc153 100644
--- a/packages/instant/src/components/zero_ex_instant.tsx
+++ b/packages/instant/src/components/zero_ex_instant.tsx
@@ -13,6 +13,7 @@ import { AssetMetaData, Network } from '../types';
import { assetUtils } from '../util/asset';
import { BigNumberInput } from '../util/big_number_input';
import { errorFlasher } from '../util/error_flasher';
+import { gasPriceEstimator } from '../util/gas_price_estimator';
import { getProvider } from '../util/provider';
import { web3Wrapper } from '../util/web3_wrapper';
@@ -78,6 +79,12 @@ export class ZeroExInstant extends React.Component<ZeroExInstantProps> {
public componentDidMount(): void {
// tslint:disable-next-line:no-floating-promises
asyncData.fetchAndDispatchToStore(this._store);
+
+ // warm up the gas price estimator cache just in case we can't
+ // grab the gas price estimate when submitting the transaction
+ // tslint:disable-next-line:no-floating-promises
+ gasPriceEstimator.getFastAmountInWeiAsync();
+
// tslint:disable-next-line:no-floating-promises
this._flashErrorIfWrongNetwork();
}
diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts
index 47cb2eaeb..424f35ecb 100644
--- a/packages/instant/src/constants.ts
+++ b/packages/instant/src/constants.ts
@@ -5,3 +5,5 @@ export const DEFAULT_ZERO_EX_CONTAINER_SELECTOR = '#zeroExInstantContainer';
export const WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX = 'Transaction failed';
export const GWEI_IN_WEI = new BigNumber(1000000000);
export const DEFAULT_GAS_PRICE = GWEI_IN_WEI.mul(6);
+export const ETH_GAS_STATION_API_BASE_URL = 'https://ethgasstation.info';
+export const COINBASE_API_BASE_URL = 'https://api.coinbase.com/v2';
diff --git a/packages/instant/src/util/coinbase_api.ts b/packages/instant/src/util/coinbase_api.ts
index 080421f98..faac8d82d 100644
--- a/packages/instant/src/util/coinbase_api.ts
+++ b/packages/instant/src/util/coinbase_api.ts
@@ -1,9 +1,10 @@
-import { BigNumber } from '@0x/utils';
+import { BigNumber, fetchAsync } from '@0x/utils';
+
+import { COINBASE_API_BASE_URL } from '../constants';
-const baseEndpoint = 'https://api.coinbase.com/v2';
export const coinbaseApi = {
getEthUsdPrice: async (): Promise<BigNumber> => {
- const res = await fetch(`${baseEndpoint}/prices/ETH-USD/buy`);
+ const res = await fetchAsync(`${COINBASE_API_BASE_URL}/prices/ETH-USD/buy`);
const resJson = await res.json();
return new BigNumber(resJson.data.amount);
},
diff --git a/packages/instant/src/util/gas_price_estimator.ts b/packages/instant/src/util/gas_price_estimator.ts
new file mode 100644
index 000000000..336c4a3fa
--- /dev/null
+++ b/packages/instant/src/util/gas_price_estimator.ts
@@ -0,0 +1,44 @@
+import { BigNumber, fetchAsync } from '@0x/utils';
+
+import { DEFAULT_GAS_PRICE, ETH_GAS_STATION_API_BASE_URL, GWEI_IN_WEI } from '../constants';
+
+interface EthGasStationResult {
+ average: number;
+ fastestWait: number;
+ fastWait: number;
+ fast: number;
+ safeLowWait: number;
+ blockNum: number;
+ avgWait: number;
+ block_time: number;
+ speed: number;
+ fastest: number;
+ safeLow: number;
+}
+
+const fetchFastAmountInWeiAsync = async () => {
+ const res = await fetchAsync(`${ETH_GAS_STATION_API_BASE_URL}/json/ethgasAPI.json`);
+ const gasInfo = (await res.json()) as EthGasStationResult;
+ // Eth Gas Station result is gwei * 10
+ const gasPriceInGwei = new BigNumber(gasInfo.fast / 10);
+ return gasPriceInGwei.mul(GWEI_IN_WEI);
+};
+
+export class GasPriceEstimator {
+ private _lastFetched?: BigNumber;
+ public async getFastAmountInWeiAsync(): Promise<BigNumber> {
+ let fetchedAmount: BigNumber | undefined;
+ try {
+ fetchedAmount = await fetchFastAmountInWeiAsync();
+ } catch {
+ fetchedAmount = undefined;
+ }
+
+ if (fetchedAmount) {
+ this._lastFetched = fetchedAmount;
+ }
+
+ return fetchedAmount || this._lastFetched || DEFAULT_GAS_PRICE;
+ }
+}
+export const gasPriceEstimator = new GasPriceEstimator();