refactored and added fees

This commit is contained in:
David Sun
2019-11-15 16:34:30 -05:00
committed by Jacob Evans
parent 9a552012f2
commit 46e0bc940a
16 changed files with 126 additions and 74 deletions

View File

@@ -8,6 +8,7 @@ import {
SwapQuoteGetOutputOpts, SwapQuoteGetOutputOpts,
SwapQuoteRequestOpts, SwapQuoteRequestOpts,
SwapQuoterOpts, SwapQuoterOpts,
ExtensionContractType,
} from './types'; } from './types';
const ETH_GAS_STATION_API_BASE_URL = 'https://ethgasstation.info'; const ETH_GAS_STATION_API_BASE_URL = 'https://ethgasstation.info';
@@ -35,13 +36,17 @@ const DEFAULT_SWAP_QUOTER_OPTS: SwapQuoterOpts = {
...DEFAULT_ORDER_PRUNER_OPTS, ...DEFAULT_ORDER_PRUNER_OPTS,
}; };
const DEFAULT_FORWARDER_SWAP_QUOTE_GET_OPTS: SwapQuoteGetOutputOpts & ForwarderExtensionContractOpts = { const DEFAULT_FORWARDER_EXTENSION_CONTRACT_OPTS: ForwarderExtensionContractOpts = {
feePercentage: 0, feePercentage: 0,
feeRecipient: NULL_ADDRESS, feeRecipient: NULL_ADDRESS,
}; };
const DEFAULT_FORWARDER_SWAP_QUOTE_EXECUTE_OPTS: SwapQuoteExecutionOpts & const DEFAULT_FORWARDER_SWAP_QUOTE_GET_OPTS: SwapQuoteGetOutputOpts = {
ForwarderExtensionContractOpts = DEFAULT_FORWARDER_SWAP_QUOTE_GET_OPTS; useExtensionContract: ExtensionContractType.Forwarder,
extensionContractOpts: DEFAULT_FORWARDER_EXTENSION_CONTRACT_OPTS,
};
const DEFAULT_FORWARDER_SWAP_QUOTE_EXECUTE_OPTS: SwapQuoteExecutionOpts = DEFAULT_FORWARDER_SWAP_QUOTE_GET_OPTS;
const DEFAULT_SWAP_QUOTE_REQUEST_OPTS: SwapQuoteRequestOpts = { const DEFAULT_SWAP_QUOTE_REQUEST_OPTS: SwapQuoteRequestOpts = {
slippagePercentage: 0.2, // 20% slippage protection, slippagePercentage: 0.2, // 20% slippage protection,

View File

@@ -37,7 +37,6 @@ export {
SwapQuoteConsumerOpts, SwapQuoteConsumerOpts,
CalldataInfo, CalldataInfo,
ExtensionContractType, ExtensionContractType,
SwapQuoteConsumingOpts,
LiquidityForTakerMakerAssetDataPair, LiquidityForTakerMakerAssetDataPair,
SwapQuoteGetOutputOpts, SwapQuoteGetOutputOpts,
PrunedSignedOrder, PrunedSignedOrder,

View File

@@ -54,7 +54,7 @@ export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumerBase<Forward
*/ */
public async getCalldataOrThrowAsync( public async getCalldataOrThrowAsync(
quote: SwapQuote, quote: SwapQuote,
opts: Partial<SwapQuoteGetOutputOpts & ForwarderExtensionContractOpts> = {}, opts: Partial<SwapQuoteGetOutputOpts> = {},
): Promise<CalldataInfo> { ): Promise<CalldataInfo> {
assert.isValidForwarderSwapQuote('quote', quote, await this._getEtherTokenAssetDataOrThrowAsync()); assert.isValidForwarderSwapQuote('quote', quote, await this._getEtherTokenAssetDataOrThrowAsync());
@@ -86,21 +86,19 @@ export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumerBase<Forward
*/ */
public async getSmartContractParamsOrThrowAsync( public async getSmartContractParamsOrThrowAsync(
quote: SwapQuote, quote: SwapQuote,
opts: Partial<SwapQuoteGetOutputOpts & ForwarderExtensionContractOpts> = {}, opts: Partial<SwapQuoteGetOutputOpts> = {},
): Promise<SmartContractParamsInfo<ForwarderSmartContractParams>> { ): Promise<SmartContractParamsInfo<ForwarderSmartContractParams>> {
assert.isValidForwarderSwapQuote('quote', quote, await this._getEtherTokenAssetDataOrThrowAsync()); assert.isValidForwarderSwapQuote('quote', quote, await this._getEtherTokenAssetDataOrThrowAsync());
const { ethAmount: providedEthAmount, feeRecipient, feePercentage } = _.merge( const { extensionContractOpts } = _.merge(
{}, {},
constants.DEFAULT_FORWARDER_SWAP_QUOTE_GET_OPTS, constants.DEFAULT_FORWARDER_SWAP_QUOTE_GET_OPTS,
opts, opts,
); );
assert.isValidPercentage('feePercentage', feePercentage); assert.isValidForwarderExtensionContractOpts('extensionContractOpts', extensionContractOpts);
assert.isETHAddressHex('feeRecipient', feeRecipient);
if (providedEthAmount !== undefined) { const { feeRecipient, feePercentage } = extensionContractOpts;
assert.isBigNumber('ethAmount', providedEthAmount);
}
const { orders, worstCaseQuoteInfo } = quote; const { orders, worstCaseQuoteInfo } = quote;
@@ -146,7 +144,7 @@ export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumerBase<Forward
return { return {
params, params,
toAddress: this._forwarder.address, toAddress: this._forwarder.address,
ethAmount: providedEthAmount || ethAmountWithFees, ethAmount: ethAmountWithFees,
methodAbi, methodAbi,
}; };
} }
@@ -158,18 +156,20 @@ export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumerBase<Forward
*/ */
public async executeSwapQuoteOrThrowAsync( public async executeSwapQuoteOrThrowAsync(
quote: SwapQuote, quote: SwapQuote,
opts: Partial<SwapQuoteExecutionOpts & ForwarderExtensionContractOpts>, opts: Partial<SwapQuoteExecutionOpts>,
): Promise<string> { ): Promise<string> {
assert.isValidForwarderSwapQuote('quote', quote, await this._getEtherTokenAssetDataOrThrowAsync()); assert.isValidForwarderSwapQuote('quote', quote, await this._getEtherTokenAssetDataOrThrowAsync());
const { ethAmount: providedEthAmount, takerAddress, gasLimit, gasPrice, feeRecipient, feePercentage } = _.merge( const { ethAmount: providedEthAmount, takerAddress, gasLimit, gasPrice, extensionContractOpts } = _.merge(
{}, {},
constants.DEFAULT_FORWARDER_SWAP_QUOTE_EXECUTE_OPTS, constants.DEFAULT_FORWARDER_SWAP_QUOTE_EXECUTE_OPTS,
opts, opts,
); );
assert.isValidPercentage('feePercentage', feePercentage); assert.isValidForwarderExtensionContractOpts('extensionContractOpts', extensionContractOpts);
assert.isETHAddressHex('feeRecipient', feeRecipient);
const { feeRecipient, feePercentage } = extensionContractOpts;
if (providedEthAmount !== undefined) { if (providedEthAmount !== undefined) {
assert.isBigNumber('ethAmount', providedEthAmount); assert.isBigNumber('ethAmount', providedEthAmount);
} }

View File

@@ -13,7 +13,6 @@ import {
SwapQuote, SwapQuote,
SwapQuoteConsumerBase, SwapQuoteConsumerBase,
SwapQuoteConsumerOpts, SwapQuoteConsumerOpts,
SwapQuoteConsumingOpts,
SwapQuoteExecutionOpts, SwapQuoteExecutionOpts,
SwapQuoteGetOutputOpts, SwapQuoteGetOutputOpts,
} from '../types'; } from '../types';
@@ -57,7 +56,7 @@ export class SwapQuoteConsumer implements SwapQuoteConsumerBase<SmartContractPar
*/ */
public async getCalldataOrThrowAsync( public async getCalldataOrThrowAsync(
quote: SwapQuote, quote: SwapQuote,
opts: Partial<SwapQuoteGetOutputOpts & SwapQuoteConsumingOpts> = {}, opts: Partial<SwapQuoteGetOutputOpts> = {},
): Promise<CalldataInfo> { ): Promise<CalldataInfo> {
assert.isValidSwapQuote('quote', quote); assert.isValidSwapQuote('quote', quote);
const consumer = await this._getConsumerForSwapQuoteAsync(opts); const consumer = await this._getConsumerForSwapQuoteAsync(opts);
@@ -71,7 +70,7 @@ export class SwapQuoteConsumer implements SwapQuoteConsumerBase<SmartContractPar
*/ */
public async getSmartContractParamsOrThrowAsync( public async getSmartContractParamsOrThrowAsync(
quote: SwapQuote, quote: SwapQuote,
opts: Partial<SwapQuoteGetOutputOpts & SwapQuoteConsumingOpts> = {}, opts: Partial<SwapQuoteGetOutputOpts> = {},
): Promise<SmartContractParamsInfo<SmartContractParams>> { ): Promise<SmartContractParamsInfo<SmartContractParams>> {
assert.isValidSwapQuote('quote', quote); assert.isValidSwapQuote('quote', quote);
const consumer = await this._getConsumerForSwapQuoteAsync(opts); const consumer = await this._getConsumerForSwapQuoteAsync(opts);
@@ -85,7 +84,7 @@ export class SwapQuoteConsumer implements SwapQuoteConsumerBase<SmartContractPar
*/ */
public async executeSwapQuoteOrThrowAsync( public async executeSwapQuoteOrThrowAsync(
quote: SwapQuote, quote: SwapQuote,
opts: Partial<SwapQuoteExecutionOpts & SwapQuoteConsumingOpts> = {}, opts: Partial<SwapQuoteExecutionOpts> = {},
): Promise<string> { ): Promise<string> {
assert.isValidSwapQuote('quote', quote); assert.isValidSwapQuote('quote', quote);
const consumer = await this._getConsumerForSwapQuoteAsync(opts); const consumer = await this._getConsumerForSwapQuoteAsync(opts);
@@ -110,7 +109,7 @@ export class SwapQuoteConsumer implements SwapQuoteConsumerBase<SmartContractPar
} }
private async _getConsumerForSwapQuoteAsync( private async _getConsumerForSwapQuoteAsync(
opts: Partial<SwapQuoteConsumingOpts>, opts: Partial<SwapQuoteGetOutputOpts>,
): Promise<SwapQuoteConsumerBase<SmartContractParams>> { ): Promise<SwapQuoteConsumerBase<SmartContractParams>> {
if (opts.useExtensionContract === ExtensionContractType.Forwarder) { if (opts.useExtensionContract === ExtensionContractType.Forwarder) {
return this._forwarderConsumer; return this._forwarderConsumer;

View File

@@ -1,6 +1,7 @@
import { SignedOrder } from '@0x/types'; import { SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import { MethodAbi } from 'ethereum-types'; import { MethodAbi } from 'ethereum-types';
import { ForwarderSwapQuoteConsumer } from '@0x/asset-swapper/src/quote_consumers/forwarder_swap_quote_consumer';
/** /**
* expiryBufferMs: The number of seconds to add when calculating whether an order is expired or not. Defaults to 300s (5m). * expiryBufferMs: The number of seconds to add when calculating whether an order is expired or not. Defaults to 300s (5m).
@@ -167,7 +168,10 @@ export interface SwapQuoteConsumerOpts {
/** /**
* Represents the options provided to a generic SwapQuoteConsumer * Represents the options provided to a generic SwapQuoteConsumer
*/ */
export interface SwapQuoteGetOutputOpts {} export interface SwapQuoteGetOutputOpts {
useExtensionContract: ExtensionContractType;
extensionContractOpts?: ForwarderExtensionContractOpts | any;
}
/** /**
* takerAddress: The address to perform the buy. Defaults to the first available address from the provider. * takerAddress: The address to perform the buy. Defaults to the first available address from the provider.
@@ -176,10 +180,10 @@ export interface SwapQuoteGetOutputOpts {}
* ethAmount: The amount of eth sent with the execution of a swap * ethAmount: The amount of eth sent with the execution of a swap
*/ */
export interface SwapQuoteExecutionOpts extends SwapQuoteGetOutputOpts { export interface SwapQuoteExecutionOpts extends SwapQuoteGetOutputOpts {
ethAmount?: BigNumber;
gasPrice?: BigNumber;
takerAddress?: string; takerAddress?: string;
gasLimit?: number; gasLimit?: number;
gasPrice?: BigNumber;
ethAmount?: BigNumber;
} }
/** /**
@@ -188,18 +192,10 @@ export interface SwapQuoteExecutionOpts extends SwapQuoteGetOutputOpts {
* feeRecipient: address of the receiver of the feePercentage of taker asset * feeRecipient: address of the receiver of the feePercentage of taker asset
*/ */
export interface ForwarderExtensionContractOpts { export interface ForwarderExtensionContractOpts {
ethAmount?: BigNumber;
feePercentage: number; feePercentage: number;
feeRecipient: string; feeRecipient: string;
} }
/*
* Options for how SwapQuoteConsumer will generate output
*/
export interface SwapQuoteConsumingOpts {
useExtensionContract: ExtensionContractType;
}
export type SwapQuote = MarketBuySwapQuote | MarketSellSwapQuote; export type SwapQuote = MarketBuySwapQuote | MarketSellSwapQuote;
export interface GetExtensionContractTypeOpts { export interface GetExtensionContractTypeOpts {

View File

@@ -96,4 +96,8 @@ export const assert = {
`Expected ${variableName} to be between 0 and 1, but is ${percentage}`, `Expected ${variableName} to be between 0 and 1, but is ${percentage}`,
); );
}, },
isValidForwarderExtensionContractOpts(variableName: string, opts: any): void {
assert.isValidPercentage(`${variableName}.feePercentage`, opts.feePercentage);
assert.isETHAddressHex(`${variableName}.feeRecipient`, opts.feeRecipient);
},
}; };

View File

@@ -270,8 +270,10 @@ describe('ForwarderSwapQuoteConsumer', () => {
takerAddress, takerAddress,
gasPrice: GAS_PRICE, gasPrice: GAS_PRICE,
gasLimit: 4000000, gasLimit: 4000000,
feePercentage: FEE_PERCENTAGE, extensionContractOpts: {
feeRecipient, feePercentage: 0.05,
feeRecipient,
},
}); });
await expectMakerAndTakerBalancesAsync( await expectMakerAndTakerBalancesAsync(
constants.ZERO_AMOUNT, constants.ZERO_AMOUNT,
@@ -294,10 +296,11 @@ describe('ForwarderSwapQuoteConsumer', () => {
const feeRecipientEthBalanceBefore = await web3Wrapper.getBalanceInWeiAsync(feeRecipient); const feeRecipientEthBalanceBefore = await web3Wrapper.getBalanceInWeiAsync(feeRecipient);
await swapQuoteConsumer.executeSwapQuoteOrThrowAsync(marketSellSwapQuote, { await swapQuoteConsumer.executeSwapQuoteOrThrowAsync(marketSellSwapQuote, {
takerAddress, takerAddress,
feePercentage: FEE_PERCENTAGE,
feeRecipient,
gasPrice: GAS_PRICE,
gasLimit: 4000000, gasLimit: 4000000,
extensionContractOpts: {
feePercentage: 0.05,
feeRecipient,
},
}); });
await expectMakerAndTakerBalancesAsync( await expectMakerAndTakerBalancesAsync(
constants.ZERO_AMOUNT, constants.ZERO_AMOUNT,
@@ -370,8 +373,10 @@ describe('ForwarderSwapQuoteConsumer', () => {
const { toAddress, params } = await swapQuoteConsumer.getSmartContractParamsOrThrowAsync( const { toAddress, params } = await swapQuoteConsumer.getSmartContractParamsOrThrowAsync(
marketSellSwapQuote, marketSellSwapQuote,
{ {
feePercentage: 0.05, extensionContractOpts: {
feeRecipient, feePercentage: 0.05,
feeRecipient,
},
}, },
); );
expect(toAddress).to.deep.equal(forwarderContract.address); expect(toAddress).to.deep.equal(forwarderContract.address);
@@ -391,8 +396,10 @@ describe('ForwarderSwapQuoteConsumer', () => {
const { toAddress, params } = await swapQuoteConsumer.getSmartContractParamsOrThrowAsync( const { toAddress, params } = await swapQuoteConsumer.getSmartContractParamsOrThrowAsync(
marketBuySwapQuote, marketBuySwapQuote,
{ {
feePercentage: 0.05, extensionContractOpts: {
feeRecipient, feePercentage: 0.05,
feeRecipient,
},
}, },
); );
expect(toAddress).to.deep.equal(forwarderContract.address); expect(toAddress).to.deep.equal(forwarderContract.address);
@@ -480,8 +487,10 @@ describe('ForwarderSwapQuoteConsumer', () => {
const { calldataHexString, toAddress, ethAmount } = await swapQuoteConsumer.getCalldataOrThrowAsync( const { calldataHexString, toAddress, ethAmount } = await swapQuoteConsumer.getCalldataOrThrowAsync(
marketSellSwapQuote, marketSellSwapQuote,
{ {
feePercentage: FEE_PERCENTAGE, extensionContractOpts: {
feeRecipient, feePercentage: 0.05,
feeRecipient,
},
}, },
); );
expect(toAddress).to.deep.equal(contractAddresses.forwarder); expect(toAddress).to.deep.equal(contractAddresses.forwarder);
@@ -514,8 +523,10 @@ describe('ForwarderSwapQuoteConsumer', () => {
const { calldataHexString, toAddress, ethAmount } = await swapQuoteConsumer.getCalldataOrThrowAsync( const { calldataHexString, toAddress, ethAmount } = await swapQuoteConsumer.getCalldataOrThrowAsync(
marketBuySwapQuote, marketBuySwapQuote,
{ {
feePercentage: FEE_PERCENTAGE, extensionContractOpts: {
feeRecipient, feePercentage: 0.05,
feeRecipient,
},
}, },
); );
expect(toAddress).to.deep.equal(contractAddresses.forwarder); expect(toAddress).to.deep.equal(contractAddresses.forwarder);

View File

@@ -64,7 +64,6 @@ export class BuyButton extends React.PureComponent<BuyButtonProps> {
return; return;
} }
this.props.onValidationPending(swapQuote); this.props.onValidationPending(swapQuote);
// TODO(dave4506)
const ethNeededForBuy = affiliateFeeUtils.getTotalEthAmountWithAffiliateFee(swapQuote.worstCaseQuoteInfo, 0); const ethNeededForBuy = affiliateFeeUtils.getTotalEthAmountWithAffiliateFee(swapQuote.worstCaseQuoteInfo, 0);
// if we don't have a balance for the user, let the transaction through, it will be handled by the wallet // if we don't have a balance for the user, let the transaction through, it will be handled by the wallet
const hasSufficientEth = accountEthBalanceInWei === undefined || accountEthBalanceInWei.gte(ethNeededForBuy); const hasSufficientEth = accountEthBalanceInWei === undefined || accountEthBalanceInWei.gte(ethNeededForBuy);
@@ -76,11 +75,15 @@ export class BuyButton extends React.PureComponent<BuyButtonProps> {
let txHash: string | undefined; let txHash: string | undefined;
const gasInfo = await gasPriceEstimator.getGasInfoAsync(); const gasInfo = await gasPriceEstimator.getGasInfoAsync();
const feeRecipient = oc(affiliateInfo).feeRecipient(); const feeRecipient = oc(affiliateInfo).feeRecipient();
const feePercentage = oc(affiliateInfo).feeRecipient();
try { try {
analytics.trackBuyStarted(swapQuote); analytics.trackBuyStarted(swapQuote);
// TODO(dave4506)
txHash = await swapQuoteConsumer.executeSwapQuoteOrThrowAsync(swapQuote, { txHash = await swapQuoteConsumer.executeSwapQuoteOrThrowAsync(swapQuote, {
useExtensionContract: ExtensionContractType.Forwarder, useExtensionContract: ExtensionContractType.Forwarder,
extensionContractOpts: {
feeRecipient,
feePercentage,
},
takerAddress: accountAddress, takerAddress: accountAddress,
gasPrice: gasInfo.gasPriceInWei, gasPrice: gasInfo.gasPriceInWei,
}); });

View File

@@ -17,7 +17,7 @@ export interface BuyOrderStateButtonProps {
accountAddress?: string; accountAddress?: string;
accountEthBalanceInWei?: BigNumber; accountEthBalanceInWei?: BigNumber;
swapQuote?: MarketBuySwapQuote; swapQuote?: MarketBuySwapQuote;
buyOrderProcessingState: OrderProcessState; swapOrderProcessingState: OrderProcessState;
swapQuoter: SwapQuoter; swapQuoter: SwapQuoter;
swapQuoteConsumer: SwapQuoteConsumer; swapQuoteConsumer: SwapQuoteConsumer;
web3Wrapper: Web3Wrapper; web3Wrapper: Web3Wrapper;
@@ -34,7 +34,7 @@ export interface BuyOrderStateButtonProps {
} }
export const BuyOrderStateButtons: React.StatelessComponent<BuyOrderStateButtonProps> = props => { export const BuyOrderStateButtons: React.StatelessComponent<BuyOrderStateButtonProps> = props => {
if (props.buyOrderProcessingState === OrderProcessState.Failure) { if (props.swapOrderProcessingState === OrderProcessState.Failure) {
return ( return (
<Flex justify="space-between"> <Flex justify="space-between">
<Button width="48%" onClick={props.onRetry} fontColor={ColorOption.white}> <Button width="48%" onClick={props.onRetry} fontColor={ColorOption.white}>
@@ -46,11 +46,11 @@ export const BuyOrderStateButtons: React.StatelessComponent<BuyOrderStateButtonP
</Flex> </Flex>
); );
} else if ( } else if (
props.buyOrderProcessingState === OrderProcessState.Success || props.swapOrderProcessingState === OrderProcessState.Success ||
props.buyOrderProcessingState === OrderProcessState.Processing props.swapOrderProcessingState === OrderProcessState.Processing
) { ) {
return <SecondaryButton onClick={props.onViewTransaction}>View Transaction</SecondaryButton>; return <SecondaryButton onClick={props.onViewTransaction}>View Transaction</SecondaryButton>;
} else if (props.buyOrderProcessingState === OrderProcessState.Validating) { } else if (props.swapOrderProcessingState === OrderProcessState.Validating) {
return <PlacingOrderButton />; return <PlacingOrderButton />;
} }

View File

@@ -1,4 +1,4 @@
import { SwapQuoter, SwapQuoterError, MarketBuySwapQuote, SwapQuoteConsumer, SwapQuote } from '@0x/asset-swapper'; import { MarketBuySwapQuote, SwapQuoteConsumer, SwapQuoteConsumerError, SwapQuoter, SwapQuoterError } from '@0x/asset-swapper';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper'; import { Web3Wrapper } from '@0x/web3-wrapper';
import * as _ from 'lodash'; import * as _ from 'lodash';
@@ -34,7 +34,7 @@ interface ConnectedDispatch {
onBuySuccess: (swapQuote: MarketBuySwapQuote, txHash: string) => void; onBuySuccess: (swapQuote: MarketBuySwapQuote, txHash: string) => void;
onBuyFailure: (swapQuote: MarketBuySwapQuote, txHash: string) => void; onBuyFailure: (swapQuote: MarketBuySwapQuote, txHash: string) => void;
onRetry: () => void; onRetry: () => void;
onValidationFail: (swapQuote: MarketBuySwapQuote, errorMessage: SwapQuoterError | ZeroExInstantError) => void; onValidationFail: (swapQuote: MarketBuySwapQuote, errorMessage: SwapQuoteConsumerError | ZeroExInstantError) => void;
} }
export interface SelectedAssetBuyOrderStateButtons {} export interface SelectedAssetBuyOrderStateButtons {}
const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyOrderStateButtons): ConnectedState => { const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyOrderStateButtons): ConnectedState => {

View File

@@ -10,7 +10,7 @@ import { ERC20AssetAmountInput, ERC20AssetAmountInputProps } from '../components
import { Action, actions } from '../redux/actions'; import { Action, actions } from '../redux/actions';
import { State } from '../redux/reducer'; import { State } from '../redux/reducer';
import { ColorOption } from '../style/theme'; import { ColorOption } from '../style/theme';
import { AffiliateInfo, ERC20Asset, Omit, OrderProcessState, QuoteFetchOrigin } from '../types'; import { ERC20Asset, Omit, OrderProcessState, QuoteFetchOrigin } from '../types';
import { swapQuoteUpdater } from '../util/swap_quote_updater'; import { swapQuoteUpdater } from '../util/swap_quote_updater';
export interface SelectedERC20AssetAmountInputProps { export interface SelectedERC20AssetAmountInputProps {
@@ -25,7 +25,6 @@ interface ConnectedState {
asset?: ERC20Asset; asset?: ERC20Asset;
isInputDisabled: boolean; isInputDisabled: boolean;
numberOfAssetsAvailable?: number; numberOfAssetsAvailable?: number;
affiliateInfo?: AffiliateInfo;
canSelectOtherAsset: boolean; canSelectOtherAsset: boolean;
} }
@@ -34,7 +33,6 @@ interface ConnectedDispatch {
swapQuoter: SwapQuoter, swapQuoter: SwapQuoter,
value?: BigNumber, value?: BigNumber,
asset?: ERC20Asset, asset?: ERC20Asset,
affiliateInfo?: AffiliateInfo,
) => void; ) => void;
} }
@@ -63,7 +61,6 @@ const mapStateToProps = (state: State, _ownProps: SelectedERC20AssetAmountInputP
asset: selectedAsset, asset: selectedAsset,
isInputDisabled, isInputDisabled,
numberOfAssetsAvailable, numberOfAssetsAvailable,
affiliateInfo: state.affiliateInfo,
canSelectOtherAsset, canSelectOtherAsset,
}; };
}; };
@@ -76,7 +73,7 @@ const mapDispatchToProps = (
dispatch: Dispatch<Action>, dispatch: Dispatch<Action>,
_ownProps: SelectedERC20AssetAmountInputProps, _ownProps: SelectedERC20AssetAmountInputProps,
): ConnectedDispatch => ({ ): ConnectedDispatch => ({
updateSwapQuote: (swapQuoter, value, asset, affiliateInfo) => { updateSwapQuote: (swapQuoter, value, asset) => {
// Update the input // Update the input
dispatch(actions.updateSelectedAssetAmount(value)); dispatch(actions.updateSelectedAssetAmount(value));
// invalidate the last swap quote. // invalidate the last swap quote.
@@ -91,7 +88,6 @@ const mapDispatchToProps = (
debouncedUpdateSwapQuoteAsync(swapQuoter, dispatch, asset, value, QuoteFetchOrigin.Manual, { debouncedUpdateSwapQuoteAsync(swapQuoter, dispatch, asset, value, QuoteFetchOrigin.Manual, {
setPending: true, setPending: true,
dispatchErrors: true, dispatchErrors: true,
affiliateInfo,
}); });
} }
}, },
@@ -107,7 +103,7 @@ const mergeProps = (
asset: connectedState.asset, asset: connectedState.asset,
value: connectedState.value, value: connectedState.value,
onChange: (value, asset) => { onChange: (value, asset) => {
connectedDispatch.updateSwapQuote(connectedState.swapQuoter, value, asset, connectedState.affiliateInfo); connectedDispatch.updateSwapQuote(connectedState.swapQuoter, value, asset);
}, },
isInputDisabled: connectedState.isInputDisabled, isInputDisabled: connectedState.isInputDisabled,
numberOfAssetsAvailable: connectedState.numberOfAssetsAvailable, numberOfAssetsAvailable: connectedState.numberOfAssetsAvailable,

View File

@@ -83,7 +83,7 @@ export const unrender = () => {
const renderInstant = (config: ZeroExInstantConfig, selector: string) => { const renderInstant = (config: ZeroExInstantConfig, selector: string) => {
const appendToIfExists = document.querySelector(selector); const appendToIfExists = document.querySelector(selector);
assert.assert(appendToIfExists !== null, `Could not find div with selector: ${selector}`); assert.assert(appendToIfExists !== null, `Could not find div with selector: ${selector}`);
parentElement = appendToIfExists; parentElement = appendToIfExists as Element;
injectedDiv = document.createElement('div'); injectedDiv = document.createElement('div');
injectedDiv.setAttribute('id', INJECTED_DIV_ID); injectedDiv.setAttribute('id', INJECTED_DIV_ID);
injectedDiv.setAttribute('class', INJECTED_DIV_CLASS); injectedDiv.setAttribute('class', INJECTED_DIV_CLASS);

View File

@@ -94,7 +94,7 @@ export const asyncData = {
fetchOrigin: QuoteFetchOrigin, fetchOrigin: QuoteFetchOrigin,
options: { updateSilently: boolean }, options: { updateSilently: boolean },
) => { ) => {
const { swapOrderState, providerState, selectedAsset, selectedAssetUnitAmount, affiliateInfo } = state; const { swapOrderState, providerState, selectedAsset, selectedAssetUnitAmount } = state;
const swapQuoter = providerState.swapQuoter; const swapQuoter = providerState.swapQuoter;
if ( if (
selectedAssetUnitAmount !== undefined && selectedAssetUnitAmount !== undefined &&
@@ -111,7 +111,6 @@ export const asyncData = {
{ {
setPending: !options.updateSilently, setPending: !options.updateSilently,
dispatchErrors: !options.updateSilently, dispatchErrors: !options.updateSilently,
affiliateInfo,
}, },
); );
} }

View File

@@ -1,4 +1,4 @@
import { SwapQuote, SwapQuoter, MarketBuySwapQuote } from '@0x/asset-swapper'; import { MarketBuySwapQuote, SwapQuote, SwapQuoter } from '@0x/asset-swapper';
import { AssetProxyId } from '@0x/types'; import { AssetProxyId } from '@0x/types';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper'; import { Web3Wrapper } from '@0x/web3-wrapper';
@@ -8,7 +8,7 @@ import { oc } from 'ts-optchain';
import { ERC20_SWAP_QUOTE_SLIPPAGE_PERCENTAGE, ERC721_SWAP_QUOTE_SLIPPAGE_PERCENTAGE } from '../constants'; import { ERC20_SWAP_QUOTE_SLIPPAGE_PERCENTAGE, ERC721_SWAP_QUOTE_SLIPPAGE_PERCENTAGE } from '../constants';
import { Action, actions } from '../redux/actions'; import { Action, actions } from '../redux/actions';
import { AffiliateInfo, Asset, QuoteFetchOrigin } from '../types'; import { Asset, QuoteFetchOrigin } from '../types';
import { analytics } from './analytics'; import { analytics } from './analytics';
import { assetUtils } from './asset'; import { assetUtils } from './asset';
import { errorFlasher } from './error_flasher'; import { errorFlasher } from './error_flasher';
@@ -24,7 +24,6 @@ export const swapQuoteUpdater = {
options: { options: {
setPending: boolean; setPending: boolean;
dispatchErrors: boolean; dispatchErrors: boolean;
affiliateInfo?: AffiliateInfo;
}, },
): Promise<void> => { ): Promise<void> => {
// get a new swap quote. // get a new swap quote.
@@ -37,8 +36,7 @@ export const swapQuoteUpdater = {
dispatch(actions.setQuoteRequestStatePending()); dispatch(actions.setQuoteRequestStatePending());
} }
// TODO(dave4506) expose wethAssetData + feePercentage utils // TODO(dave4506) expose wethAssetData + feePercentage utils
const wethAssetData = ''; const wethAssetData = await swapQuoter.getEtherTokenAssetDataOrThrowAsync();
const feePercentage = oc(options.affiliateInfo).feePercentage();
let newSwapQuote: MarketBuySwapQuote | undefined; let newSwapQuote: MarketBuySwapQuote | undefined;
const slippagePercentage = const slippagePercentage =
asset.metaData.assetProxyId === AssetProxyId.ERC20 asset.metaData.assetProxyId === AssetProxyId.ERC20

View File

@@ -150,7 +150,16 @@ const generateConfig = (dischargeTarget, heapConfigOptions, rollbarConfigOptions
}, },
{ {
test: /\.svg$/, test: /\.svg$/,
loader: 'svg-react-loader', use: [
{
loader: 'react-svg-loader',
options: {
svgo: {
plugins: [{ removeViewBox: false }],
},
},
},
],
}, },
{ {
test: /\.js$/, test: /\.js$/,

View File

@@ -661,6 +661,23 @@
lodash "^4.17.11" lodash "^4.17.11"
valid-url "^1.0.9" valid-url "^1.0.9"
"@0x/asset-buyer@6.1.8":
version "6.1.8"
resolved "https://registry.yarnpkg.com/@0x/asset-buyer/-/asset-buyer-6.1.8.tgz#71f6abb366e89e62457c256644edb37e12113e94"
dependencies:
"@0x/assert" "^2.1.0"
"@0x/connect" "^5.0.13"
"@0x/contract-wrappers" "^9.1.7"
"@0x/json-schemas" "^3.0.11"
"@0x/order-utils" "^8.2.2"
"@0x/subproviders" "^4.1.1"
"@0x/types" "^2.4.0"
"@0x/typescript-typings" "^4.2.3"
"@0x/utils" "^4.4.0"
"@0x/web3-wrapper" "^6.0.7"
ethereum-types "^2.1.3"
lodash "^4.17.11"
"@0x/base-contract@^5.4.0": "@0x/base-contract@^5.4.0":
version "5.4.0" version "5.4.0"
resolved "https://registry.npmjs.org/@0x/base-contract/-/base-contract-5.4.0.tgz#466ea98af22d7e629a21a7d16211c825664e2a48" resolved "https://registry.npmjs.org/@0x/base-contract/-/base-contract-5.4.0.tgz#466ea98af22d7e629a21a7d16211c825664e2a48"
@@ -680,6 +697,22 @@
lodash "^4.17.11" lodash "^4.17.11"
uuid "^3.3.2" uuid "^3.3.2"
"@0x/connect@^5.0.13":
version "5.0.19"
resolved "https://registry.npmjs.org/@0x/connect/-/connect-5.0.19.tgz#569679af661ef84a4c34958388e1be7f1c250a04"
dependencies:
"@0x/assert" "^2.1.6"
"@0x/json-schemas" "^4.0.2"
"@0x/order-utils" "^8.4.0"
"@0x/types" "^2.4.3"
"@0x/typescript-typings" "^4.3.0"
"@0x/utils" "^4.5.2"
lodash "^4.17.11"
query-string "^6.0.0"
sinon "^4.0.0"
uuid "^3.3.2"
websocket "^1.0.26"
"@0x/contract-addresses@^3.0.1", "@0x/contract-addresses@^3.0.2", "@0x/contract-addresses@^3.2.0": "@0x/contract-addresses@^3.0.1", "@0x/contract-addresses@^3.0.2", "@0x/contract-addresses@^3.2.0":
version "3.2.0" version "3.2.0"
resolved "https://registry.npmjs.org/@0x/contract-addresses/-/contract-addresses-3.2.0.tgz#606307696d9622764220a34e9d4638b899093eec" resolved "https://registry.npmjs.org/@0x/contract-addresses/-/contract-addresses-3.2.0.tgz#606307696d9622764220a34e9d4638b899093eec"
@@ -690,7 +723,7 @@
version "2.2.2" version "2.2.2"
resolved "https://registry.npmjs.org/@0x/contract-artifacts/-/contract-artifacts-2.2.2.tgz#e6d771afb58d0b59c19c5364af5a42a3dfd17219" resolved "https://registry.npmjs.org/@0x/contract-artifacts/-/contract-artifacts-2.2.2.tgz#e6d771afb58d0b59c19c5364af5a42a3dfd17219"
"@0x/contract-wrappers@^9.1.6": "@0x/contract-wrappers@^9.1.6", "@0x/contract-wrappers@^9.1.7":
version "9.1.8" version "9.1.8"
resolved "https://registry.yarnpkg.com/@0x/contract-wrappers/-/contract-wrappers-9.1.8.tgz#5923d35af3e4b442a57d02f74e02620b2d5b1356" resolved "https://registry.yarnpkg.com/@0x/contract-wrappers/-/contract-wrappers-9.1.8.tgz#5923d35af3e4b442a57d02f74e02620b2d5b1356"
dependencies: dependencies:
@@ -774,7 +807,7 @@
uuid "^3.3.2" uuid "^3.3.2"
websocket "^1.0.29" websocket "^1.0.29"
"@0x/order-utils@^8.2.1", "@0x/order-utils@^8.2.3", "@0x/order-utils@^8.2.4", "@0x/order-utils@^8.4.0": "@0x/order-utils@^8.2.1", "@0x/order-utils@^8.2.2", "@0x/order-utils@^8.2.3", "@0x/order-utils@^8.2.4", "@0x/order-utils@^8.4.0":
version "8.4.0" version "8.4.0"
resolved "https://registry.npmjs.org/@0x/order-utils/-/order-utils-8.4.0.tgz#f7fe9c73f9fd82ab05ec3c04951049e904aab46a" resolved "https://registry.npmjs.org/@0x/order-utils/-/order-utils-8.4.0.tgz#f7fe9c73f9fd82ab05ec3c04951049e904aab46a"
dependencies: dependencies:
@@ -6717,7 +6750,7 @@ ethereum-common@^0.0.18:
version "0.0.18" version "0.0.18"
resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f"
ethereum-types@^2.1.4, ethereum-types@^2.1.6: ethereum-types@^2.1.3, ethereum-types@^2.1.4, ethereum-types@^2.1.6:
version "2.1.6" version "2.1.6"
resolved "https://registry.npmjs.org/ethereum-types/-/ethereum-types-2.1.6.tgz#57d9d515fad86ab987c0f6962c4203be37da8579" resolved "https://registry.npmjs.org/ethereum-types/-/ethereum-types-2.1.6.tgz#57d9d515fad86ab987c0f6962c4203be37da8579"
dependencies: dependencies: