From ffecba21f4e9dcda961a3e8432e70e6605174de5 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 26 Oct 2018 12:43:08 -0700 Subject: ethDecimals -> ETH_DECIMALS --- packages/instant/src/components/buy_button.tsx | 4 +++- packages/instant/src/constants.ts | 2 +- packages/instant/src/util/format.ts | 6 +++--- packages/instant/test/util/format.test.ts | 8 ++++---- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index a70269dde..4780b80e7 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -4,6 +4,7 @@ import * as React from 'react'; import { WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants'; import { ColorOption } from '../style/theme'; +import { getBestAddress } from '../util/address'; import { util } from '../util/util'; import { web3Wrapper } from '../util/web3_wrapper'; @@ -45,7 +46,8 @@ export class BuyButton extends React.Component { let txHash: string | undefined; this.props.onAwaitingSignature(buyQuote); try { - txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote); + const takerAddress = await getBestAddress(); + txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { takerAddress }); } catch (e) { if (e instanceof Error && e.message === AssetBuyerError.SignatureRequestDenied) { this.props.onSignatureDenied(buyQuote, e); diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index 48d0d4aa2..e4281d54a 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -1,5 +1,5 @@ import { BigNumber } from '@0x/utils'; export const BIG_NUMBER_ZERO = new BigNumber(0); -export const ethDecimals = 18; +export const ETH_DECIMALS = 18; export const DEFAULT_ZERO_EX_CONTAINER_SELECTOR = '#zeroExInstantContainer'; export const WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX = 'Transaction failed'; diff --git a/packages/instant/src/util/format.ts b/packages/instant/src/util/format.ts index 8482b1526..2e0ccc03b 100644 --- a/packages/instant/src/util/format.ts +++ b/packages/instant/src/util/format.ts @@ -2,7 +2,7 @@ import { BigNumber } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; -import { ethDecimals } from '../constants'; +import { ETH_DECIMALS } from '../constants'; export const format = { ethBaseAmount: ( @@ -13,7 +13,7 @@ export const format = { if (_.isUndefined(ethBaseAmount)) { return defaultText; } - const ethUnitAmount = Web3Wrapper.toUnitAmount(ethBaseAmount, ethDecimals); + const ethUnitAmount = Web3Wrapper.toUnitAmount(ethBaseAmount, ETH_DECIMALS); return format.ethUnitAmount(ethUnitAmount, decimalPlaces); }, ethUnitAmount: ( @@ -36,7 +36,7 @@ export const format = { if (_.isUndefined(ethBaseAmount) || _.isUndefined(ethUsdPrice)) { return defaultText; } - const ethUnitAmount = Web3Wrapper.toUnitAmount(ethBaseAmount, ethDecimals); + const ethUnitAmount = Web3Wrapper.toUnitAmount(ethBaseAmount, ETH_DECIMALS); return format.ethUnitAmountInUsd(ethUnitAmount, ethUsdPrice, decimalPlaces); }, ethUnitAmountInUsd: ( diff --git a/packages/instant/test/util/format.test.ts b/packages/instant/test/util/format.test.ts index 141df9275..1be226ed8 100644 --- a/packages/instant/test/util/format.test.ts +++ b/packages/instant/test/util/format.test.ts @@ -1,15 +1,15 @@ import { BigNumber } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; -import { ethDecimals } from '../../src/constants'; +import { ETH_DECIMALS } from '../../src/constants'; import { format } from '../../src/util/format'; const BIG_NUMBER_ONE = new BigNumber(1); const BIG_NUMBER_DECIMAL = new BigNumber(0.432414); const BIG_NUMBER_IRRATIONAL = new BigNumber(5.3014059295032); -const ONE_ETH_IN_BASE_UNITS = Web3Wrapper.toBaseUnitAmount(BIG_NUMBER_ONE, ethDecimals); -const DECIMAL_ETH_IN_BASE_UNITS = Web3Wrapper.toBaseUnitAmount(BIG_NUMBER_DECIMAL, ethDecimals); -const IRRATIONAL_ETH_IN_BASE_UNITS = Web3Wrapper.toBaseUnitAmount(BIG_NUMBER_IRRATIONAL, ethDecimals); +const ONE_ETH_IN_BASE_UNITS = Web3Wrapper.toBaseUnitAmount(BIG_NUMBER_ONE, ETH_DECIMALS); +const DECIMAL_ETH_IN_BASE_UNITS = Web3Wrapper.toBaseUnitAmount(BIG_NUMBER_DECIMAL, ETH_DECIMALS); +const IRRATIONAL_ETH_IN_BASE_UNITS = Web3Wrapper.toBaseUnitAmount(BIG_NUMBER_IRRATIONAL, ETH_DECIMALS); const BIG_NUMBER_FAKE_ETH_USD_PRICE = new BigNumber(2.534); describe('format', () => { -- cgit v1.2.3 From 9512978de9aee1953930d4f16a105ec5ef7f048e Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 26 Oct 2018 12:43:44 -0700 Subject: feat(instant): Show message if user doesn't have enough ETH --- .../instant/src/containers/selected_asset_amount_input.ts | 14 +++++++++++++- packages/instant/src/types.ts | 1 + packages/instant/src/util/address.ts | 6 ++++++ packages/instant/src/util/error.ts | 5 ++++- 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 packages/instant/src/util/address.ts diff --git a/packages/instant/src/containers/selected_asset_amount_input.ts b/packages/instant/src/containers/selected_asset_amount_input.ts index e9dbc61ce..504f51535 100644 --- a/packages/instant/src/containers/selected_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_asset_amount_input.ts @@ -10,11 +10,15 @@ import { Dispatch } from 'redux'; import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; import { ColorOption } from '../style/theme'; -import { ERC20Asset, OrderProcessState } from '../types'; +import { ERC20Asset, OrderProcessState, ZeroExInstantError } from '../types'; +import { getBestAddress } from '../util/address'; import { errorUtil } from '../util/error'; +import { web3Wrapper } from '../util/web3_wrapper'; import { AssetAmountInput } from '../components/asset_amount_input'; +import { ETH_DECIMALS } from '../constants'; + export interface SelectedAssetAmountInputProps { fontColor?: ColorOption; fontSize?: string; @@ -76,6 +80,14 @@ const updateBuyQuoteAsync = async ( errorUtil.errorFlasher.clearError(dispatch); // invalidate the last buy quote. dispatch(actions.updateLatestBuyQuote(newBuyQuote)); + + // set error if user doesn't have appropriate balance + const takerAddress = await getBestAddress(); + const balanceWei = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + if (balanceWei < newBuyQuote.worstCaseQuoteInfo.totalEthAmount) { + const balanceError = new Error(ZeroExInstantError.InsufficientBalance); + errorUtil.errorFlasher.flashNewError(dispatch, balanceError); + } }; const debouncedUpdateBuyQuoteAsync = _.debounce(updateBuyQuoteAsync, 200, { trailing: true }); diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index c63371fb4..174ad86e6 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -72,4 +72,5 @@ export enum Network { export enum ZeroExInstantError { AssetMetaDataNotAvailable = 'ASSET_META_DATA_NOT_AVAILABLE', + InsufficientBalance = 'INSUFFICIENT_BALANCE', } diff --git a/packages/instant/src/util/address.ts b/packages/instant/src/util/address.ts new file mode 100644 index 000000000..97ed30a00 --- /dev/null +++ b/packages/instant/src/util/address.ts @@ -0,0 +1,6 @@ +import { web3Wrapper } from '../util/web3_wrapper'; + +export const getBestAddress = async (): Promise => { + const addresses = await web3Wrapper.getAvailableAddressesAsync(); + return addresses[0]; +}; diff --git a/packages/instant/src/util/error.ts b/packages/instant/src/util/error.ts index 64c1f4885..5db0c66d2 100644 --- a/packages/instant/src/util/error.ts +++ b/packages/instant/src/util/error.ts @@ -2,7 +2,7 @@ import { AssetBuyerError } from '@0x/asset-buyer'; import { Dispatch } from 'redux'; import { Action, actions } from '../redux/actions'; -import { Asset } from '../types'; +import { Asset, ZeroExInstantError } from '../types'; import { assetUtils } from './asset'; @@ -49,6 +49,9 @@ const humanReadableMessageForError = (error: Error, asset?: Asset): string | und if (error.message === AssetBuyerError.SignatureRequestDenied) { return 'You denied this transaction'; } + if (error.message === ZeroExInstantError.InsufficientBalance) { + return "You don't have enough ETH"; + } return undefined; }; -- cgit v1.2.3 From 341d7b3407d57277b7a93e7a7b85e23a59193268 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 26 Oct 2018 12:48:56 -0700 Subject: yarn.lock changes --- yarn.lock | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1ea799433..f3c0be06b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1900,6 +1900,10 @@ aes-js@^0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-0.2.4.tgz#94b881ab717286d015fa219e08fb66709dda5a3d" +aes-js@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.1.tgz#89fd1f94ae51b4c72d62466adc1a7323ff52f072" + agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -3337,7 +3341,7 @@ bs-logger@0.x: dependencies: fast-json-stable-stringify "^2.0.0" -bs58@=4.0.1: +bs58@=4.0.1, bs58@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" dependencies: @@ -3360,6 +3364,14 @@ bs58check@^1.0.8: bs58 "^3.1.0" create-hash "^1.1.0" +bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + bser@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" @@ -5947,6 +5959,19 @@ ethereumjs-wallet@0.6.0: utf8 "^2.1.1" uuid "^2.0.1" +ethereumjs-wallet@~0.6.0: + version "0.6.2" + resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.2.tgz#67244b6af3e8113b53d709124b25477b64aeccda" + dependencies: + aes-js "^3.1.1" + bs58check "^2.1.2" + ethereumjs-util "^5.2.0" + hdkey "^1.0.0" + safe-buffer "^5.1.2" + scrypt.js "^0.2.0" + utf8 "^3.0.0" + uuid "^3.3.2" + ethers@~4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.4.tgz#d3f85e8b27f4b59537e06526439b0fb15b44dc65" @@ -6751,7 +6776,7 @@ ganache-core@0xProject/ganache-core#monorepo-dep: ethereumjs-tx "0xProject/ethereumjs-tx#fake-tx-include-signature-by-default" ethereumjs-util "^5.2.0" ethereumjs-vm "2.3.5" - ethereumjs-wallet "~0.6.0" + ethereumjs-wallet "0.6.0" fake-merkle-patricia-tree "~1.0.1" heap "~0.2.6" js-scrypt "^0.2.0" @@ -7476,6 +7501,14 @@ hdkey@^0.7.0, hdkey@^0.7.1: coinstring "^2.0.0" secp256k1 "^3.0.1" +hdkey@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.0.tgz#e74e7b01d2c47f797fa65d1d839adb7a44639f29" + dependencies: + coinstring "^2.0.0" + safe-buffer "^5.1.1" + secp256k1 "^3.0.1" + he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" @@ -15562,6 +15595,10 @@ utf8@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" +utf8@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" -- cgit v1.2.3 From 476cbbb6cb32db5ca72cc9d200b3ead152ae0e33 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 26 Oct 2018 15:03:56 -0700 Subject: move imports --- .../instant/src/containers/selected_erc20_asset_amount_input.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts index 67c3ce6a5..3d0895aac 100644 --- a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts @@ -7,18 +7,16 @@ import * as React from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; +import { ERC20AssetAmountInput } from '../components/erc20_asset_amount_input'; import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; import { ColorOption } from '../style/theme'; +import { ERC20Asset, OrderProcessState, ZeroExInstantError } from '../types'; import { getBestAddress } from '../util/address'; import { BigNumberInput } from '../util/big_number_input'; import { errorUtil } from '../util/error'; import { web3Wrapper } from '../util/web3_wrapper'; -import { ERC20AssetAmountInput } from '../components/erc20_asset_amount_input'; - -import { ERC20Asset, OrderProcessState, ZeroExInstantError } from '../types'; - export interface SelectedERC20AssetAmountInputProps { fontColor?: ColorOption; startingFontSizePx: number; -- cgit v1.2.3 From e1ae551560ad12501256fd5702dcd929baa84100 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 26 Oct 2018 15:20:04 -0700 Subject: move funct into util --- .../selected_erc20_asset_amount_input.ts | 7 ++--- packages/instant/src/util/balance.ts | 30 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 packages/instant/src/util/balance.ts diff --git a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts index 3d0895aac..1fc5b6d8c 100644 --- a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts @@ -13,6 +13,7 @@ import { State } from '../redux/reducer'; import { ColorOption } from '../style/theme'; import { ERC20Asset, OrderProcessState, ZeroExInstantError } from '../types'; import { getBestAddress } from '../util/address'; +import { balanceUtil } from '../util/balance'; import { BigNumberInput } from '../util/big_number_input'; import { errorUtil } from '../util/error'; import { web3Wrapper } from '../util/web3_wrapper'; @@ -81,11 +82,7 @@ const updateBuyQuoteAsync = async ( // set error if user doesn't have appropriate balance const takerAddress = await getBestAddress(); - const balanceWei = await web3Wrapper.getBalanceInWeiAsync(takerAddress); - if (balanceWei < newBuyQuote.worstCaseQuoteInfo.totalEthAmount) { - const balanceError = new Error(ZeroExInstantError.InsufficientBalance); - errorUtil.errorFlasher.flashNewError(dispatch, balanceError); - } + await balanceUtil.checkSufficientBalanceAndFlashError(takerAddress, newBuyQuote, web3Wrapper, dispatch); }; const debouncedUpdateBuyQuoteAsync = _.debounce(updateBuyQuoteAsync, 200, { trailing: true }); diff --git a/packages/instant/src/util/balance.ts b/packages/instant/src/util/balance.ts new file mode 100644 index 000000000..d442da9e0 --- /dev/null +++ b/packages/instant/src/util/balance.ts @@ -0,0 +1,30 @@ +import { BuyQuote } from '@0x/asset-buyer'; +import { Web3Wrapper } from '@0x/web3-wrapper'; +import { Dispatch } from 'redux'; + +import { ZeroExInstantError } from '../types'; + +import { errorUtil } from './error'; + +export const balanceUtil = { + /** + * Checks to see if user has enough balance to buy assets + * If they do not, flash an error and return false + * If they do, return true + */ + checkSufficientBalanceAndFlashError: async ( + takerAddress: string, + buyQuote: BuyQuote, + web3Wrapper: Web3Wrapper, + dispatch: Dispatch, + ) => { + const balanceWei = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + + if (balanceWei < buyQuote.worstCaseQuoteInfo.totalEthAmount) { + const balanceError = new Error(ZeroExInstantError.InsufficientBalance); + errorUtil.errorFlasher.flashNewError(dispatch, balanceError); + return false; + } + return true; + }, +}; -- cgit v1.2.3 From 86febc3cce1135d2345f0048c205c3c524a66733 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 26 Oct 2018 15:34:35 -0700 Subject: acccount for no address --- .../selected_erc20_asset_amount_input.ts | 2 +- packages/instant/src/util/address.ts | 2 +- packages/instant/src/util/balance.ts | 26 ++++++++++++++-------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts index 1fc5b6d8c..325dc0ef2 100644 --- a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts @@ -82,7 +82,7 @@ const updateBuyQuoteAsync = async ( // set error if user doesn't have appropriate balance const takerAddress = await getBestAddress(); - await balanceUtil.checkSufficientBalanceAndFlashError(takerAddress, newBuyQuote, web3Wrapper, dispatch); + await balanceUtil.checkInsufficientEthBalanceAndFlashError(takerAddress, newBuyQuote, web3Wrapper, dispatch); }; const debouncedUpdateBuyQuoteAsync = _.debounce(updateBuyQuoteAsync, 200, { trailing: true }); diff --git a/packages/instant/src/util/address.ts b/packages/instant/src/util/address.ts index 97ed30a00..14d42d8c0 100644 --- a/packages/instant/src/util/address.ts +++ b/packages/instant/src/util/address.ts @@ -1,6 +1,6 @@ import { web3Wrapper } from '../util/web3_wrapper'; -export const getBestAddress = async (): Promise => { +export const getBestAddress = async (): Promise => { const addresses = await web3Wrapper.getAvailableAddressesAsync(); return addresses[0]; }; diff --git a/packages/instant/src/util/balance.ts b/packages/instant/src/util/balance.ts index d442da9e0..954dc7156 100644 --- a/packages/instant/src/util/balance.ts +++ b/packages/instant/src/util/balance.ts @@ -1,30 +1,38 @@ import { BuyQuote } from '@0x/asset-buyer'; import { Web3Wrapper } from '@0x/web3-wrapper'; +import * as _ from 'lodash'; import { Dispatch } from 'redux'; import { ZeroExInstantError } from '../types'; import { errorUtil } from './error'; +const hasSufficientFunds = async (takerAddress: string | undefined, buyQuote: BuyQuote, web3Wrapper: Web3Wrapper) => { + if (_.isUndefined(takerAddress)) { + return false; + } + const balanceWei = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + return balanceWei >= buyQuote.worstCaseQuoteInfo.totalEthAmount; +}; + export const balanceUtil = { /** * Checks to see if user has enough balance to buy assets * If they do not, flash an error and return false * If they do, return true */ - checkSufficientBalanceAndFlashError: async ( - takerAddress: string, + checkInsufficientEthBalanceAndFlashError: async ( + takerAddress: string | undefined, buyQuote: BuyQuote, web3Wrapper: Web3Wrapper, dispatch: Dispatch, ) => { - const balanceWei = await web3Wrapper.getBalanceInWeiAsync(takerAddress); - - if (balanceWei < buyQuote.worstCaseQuoteInfo.totalEthAmount) { - const balanceError = new Error(ZeroExInstantError.InsufficientBalance); - errorUtil.errorFlasher.flashNewError(dispatch, balanceError); - return false; + const hasEnoughFunds = await hasSufficientFunds(takerAddress, buyQuote, web3Wrapper); + if (hasEnoughFunds) { + return true; } - return true; + const balanceError = new Error(ZeroExInstantError.InsufficientBalance); + errorUtil.errorFlasher.flashNewError(dispatch, balanceError); + return false; }, }; -- cgit v1.2.3 From 667b1e03ddba1a2fac16488239f6bc977fa4cb6d Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 26 Oct 2018 15:51:23 -0700 Subject: Validate enough ETH when user clicks buy --- packages/instant/src/components/buy_button.tsx | 9 ++++++++- packages/instant/src/components/buy_order_state_buttons.tsx | 2 ++ .../src/containers/selected_asset_buy_order_state_buttons.ts | 6 ++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 4780b80e7..8b2e0e1f6 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -5,6 +5,7 @@ import * as React from 'react'; import { WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants'; import { ColorOption } from '../style/theme'; import { getBestAddress } from '../util/address'; +import { balanceUtil } from '../util/balance'; import { util } from '../util/util'; import { web3Wrapper } from '../util/web3_wrapper'; @@ -18,6 +19,7 @@ export interface BuyButtonProps { onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => void; onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; + validateWalletBeforeBuy: (buyQuote: BuyQuote, takerAddress: string | undefined) => Promise; } export class BuyButton extends React.Component { @@ -43,10 +45,15 @@ export class BuyButton extends React.Component { return; } + const takerAddress = await getBestAddress(); + const validWallet = await this.props.validateWalletBeforeBuy(buyQuote, takerAddress); + if (!validWallet) { + return; + } + let txHash: string | undefined; this.props.onAwaitingSignature(buyQuote); try { - const takerAddress = await getBestAddress(); txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { takerAddress }); } catch (e) { if (e instanceof Error && e.message === AssetBuyerError.SignatureRequestDenied) { diff --git a/packages/instant/src/components/buy_order_state_buttons.tsx b/packages/instant/src/components/buy_order_state_buttons.tsx index b9e92e763..cb5654424 100644 --- a/packages/instant/src/components/buy_order_state_buttons.tsx +++ b/packages/instant/src/components/buy_order_state_buttons.tsx @@ -23,6 +23,7 @@ export interface BuyOrderStateButtonProps { onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; onRetry: () => void; + validateWalletBeforeBuy: (buyQuote: BuyQuote, takerAddress: string | undefined) => Promise; } // TODO: rename to buttons @@ -58,6 +59,7 @@ export const BuyOrderStateButtons: React.StatelessComponent ); }; diff --git a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts index 8927b8954..49b9cf209 100644 --- a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts +++ b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts @@ -7,7 +7,9 @@ import { Dispatch } from 'redux'; import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; import { OrderProcessState, OrderState } from '../types'; +import { balanceUtil } from '../util/balance'; import { etherscanUtil } from '../util/etherscan'; +import { web3Wrapper } from '../util/web3_wrapper'; import { BuyOrderStateButtons } from '../components/buy_order_state_buttons'; @@ -25,6 +27,7 @@ interface ConnectedDispatch { onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; onRetry: () => void; + validateWalletBeforeBuy: (buyQuote: BuyQuote, takerAddress: string | undefined) => Promise; } export interface SelectedAssetBuyOrderStateButtons {} const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyOrderStateButtons): ConnectedState => ({ @@ -73,6 +76,9 @@ const mapDispatchToProps = ( onRetry: () => { dispatch(actions.resetAmount()); }, + validateWalletBeforeBuy: async (buyQuote: BuyQuote, takerAddress: string | undefined) => { + return balanceUtil.checkInsufficientEthBalanceAndFlashError(takerAddress, buyQuote, web3Wrapper, dispatch); + }, }); export const SelectedAssetBuyOrderStateButtons: React.ComponentClass = connect( -- cgit v1.2.3 From bb307a55d347c34ab51144c75721860e13659ecb Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 26 Oct 2018 19:23:42 -0700 Subject: questionmark syntax instead of '| undefined' --- packages/instant/src/components/buy_button.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 8b2e0e1f6..86c55dbf9 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -19,7 +19,7 @@ export interface BuyButtonProps { onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => void; onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; - validateWalletBeforeBuy: (buyQuote: BuyQuote, takerAddress: string | undefined) => Promise; + validateWalletBeforeBuy: (buyQuote: BuyQuote, takerAddress?: string) => Promise; } export class BuyButton extends React.Component { -- cgit v1.2.3 From ff295daa5c56b5c056a5faa5ca8875c317524070 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 26 Oct 2018 19:53:15 -0700 Subject: Simpler way of validaitng has enough eth --- packages/instant/src/components/buy_button.tsx | 13 ++++--- .../src/components/buy_order_state_buttons.tsx | 12 +++---- .../selected_asset_buy_order_state_buttons.ts | 20 ++++++----- .../selected_erc20_asset_amount_input.ts | 4 --- packages/instant/src/types.ts | 4 +-- packages/instant/src/util/balance.ts | 40 ++++++---------------- 6 files changed, 37 insertions(+), 56 deletions(-) diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 86c55dbf9..2f670d387 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -4,6 +4,7 @@ import * as React from 'react'; 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 { util } from '../util/util'; @@ -14,12 +15,12 @@ import { Button, Text } from './ui'; export interface BuyButtonProps { buyQuote?: BuyQuote; assetBuyer?: AssetBuyer; - onAwaitingSignature: (buyQuote: BuyQuote) => void; + onPendingValidation: (buyQuote: BuyQuote) => void; + onValidationFail: (buyQuote: BuyQuote, error: ZeroExInstantError) => void; onSignatureDenied: (buyQuote: BuyQuote, preventedError: Error) => void; onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => void; onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; - validateWalletBeforeBuy: (buyQuote: BuyQuote, takerAddress?: string) => Promise; } export class BuyButton extends React.Component { @@ -45,14 +46,16 @@ export class BuyButton extends React.Component { return; } + this.props.onPendingValidation(buyQuote); const takerAddress = await getBestAddress(); - const validWallet = await this.props.validateWalletBeforeBuy(buyQuote, takerAddress); - if (!validWallet) { + + const hasSufficientFunds = await balanceUtil.hasSufficientFunds(takerAddress, buyQuote, web3Wrapper); + if (!hasSufficientFunds) { + this.props.onValidationFail(buyQuote, ZeroExInstantError.InsufficientBalance); return; } let txHash: string | undefined; - this.props.onAwaitingSignature(buyQuote); try { txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { takerAddress }); } catch (e) { diff --git a/packages/instant/src/components/buy_order_state_buttons.tsx b/packages/instant/src/components/buy_order_state_buttons.tsx index cb5654424..8225441f7 100644 --- a/packages/instant/src/components/buy_order_state_buttons.tsx +++ b/packages/instant/src/components/buy_order_state_buttons.tsx @@ -7,7 +7,7 @@ import { Flex } from '../components/ui/flex'; import { PlacingOrderButton } from '../components/placing_order_button'; import { ColorOption } from '../style/theme'; -import { OrderProcessState } from '../types'; +import { OrderProcessState, ZeroExInstantError } from '../types'; import { Button } from './ui/button'; import { Text } from './ui/text'; @@ -17,13 +17,13 @@ export interface BuyOrderStateButtonProps { buyOrderProcessingState: OrderProcessState; assetBuyer?: AssetBuyer; onViewTransaction: () => void; - onAwaitingSignature: (buyQuote: BuyQuote) => void; + onPendingValidation: (buyQuote: BuyQuote) => void; onSignatureDenied: (buyQuote: BuyQuote, error: Error) => void; onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => void; onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; onRetry: () => void; - validateWalletBeforeBuy: (buyQuote: BuyQuote, takerAddress: string | undefined) => Promise; + onValidationFail: (buyQuote: BuyQuote, error: ZeroExInstantError) => void; } // TODO: rename to buttons @@ -46,7 +46,7 @@ export const BuyOrderStateButtons: React.StatelessComponentView Transaction; - } else if (props.buyOrderProcessingState === OrderProcessState.AWAITING_SIGNATURE) { + } else if (props.buyOrderProcessingState === OrderProcessState.VALIDATING) { return ; } @@ -54,12 +54,12 @@ export const BuyOrderStateButtons: React.StatelessComponent ); }; diff --git a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts index 49b9cf209..dee724e15 100644 --- a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts +++ b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts @@ -6,12 +6,13 @@ import { Dispatch } from 'redux'; import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; -import { OrderProcessState, OrderState } from '../types'; +import { OrderProcessState, OrderState, ZeroExInstantError } from '../types'; import { balanceUtil } from '../util/balance'; import { etherscanUtil } from '../util/etherscan'; import { web3Wrapper } from '../util/web3_wrapper'; import { BuyOrderStateButtons } from '../components/buy_order_state_buttons'; +import { errorUtil } from '../util/error'; interface ConnectedState { buyQuote?: BuyQuote; @@ -21,13 +22,13 @@ interface ConnectedState { } interface ConnectedDispatch { - onAwaitingSignature: (buyQuote: BuyQuote) => void; + onPendingValidation: (buyQuote: BuyQuote) => void; onSignatureDenied: (buyQuote: BuyQuote, error: Error) => void; onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => void; onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; onRetry: () => void; - validateWalletBeforeBuy: (buyQuote: BuyQuote, takerAddress: string | undefined) => Promise; + onValidationFail: (buyQuote: BuyQuote, error: ZeroExInstantError) => void; } export interface SelectedAssetBuyOrderStateButtons {} const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyOrderStateButtons): ConnectedState => ({ @@ -57,8 +58,8 @@ const mapDispatchToProps = ( dispatch: Dispatch, ownProps: SelectedAssetBuyOrderStateButtons, ): ConnectedDispatch => ({ - onAwaitingSignature: (buyQuote: BuyQuote) => { - const newOrderState: OrderState = { processState: OrderProcessState.AWAITING_SIGNATURE }; + onPendingValidation: (buyQuote: BuyQuote) => { + const newOrderState: OrderState = { processState: OrderProcessState.VALIDATING }; dispatch(actions.updateBuyOrderState(newOrderState)); }, onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => { @@ -71,14 +72,15 @@ const mapDispatchToProps = ( dispatch(actions.updateBuyOrderState({ processState: OrderProcessState.FAILURE, txHash })), onSignatureDenied: (buyQuote, error) => { dispatch(actions.resetAmount()); - dispatch(actions.setError(error)); + errorUtil.errorFlasher.flashNewError(dispatch, error); + }, + onValidationFail: (buyQuote, error) => { + dispatch(actions.updateBuyOrderState({ processState: OrderProcessState.NONE })); + errorUtil.errorFlasher.flashNewError(dispatch, new Error(error)); }, onRetry: () => { dispatch(actions.resetAmount()); }, - validateWalletBeforeBuy: async (buyQuote: BuyQuote, takerAddress: string | undefined) => { - return balanceUtil.checkInsufficientEthBalanceAndFlashError(takerAddress, buyQuote, web3Wrapper, dispatch); - }, }); export const SelectedAssetBuyOrderStateButtons: React.ComponentClass = connect( diff --git a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts index 325dc0ef2..a090ad8fb 100644 --- a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts @@ -79,10 +79,6 @@ const updateBuyQuoteAsync = async ( errorUtil.errorFlasher.clearError(dispatch); // invalidate the last buy quote. dispatch(actions.updateLatestBuyQuote(newBuyQuote)); - - // set error if user doesn't have appropriate balance - const takerAddress = await getBestAddress(); - await balanceUtil.checkInsufficientEthBalanceAndFlashError(takerAddress, newBuyQuote, web3Wrapper, dispatch); }; const debouncedUpdateBuyQuoteAsync = _.debounce(updateBuyQuoteAsync, 200, { trailing: true }); diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index 174ad86e6..9dd5624b6 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -10,14 +10,14 @@ export enum AsyncProcessState { export enum OrderProcessState { NONE = 'None', - AWAITING_SIGNATURE = 'Awaiting Signature', + VALIDATING = 'Validating', PROCESSING = 'Processing', SUCCESS = 'Success', FAILURE = 'Failure', } interface OrderStatePreTx { - processState: OrderProcessState.NONE | OrderProcessState.AWAITING_SIGNATURE; + processState: OrderProcessState.NONE | OrderProcessState.VALIDATING; } interface OrderStatePostTx { processState: OrderProcessState.PROCESSING | OrderProcessState.SUCCESS | OrderProcessState.FAILURE; diff --git a/packages/instant/src/util/balance.ts b/packages/instant/src/util/balance.ts index 954dc7156..9cb8b8987 100644 --- a/packages/instant/src/util/balance.ts +++ b/packages/instant/src/util/balance.ts @@ -1,38 +1,18 @@ import { BuyQuote } from '@0x/asset-buyer'; import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; -import { Dispatch } from 'redux'; - -import { ZeroExInstantError } from '../types'; - -import { errorUtil } from './error'; - -const hasSufficientFunds = async (takerAddress: string | undefined, buyQuote: BuyQuote, web3Wrapper: Web3Wrapper) => { - if (_.isUndefined(takerAddress)) { - return false; - } - const balanceWei = await web3Wrapper.getBalanceInWeiAsync(takerAddress); - return balanceWei >= buyQuote.worstCaseQuoteInfo.totalEthAmount; -}; export const balanceUtil = { - /** - * Checks to see if user has enough balance to buy assets - * If they do not, flash an error and return false - * If they do, return true - */ - checkInsufficientEthBalanceAndFlashError: async ( - takerAddress: string | undefined, - buyQuote: BuyQuote, - web3Wrapper: Web3Wrapper, - dispatch: Dispatch, - ) => { - const hasEnoughFunds = await hasSufficientFunds(takerAddress, buyQuote, web3Wrapper); - if (hasEnoughFunds) { - return true; + hasSufficientFunds: async (takerAddress: string | undefined, buyQuote: BuyQuote, web3Wrapper: Web3Wrapper) => { + if (_.isUndefined(takerAddress)) { + return false; } - const balanceError = new Error(ZeroExInstantError.InsufficientBalance); - errorUtil.errorFlasher.flashNewError(dispatch, balanceError); - return false; + const balanceWei = await web3Wrapper.getBalanceInWeiAsync(takerAddress); + console.log('balanceWei', balanceWei.toString()); + console.log( + 'buyQuote.worstCaseQuoteInfo.totalEthAmount', + buyQuote.worstCaseQuoteInfo.totalEthAmount.toString(), + ); + return balanceWei >= buyQuote.worstCaseQuoteInfo.totalEthAmount; }, }; -- cgit v1.2.3 From 3052c8d303bdbaf57e762345d5ee8428d2194d0a Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 26 Oct 2018 19:55:42 -0700 Subject: linting --- .../instant/src/containers/selected_asset_buy_order_state_buttons.ts | 2 -- packages/instant/src/containers/selected_erc20_asset_amount_input.ts | 5 +---- packages/instant/src/util/balance.ts | 5 ----- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts index dee724e15..d22fd7d24 100644 --- a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts +++ b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts @@ -7,9 +7,7 @@ import { Dispatch } from 'redux'; import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; import { OrderProcessState, OrderState, ZeroExInstantError } from '../types'; -import { balanceUtil } from '../util/balance'; import { etherscanUtil } from '../util/etherscan'; -import { web3Wrapper } from '../util/web3_wrapper'; import { BuyOrderStateButtons } from '../components/buy_order_state_buttons'; import { errorUtil } from '../util/error'; diff --git a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts index a090ad8fb..6536e2787 100644 --- a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts @@ -11,12 +11,9 @@ import { ERC20AssetAmountInput } from '../components/erc20_asset_amount_input'; import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; import { ColorOption } from '../style/theme'; -import { ERC20Asset, OrderProcessState, ZeroExInstantError } from '../types'; -import { getBestAddress } from '../util/address'; -import { balanceUtil } from '../util/balance'; +import { ERC20Asset, OrderProcessState } from '../types'; import { BigNumberInput } from '../util/big_number_input'; import { errorUtil } from '../util/error'; -import { web3Wrapper } from '../util/web3_wrapper'; export interface SelectedERC20AssetAmountInputProps { fontColor?: ColorOption; diff --git a/packages/instant/src/util/balance.ts b/packages/instant/src/util/balance.ts index 9cb8b8987..24b7b99c3 100644 --- a/packages/instant/src/util/balance.ts +++ b/packages/instant/src/util/balance.ts @@ -8,11 +8,6 @@ export const balanceUtil = { return false; } const balanceWei = await web3Wrapper.getBalanceInWeiAsync(takerAddress); - console.log('balanceWei', balanceWei.toString()); - console.log( - 'buyQuote.worstCaseQuoteInfo.totalEthAmount', - buyQuote.worstCaseQuoteInfo.totalEthAmount.toString(), - ); return balanceWei >= buyQuote.worstCaseQuoteInfo.totalEthAmount; }, }; -- cgit v1.2.3 From 1bb7a28690662d682f865505b6c62fe655d57316 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 29 Oct 2018 08:56:49 -0700 Subject: onPendingValidation -> onValidationPending --- packages/instant/src/components/buy_button.tsx | 4 ++-- packages/instant/src/components/buy_order_state_buttons.tsx | 8 ++++---- .../src/containers/selected_asset_buy_order_state_buttons.ts | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 2f670d387..876edd396 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -15,7 +15,7 @@ import { Button, Text } from './ui'; export interface BuyButtonProps { buyQuote?: BuyQuote; assetBuyer?: AssetBuyer; - onPendingValidation: (buyQuote: BuyQuote) => void; + onValidationPending: (buyQuote: BuyQuote) => void; onValidationFail: (buyQuote: BuyQuote, error: ZeroExInstantError) => void; onSignatureDenied: (buyQuote: BuyQuote, preventedError: Error) => void; onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => void; @@ -46,7 +46,7 @@ export class BuyButton extends React.Component { return; } - this.props.onPendingValidation(buyQuote); + this.props.onValidationPending(buyQuote); const takerAddress = await getBestAddress(); const hasSufficientFunds = await balanceUtil.hasSufficientFunds(takerAddress, buyQuote, web3Wrapper); diff --git a/packages/instant/src/components/buy_order_state_buttons.tsx b/packages/instant/src/components/buy_order_state_buttons.tsx index 8225441f7..f9d683be6 100644 --- a/packages/instant/src/components/buy_order_state_buttons.tsx +++ b/packages/instant/src/components/buy_order_state_buttons.tsx @@ -17,13 +17,13 @@ export interface BuyOrderStateButtonProps { buyOrderProcessingState: OrderProcessState; assetBuyer?: AssetBuyer; onViewTransaction: () => void; - onPendingValidation: (buyQuote: BuyQuote) => void; + onValidationPending: (buyQuote: BuyQuote) => void; + onValidationFail: (buyQuote: BuyQuote, error: ZeroExInstantError) => void; onSignatureDenied: (buyQuote: BuyQuote, error: Error) => void; onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => void; onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; onRetry: () => void; - onValidationFail: (buyQuote: BuyQuote, error: ZeroExInstantError) => void; } // TODO: rename to buttons @@ -54,12 +54,12 @@ export const BuyOrderStateButtons: React.StatelessComponent ); }; diff --git a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts index d22fd7d24..1a568c1fb 100644 --- a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts +++ b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts @@ -20,7 +20,7 @@ interface ConnectedState { } interface ConnectedDispatch { - onPendingValidation: (buyQuote: BuyQuote) => void; + onValidationPending: (buyQuote: BuyQuote) => void; onSignatureDenied: (buyQuote: BuyQuote, error: Error) => void; onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => void; onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; @@ -56,7 +56,7 @@ const mapDispatchToProps = ( dispatch: Dispatch, ownProps: SelectedAssetBuyOrderStateButtons, ): ConnectedDispatch => ({ - onPendingValidation: (buyQuote: BuyQuote) => { + onValidationPending: (buyQuote: BuyQuote) => { const newOrderState: OrderState = { processState: OrderProcessState.VALIDATING }; dispatch(actions.updateBuyOrderState(newOrderState)); }, -- cgit v1.2.3 From 8288e8cce963bbd96c71b3adeb5d34bb96c30693 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 29 Oct 2018 09:03:39 -0700 Subject: When transaction too low, treat as validation error. also modify callback: errorMessage could be AssetBuyError as well --- packages/instant/src/components/buy_button.tsx | 13 +++++++++---- packages/instant/src/components/buy_order_state_buttons.tsx | 4 ++-- .../containers/selected_asset_buy_order_state_buttons.ts | 4 ++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 876edd396..bceabbca3 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -16,7 +16,7 @@ export interface BuyButtonProps { buyQuote?: BuyQuote; assetBuyer?: AssetBuyer; onValidationPending: (buyQuote: BuyQuote) => void; - onValidationFail: (buyQuote: BuyQuote, error: ZeroExInstantError) => void; + onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void; onSignatureDenied: (buyQuote: BuyQuote, preventedError: Error) => void; onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => void; onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; @@ -59,9 +59,14 @@ export class BuyButton extends React.Component { try { txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { takerAddress }); } catch (e) { - if (e instanceof Error && e.message === AssetBuyerError.SignatureRequestDenied) { - this.props.onSignatureDenied(buyQuote, e); - return; + if (e instanceof Error) { + if (e.message === AssetBuyerError.SignatureRequestDenied) { + this.props.onSignatureDenied(buyQuote, e); + return; + } else if (e.message === AssetBuyerError.TransactionValueTooLow) { + this.props.onValidationFail(buyQuote, AssetBuyerError.TransactionValueTooLow); + return; + } } throw e; } diff --git a/packages/instant/src/components/buy_order_state_buttons.tsx b/packages/instant/src/components/buy_order_state_buttons.tsx index f9d683be6..7c06ff31b 100644 --- a/packages/instant/src/components/buy_order_state_buttons.tsx +++ b/packages/instant/src/components/buy_order_state_buttons.tsx @@ -1,4 +1,4 @@ -import { AssetBuyer, BuyQuote } from '@0x/asset-buyer'; +import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; import * as React from 'react'; import { BuyButton } from '../components/buy_button'; @@ -18,7 +18,7 @@ export interface BuyOrderStateButtonProps { assetBuyer?: AssetBuyer; onViewTransaction: () => void; onValidationPending: (buyQuote: BuyQuote) => void; - onValidationFail: (buyQuote: BuyQuote, error: ZeroExInstantError) => void; + onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void; onSignatureDenied: (buyQuote: BuyQuote, error: Error) => void; onBuyProcessing: (buyQuote: BuyQuote, txHash: string) => void; onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; diff --git a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts index 1a568c1fb..241c0192c 100644 --- a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts +++ b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts @@ -1,4 +1,4 @@ -import { AssetBuyer, BuyQuote } from '@0x/asset-buyer'; +import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; import * as _ from 'lodash'; import * as React from 'react'; import { connect } from 'react-redux'; @@ -26,7 +26,7 @@ interface ConnectedDispatch { onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void; onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void; onRetry: () => void; - onValidationFail: (buyQuote: BuyQuote, error: ZeroExInstantError) => void; + onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void; } export interface SelectedAssetBuyOrderStateButtons {} const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyOrderStateButtons): ConnectedState => ({ -- cgit v1.2.3 From 7ed44f7b2f0224b4169f0a8f34bae09e8c6b986f Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 29 Oct 2018 09:07:40 -0700 Subject: Has Sufficient Funds/Balance -> Has Sufficient ETH --- packages/instant/src/components/buy_button.tsx | 6 +++--- packages/instant/src/types.ts | 2 +- packages/instant/src/util/balance.ts | 2 +- packages/instant/src/util/error.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index bceabbca3..bcd435250 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -49,9 +49,9 @@ export class BuyButton extends React.Component { this.props.onValidationPending(buyQuote); const takerAddress = await getBestAddress(); - const hasSufficientFunds = await balanceUtil.hasSufficientFunds(takerAddress, buyQuote, web3Wrapper); - if (!hasSufficientFunds) { - this.props.onValidationFail(buyQuote, ZeroExInstantError.InsufficientBalance); + const hasSufficentEth = await balanceUtil.hasSufficentEth(takerAddress, buyQuote, web3Wrapper); + if (!hasSufficentEth) { + this.props.onValidationFail(buyQuote, ZeroExInstantError.InsufficientETH); return; } diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index 9dd5624b6..c02b66990 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -72,5 +72,5 @@ export enum Network { export enum ZeroExInstantError { AssetMetaDataNotAvailable = 'ASSET_META_DATA_NOT_AVAILABLE', - InsufficientBalance = 'INSUFFICIENT_BALANCE', + InsufficientETH = 'INSUFFICIENT_ETH', } diff --git a/packages/instant/src/util/balance.ts b/packages/instant/src/util/balance.ts index 24b7b99c3..533656858 100644 --- a/packages/instant/src/util/balance.ts +++ b/packages/instant/src/util/balance.ts @@ -3,7 +3,7 @@ import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; export const balanceUtil = { - hasSufficientFunds: async (takerAddress: string | undefined, buyQuote: BuyQuote, web3Wrapper: Web3Wrapper) => { + hasSufficentEth: async (takerAddress: string | undefined, buyQuote: BuyQuote, web3Wrapper: Web3Wrapper) => { if (_.isUndefined(takerAddress)) { return false; } diff --git a/packages/instant/src/util/error.ts b/packages/instant/src/util/error.ts index 5db0c66d2..39c563c75 100644 --- a/packages/instant/src/util/error.ts +++ b/packages/instant/src/util/error.ts @@ -49,7 +49,7 @@ const humanReadableMessageForError = (error: Error, asset?: Asset): string | und if (error.message === AssetBuyerError.SignatureRequestDenied) { return 'You denied this transaction'; } - if (error.message === ZeroExInstantError.InsufficientBalance) { + if (error.message === ZeroExInstantError.InsufficientETH) { return "You don't have enough ETH"; } -- cgit v1.2.3