Extreme MVP of buying a ERC721 works
This commit is contained in:
parent
fdcad84cee
commit
90ad681a9e
@ -245,7 +245,7 @@ export class DutchAuctionContract extends BaseContract {
|
||||
return contractInstance;
|
||||
}
|
||||
constructor(abi: ContractAbi, address: string, supportedProvider: SupportedProvider, txDefaults?: Partial<TxData>) {
|
||||
super('DutchAuction', abi, address, providerUtils.standardizeOrThrow(supportedProvider), txDefaults);
|
||||
super('DutchAuction', abi, address, supportedProvider, txDefaults);
|
||||
classUtils.bindAll(this, ['_abiEncoderByFunctionSignature', 'address', 'abi', '_web3Wrapper']);
|
||||
}
|
||||
} // tslint:disable:max-file-line-count
|
||||
|
@ -74,6 +74,26 @@
|
||||
EXPONENTIAL_AT: 1000,
|
||||
DECIMAL_PLACES: 78,
|
||||
});
|
||||
const nftOrders = [
|
||||
{
|
||||
makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
|
||||
takerAddress: '0x0000000000000000000000000000000000000000',
|
||||
makerFee: '0',
|
||||
takerFee: '0',
|
||||
senderAddress: '0x0000000000000000000000000000000000000000',
|
||||
makerAssetAmount: '1',
|
||||
takerAssetAmount: '25000000000000000',
|
||||
makerAssetData:
|
||||
'0x02571792000000000000000000000000f5b0a3efb8e8e4c201e2a935f110eaaf3ffecb8d0000000000000000000000000000000000000000000000000000000000008849',
|
||||
takerAssetData: '0xf47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
||||
exchangeAddress: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b',
|
||||
feeRecipientAddress: '0x66a836664adc7c525c0cc4527dee8619d4faf669',
|
||||
salt: '73683692897280689979350475364949461624706477613931387930893215569576520901319',
|
||||
expirationTimeSeconds: '1557096652',
|
||||
signature:
|
||||
'0x1bf37ac01ba863c08f2ddba776b263af4f960326ed8d8a0a651acb4c7bce54592e5bd9826fb117ccd0d40392d26339de6e3377721fabbb3107043e4de444b24ae602',
|
||||
},
|
||||
];
|
||||
const providedOrders = [
|
||||
// Order selling REP
|
||||
{
|
||||
@ -168,7 +188,8 @@
|
||||
};
|
||||
}
|
||||
const renderOptionsOverrides = {
|
||||
orderSource: orderSourceOverride === 'provided' ? providedOrders : orderSourceOverride,
|
||||
// orderSource: orderSourceOverride === 'provided' ? providedOrders : orderSourceOverride,
|
||||
orderSource: nftOrders,
|
||||
networkId: +queryParams.getQueryParamValue('networkId') || undefined,
|
||||
defaultAssetBuyAmount: +queryParams.getQueryParamValue('defaultAssetBuyAmount') || undefined,
|
||||
availableAssetDatas: availableAssetDatasString ? JSON.parse(availableAssetDatasString) : undefined,
|
||||
@ -176,6 +197,15 @@
|
||||
affiliateInfo: affiliateInfoOverride,
|
||||
shouldDisablePushToHistory: !!queryParams.getQueryParamValue('shouldDisablePushToHistory'),
|
||||
walletDisplayName: queryParams.getQueryParamValue('walletDisplayName') || undefined,
|
||||
additionalAssetMetaDataMap: {
|
||||
'0x02571792000000000000000000000000f5b0a3efb8e8e4c201e2a935f110eaaf3ffecb8d0000000000000000000000000000000000000000000000000000000000008849': {
|
||||
assetProxyId: '0x02571792',
|
||||
name: 'Axie #34889',
|
||||
imageUrl:
|
||||
'https://storage.opensea.io/0xf5b0a3efb8e8e4c201e2a935f110eaaf3ffecb8d/34889-1549990035.png',
|
||||
primaryColor: '#b5d868',
|
||||
},
|
||||
},
|
||||
};
|
||||
return renderOptionsOverrides;
|
||||
};
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { AssetProxyId } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
|
||||
import { SelectedERC20AssetAmountInput } from '../containers/selected_erc20_asset_amount_input';
|
||||
import { ColorOption } from '../style/theme';
|
||||
import { AsyncProcessState, ERC20Asset, OrderProcessState, OrderState } from '../types';
|
||||
import { Asset, AsyncProcessState, ERC20Asset, ERC721Asset, OrderProcessState, OrderState } from '../types';
|
||||
import { format } from '../util/format';
|
||||
|
||||
import { AmountPlaceholder } from './amount_placeholder';
|
||||
@ -15,6 +16,7 @@ import { Spinner } from './ui/spinner';
|
||||
import { Text } from './ui/text';
|
||||
|
||||
export interface InstantHeadingProps {
|
||||
selectedAsset?: Asset;
|
||||
selectedAssetUnitAmount?: BigNumber;
|
||||
totalEthBaseUnitAmount?: BigNumber;
|
||||
ethUsdPrice?: BigNumber;
|
||||
@ -30,9 +32,36 @@ const ICON_COLOR = ColorOption.white;
|
||||
|
||||
export class InstantHeading extends React.PureComponent<InstantHeadingProps, {}> {
|
||||
public render(): React.ReactNode {
|
||||
const iconOrAmounts = this._renderIcon() || this._renderAmountsSection();
|
||||
const { selectedAsset } = this.props;
|
||||
return (
|
||||
<Container backgroundColor={ColorOption.primaryColor} width="100%" padding="20px">
|
||||
{this._renderAssetHeadingContent()}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
private _renderAssetHeadingContent(): React.ReactNode {
|
||||
const { selectedAsset } = this.props;
|
||||
if (_.isUndefined(selectedAsset)) {
|
||||
// TODO: Only the ERC20 flow supports selecting assets.
|
||||
return this._renderERC20AssetHeading();
|
||||
}
|
||||
if (selectedAsset.metaData.assetProxyId === AssetProxyId.ERC20) {
|
||||
return this._renderERC20AssetHeading();
|
||||
} else if (selectedAsset.metaData.assetProxyId === AssetProxyId.ERC721) {
|
||||
return this._renderERC721AssetHeading(selectedAsset as ERC721Asset);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private _renderERC721AssetHeading(asset: ERC721Asset): React.ReactNode {
|
||||
return <Container><img src={asset.metaData.imageUrl}/> </Container>;
|
||||
}
|
||||
|
||||
private _renderERC20AssetHeading(): React.ReactNode {
|
||||
const iconOrAmounts = this._renderIcon() || this._renderAmountsSection();
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Container marginBottom="5px">
|
||||
<Text
|
||||
letterSpacing="1px"
|
||||
@ -56,7 +85,7 @@ export class InstantHeading extends React.PureComponent<InstantHeadingProps, {}>
|
||||
{iconOrAmounts}
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Container>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { AssetProxyId } from '@0x/types';
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
|
||||
import PoweredByLogo from '../assets/powered_by_0x.svg';
|
||||
@ -11,7 +13,7 @@ import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_
|
||||
import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading';
|
||||
import { ColorOption } from '../style/theme';
|
||||
import { zIndex } from '../style/z_index';
|
||||
import { SlideAnimationState } from '../types';
|
||||
import { Asset, SlideAnimationState } from '../types';
|
||||
import { analytics, TokenSelectorClosedVia } from '../util/analytics';
|
||||
|
||||
import { CSSReset } from './css_reset';
|
||||
@ -84,11 +86,15 @@ export class ZeroExInstantContainer extends React.PureComponent<
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
private readonly _handleSymbolClick = (): void => {
|
||||
analytics.trackTokenSelectorOpened();
|
||||
this.setState({
|
||||
tokenSelectionPanelAnimationState: 'slidIn',
|
||||
});
|
||||
private readonly _handleSymbolClick = (asset?: Asset): void => {
|
||||
if (_.isUndefined(asset) || asset.metaData.assetProxyId === AssetProxyId.ERC20) {
|
||||
analytics.trackTokenSelectorOpened();
|
||||
this.setState({
|
||||
tokenSelectionPanelAnimationState: 'slidIn',
|
||||
});
|
||||
} else if (asset.metaData.assetProxyId === AssetProxyId.ERC721) {
|
||||
// TODO: Link open sea.
|
||||
}
|
||||
};
|
||||
private readonly _handlePanelCloseClickedX = (): void => {
|
||||
this._handlePanelClose(TokenSelectorClosedVia.ClickedX);
|
||||
|
@ -18,6 +18,7 @@ import { gasPriceEstimator } from '../util/gas_price_estimator';
|
||||
import { Heartbeater } from '../util/heartbeater';
|
||||
import { generateAccountHeartbeater, generateBuyQuoteHeartbeater } from '../util/heartbeater_factory';
|
||||
import { providerStateFactory } from '../util/provider_state_factory';
|
||||
import { AssetProxyId } from '@0x/types';
|
||||
|
||||
export type ZeroExInstantProviderProps = ZeroExInstantBaseConfig;
|
||||
|
||||
@ -46,22 +47,30 @@ export class ZeroExInstantProvider extends React.PureComponent<ZeroExInstantProv
|
||||
..._.mapKeys(props.additionalAssetMetaDataMap || {}, (value, key) => key.toLowerCase()),
|
||||
...defaultState.assetMetaDataMap,
|
||||
};
|
||||
|
||||
const selectedAsset = _.isUndefined(props.defaultSelectedAssetData)
|
||||
? undefined
|
||||
: assetUtils.createAssetFromAssetDataOrThrow(
|
||||
props.defaultSelectedAssetData,
|
||||
completeAssetMetaDataMap,
|
||||
networkId,
|
||||
);
|
||||
|
||||
let selectedAssetUnitAmount: BigNumber | undefined = new BigNumber(1);
|
||||
if (!_.isUndefined(selectedAsset) && selectedAsset.metaData.assetProxyId === AssetProxyId.ERC20) {
|
||||
selectedAssetUnitAmount = _.isUndefined(props.defaultAssetBuyAmount)
|
||||
? undefined
|
||||
: new BigNumber(props.defaultAssetBuyAmount);
|
||||
}
|
||||
|
||||
// construct the final state
|
||||
const storeStateFromProps: State = {
|
||||
...defaultState,
|
||||
providerState,
|
||||
network: networkId,
|
||||
walletDisplayName: props.walletDisplayName,
|
||||
selectedAsset: _.isUndefined(props.defaultSelectedAssetData)
|
||||
? undefined
|
||||
: assetUtils.createAssetFromAssetDataOrThrow(
|
||||
props.defaultSelectedAssetData,
|
||||
completeAssetMetaDataMap,
|
||||
networkId,
|
||||
),
|
||||
selectedAssetUnitAmount: _.isUndefined(props.defaultAssetBuyAmount)
|
||||
? undefined
|
||||
: new BigNumber(props.defaultAssetBuyAmount),
|
||||
selectedAsset,
|
||||
selectedAssetUnitAmount,
|
||||
availableAssets: _.isUndefined(props.availableAssetDatas)
|
||||
? undefined
|
||||
: assetUtils.createAssetsFromAssetDatas(props.availableAssetDatas, completeAssetMetaDataMap, networkId),
|
||||
|
@ -16,7 +16,8 @@ export const ONE_SECOND_MS = 1000;
|
||||
export const ONE_MINUTE_MS = ONE_SECOND_MS * 60;
|
||||
export const GIT_SHA = process.env.GIT_SHA;
|
||||
export const NODE_ENV = process.env.NODE_ENV;
|
||||
export const SLIPPAGE_PERCENTAGE = 0.2;
|
||||
export const ERC20_BUY_QUOTE_SLIPPAGE_PERCENTAGE = 0.2;
|
||||
export const ERC721_BUY_QUOTE_SLIPPAGE_PERCENTAGE = 0;
|
||||
export const NPM_PACKAGE_VERSION = process.env.NPM_PACKAGE_VERSION;
|
||||
export const DEFAULT_UNKOWN_ASSET_NAME = '???';
|
||||
export const ACCOUNT_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 5;
|
||||
|
@ -5,15 +5,16 @@ import { connect } from 'react-redux';
|
||||
import { oc } from 'ts-optchain';
|
||||
|
||||
import { State } from '../redux/reducer';
|
||||
import { AsyncProcessState, ERC20Asset, OrderState } from '../types';
|
||||
import { Asset, AsyncProcessState, OrderState } from '../types';
|
||||
|
||||
import { InstantHeading } from '../components/instant_heading';
|
||||
|
||||
export interface InstantHeadingProps {
|
||||
onSelectAssetClick?: (asset?: ERC20Asset) => void;
|
||||
onSelectAssetClick?: (asset?: Asset) => void;
|
||||
}
|
||||
|
||||
interface ConnectedState {
|
||||
selectedAsset?: Asset;
|
||||
selectedAssetUnitAmount?: BigNumber;
|
||||
totalEthBaseUnitAmount?: BigNumber;
|
||||
ethUsdPrice?: BigNumber;
|
||||
@ -22,6 +23,7 @@ interface ConnectedState {
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: State, _ownProps: InstantHeadingProps): ConnectedState => ({
|
||||
selectedAsset: state.selectedAsset,
|
||||
selectedAssetUnitAmount: state.selectedAssetUnitAmount,
|
||||
totalEthBaseUnitAmount: oc(state).latestBuyQuote.worstCaseQuoteInfo.totalEthAmount(),
|
||||
ethUsdPrice: state.ethUsdPrice,
|
||||
|
@ -100,13 +100,12 @@ export const asyncData = {
|
||||
!_.isUndefined(selectedAssetUnitAmount) &&
|
||||
!_.isUndefined(selectedAsset) &&
|
||||
selectedAssetUnitAmount.isGreaterThan(BIG_NUMBER_ZERO) &&
|
||||
buyOrderState.processState === OrderProcessState.None &&
|
||||
selectedAsset.metaData.assetProxyId === AssetProxyId.ERC20
|
||||
buyOrderState.processState === OrderProcessState.None
|
||||
) {
|
||||
await buyQuoteUpdater.updateBuyQuoteAsync(
|
||||
assetBuyer,
|
||||
dispatch,
|
||||
selectedAsset as ERC20Asset,
|
||||
selectedAsset,
|
||||
selectedAssetUnitAmount,
|
||||
fetchOrigin,
|
||||
{
|
||||
|
@ -109,17 +109,17 @@ export const assetUtils = {
|
||||
);
|
||||
return _.compact(erc20sOrUndefined);
|
||||
},
|
||||
assetBuyerErrorMessage: (asset: ERC20Asset, error: Error): string | undefined => {
|
||||
assetBuyerErrorMessage: (asset: Asset, error: Error): string | undefined => {
|
||||
if (error.message === AssetBuyerError.InsufficientAssetLiquidity) {
|
||||
const assetName = assetUtils.bestNameForAsset(asset, 'of this asset');
|
||||
if (
|
||||
error instanceof InsufficientAssetLiquidityError &&
|
||||
error.amountAvailableToFill.isGreaterThan(BIG_NUMBER_ZERO)
|
||||
) {
|
||||
const unitAmountAvailableToFill = Web3Wrapper.toUnitAmount(
|
||||
error.amountAvailableToFill,
|
||||
asset.metaData.decimals,
|
||||
);
|
||||
const unitAmountAvailableToFill =
|
||||
asset.metaData.assetProxyId === AssetProxyId.ERC20
|
||||
? Web3Wrapper.toUnitAmount(error.amountAvailableToFill, asset.metaData.decimals)
|
||||
: error.amountAvailableToFill;
|
||||
const roundedUnitAmountAvailableToFill = unitAmountAvailableToFill.decimalPlaces(
|
||||
2,
|
||||
BigNumber.ROUND_DOWN,
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { AssetBuyer, BuyQuote } from '@0x/asset-buyer';
|
||||
import { AssetProxyId } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import * as _ from 'lodash';
|
||||
import { Dispatch } from 'redux';
|
||||
import { oc } from 'ts-optchain';
|
||||
|
||||
import { SLIPPAGE_PERCENTAGE } from '../constants';
|
||||
import { ERC20_BUY_QUOTE_SLIPPAGE_PERCENTAGE, ERC721_BUY_QUOTE_SLIPPAGE_PERCENTAGE } from '../constants';
|
||||
import { Action, actions } from '../redux/actions';
|
||||
import { AffiliateInfo, ERC20Asset, QuoteFetchOrigin } from '../types';
|
||||
import { AffiliateInfo, Asset, QuoteFetchOrigin } from '../types';
|
||||
import { analytics } from '../util/analytics';
|
||||
import { assetUtils } from '../util/asset';
|
||||
import { errorFlasher } from '../util/error_flasher';
|
||||
@ -17,7 +18,7 @@ export const buyQuoteUpdater = {
|
||||
updateBuyQuoteAsync: async (
|
||||
assetBuyer: AssetBuyer,
|
||||
dispatch: Dispatch<Action>,
|
||||
asset: ERC20Asset,
|
||||
asset: Asset,
|
||||
assetUnitAmount: BigNumber,
|
||||
fetchOrigin: QuoteFetchOrigin,
|
||||
options: {
|
||||
@ -27,14 +28,20 @@ export const buyQuoteUpdater = {
|
||||
},
|
||||
): Promise<void> => {
|
||||
// get a new buy quote.
|
||||
const baseUnitValue = Web3Wrapper.toBaseUnitAmount(assetUnitAmount, asset.metaData.decimals);
|
||||
const baseUnitValue =
|
||||
asset.metaData.assetProxyId === AssetProxyId.ERC20
|
||||
? Web3Wrapper.toBaseUnitAmount(assetUnitAmount, asset.metaData.decimals)
|
||||
: assetUnitAmount;
|
||||
if (options.setPending) {
|
||||
// mark quote as pending
|
||||
dispatch(actions.setQuoteRequestStatePending());
|
||||
}
|
||||
const feePercentage = oc(options.affiliateInfo).feePercentage();
|
||||
let newBuyQuote: BuyQuote | undefined;
|
||||
const slippagePercentage = SLIPPAGE_PERCENTAGE;
|
||||
const slippagePercentage =
|
||||
asset.metaData.assetProxyId === AssetProxyId.ERC20
|
||||
? ERC20_BUY_QUOTE_SLIPPAGE_PERCENTAGE
|
||||
: ERC721_BUY_QUOTE_SLIPPAGE_PERCENTAGE;
|
||||
try {
|
||||
newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue, {
|
||||
feePercentage,
|
||||
|
Loading…
x
Reference in New Issue
Block a user