From f39541436a5088e928660b61bde7cef5153bc7a1 Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 12 Oct 2018 16:11:30 -0700 Subject: feat: model asset meta data and add dynamic assetData state --- packages/instant/package.json | 1 + packages/instant/src/components/amount_input.tsx | 9 ++-- .../instant/src/components/asset_amount_input.tsx | 51 ++++++++++++++++++++++ .../instant/src/components/instant_heading.tsx | 9 +--- packages/instant/src/constants.ts | 2 +- .../src/containers/selected_asset_amount_input.ts | 31 ++++++++----- packages/instant/src/data/asset_meta_data.ts | 15 +++++++ packages/instant/src/redux/reducer.ts | 8 +++- packages/instant/src/types.ts | 22 +++++++++- 9 files changed, 121 insertions(+), 27 deletions(-) create mode 100644 packages/instant/src/components/asset_amount_input.tsx create mode 100644 packages/instant/src/data/asset_meta_data.ts (limited to 'packages') diff --git a/packages/instant/package.json b/packages/instant/package.json index ff40ba2ea..35cc39d27 100644 --- a/packages/instant/package.json +++ b/packages/instant/package.json @@ -44,6 +44,7 @@ "homepage": "https://github.com/0xProject/0x-monorepo/packages/instant/README.md", "dependencies": { "@0xproject/asset-buyer": "^2.0.0", + "@0xproject/order-utils": "^1.0.7", "@0xproject/types": "^1.1.4", "@0xproject/typescript-typings": "^2.0.2", "@0xproject/utils": "^2.0.2", diff --git a/packages/instant/src/components/amount_input.tsx b/packages/instant/src/components/amount_input.tsx index a2113f143..5b81a3d68 100644 --- a/packages/instant/src/components/amount_input.tsx +++ b/packages/instant/src/components/amount_input.tsx @@ -10,10 +10,13 @@ export interface AmountInputProps { fontColor?: ColorOption; fontSize?: string; value?: BigNumber; - onChange?: (value?: BigNumber) => void; + onChange: (value?: BigNumber) => void; } export class AmountInput extends React.Component { + public static defaultProps = { + onChange: _.noop.bind(_), + }; public render(): React.ReactNode { const { fontColor, fontSize, value } = this.props; return ( @@ -40,8 +43,6 @@ export class AmountInput extends React.Component { return; } } - if (!_.isUndefined(this.props.onChange)) { - this.props.onChange(bigNumberValue); - } + this.props.onChange(bigNumberValue); }; } diff --git a/packages/instant/src/components/asset_amount_input.tsx b/packages/instant/src/components/asset_amount_input.tsx new file mode 100644 index 000000000..915c66e1e --- /dev/null +++ b/packages/instant/src/components/asset_amount_input.tsx @@ -0,0 +1,51 @@ +import { AssetProxyId } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; +import * as React from 'react'; + +import { assetMetaData } from '../data/asset_meta_data'; +import { ColorOption } from '../style/theme'; + +import { AmountInput, AmountInputProps } from './amount_input'; +import { Container, Text } from './ui'; + +export interface AssetAmountInputProps extends AmountInputProps { + assetData?: string; + onChange: (value?: BigNumber, assetData?: string) => void; +} + +export class AssetAmountInput extends React.Component { + public static defaultProps = { + onChange: _.noop.bind(_), + }; + public render(): React.ReactNode { + const { assetData, onChange, ...rest } = this.props; + return ( + + + + + {this._getLabel()} + + + + ); + } + private readonly _getLabel = (): string => { + const unknownLabel = '???'; + if (_.isUndefined(this.props.assetData)) { + return unknownLabel; + } + const metaData = assetMetaData[this.props.assetData]; + if (_.isUndefined(metaData)) { + return unknownLabel; + } + if (metaData.assetProxyId === AssetProxyId.ERC20) { + return metaData.symbol; + } + return unknownLabel; + }; + private readonly _handleChange = (value?: BigNumber): void => { + this.props.onChange(value, this.props.assetData); + }; +} diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index 377bb20bf..492c1b2c0 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -43,14 +43,7 @@ export const InstantHeading: React.StatelessComponent = pro - - - - - zrx - - - + diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index 75afc474a..1fd321c5a 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -1,6 +1,6 @@ import { BigNumber } from '@0xproject/utils'; export const BIG_NUMBER_ZERO = new BigNumber(0); export const sraApiUrl = 'https://api.radarrelay.com/0x/v2/'; -export const zrxContractAddress = '0xe41d2489571d322189246dafa5ebde1f4699f498'; +export const zrxAssetData = '0xf47261b0000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498'; export const zrxDecimals = 18; export const ethDecimals = 18; diff --git a/packages/instant/src/containers/selected_asset_amount_input.ts b/packages/instant/src/containers/selected_asset_amount_input.ts index 9e3063ecc..f2ca96ae4 100644 --- a/packages/instant/src/containers/selected_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_asset_amount_input.ts @@ -5,14 +5,14 @@ import * as React from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; -import { zrxContractAddress, zrxDecimals } from '../constants'; +import { zrxDecimals } from '../constants'; import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; import { ColorOption } from '../style/theme'; import { AsyncProcessState } from '../types'; import { assetBuyer } from '../util/asset_buyer'; -import { AmountInput } from '../components/amount_input'; +import { AssetAmountInput } from '../components/asset_amount_input'; export interface SelectedAssetAmountInputProps { fontColor?: ColorOption; @@ -21,31 +21,40 @@ export interface SelectedAssetAmountInputProps { interface ConnectedState { value?: BigNumber; + assetData?: string; } interface ConnectedDispatch { - onChange?: (value?: BigNumber) => void; + onChange: (value?: BigNumber, assetData?: string) => void; } const mapStateToProps = (state: State, _ownProps: SelectedAssetAmountInputProps): ConnectedState => ({ value: state.selectedAssetAmount, + assetData: state.selectedAssetData, }); -const updateBuyQuote = async (dispatch: Dispatch, assetAmount?: BigNumber): Promise => { - if (_.isUndefined(assetAmount)) { +const updateBuyQuoteAsync = async ( + dispatch: Dispatch, + assetData?: string, + assetAmount?: BigNumber, +): Promise => { + if (_.isUndefined(assetAmount) || _.isUndefined(assetData)) { return; } // get a new buy quote. const baseUnitValue = Web3Wrapper.toBaseUnitAmount(assetAmount, zrxDecimals); - const newBuyQuote = await assetBuyer.getBuyQuoteForERC20TokenAddressAsync(zrxContractAddress, baseUnitValue); + const newBuyQuote = await assetBuyer.getBuyQuoteAsync(assetData, baseUnitValue); // invalidate the last buy quote. dispatch(actions.updateLatestBuyQuote(newBuyQuote)); }; -const debouncedUpdateBuyQuote = _.debounce(updateBuyQuote, 200, { trailing: true }); +const debouncedUpdateBuyQuoteAsync = _.debounce(updateBuyQuoteAsync, 200, { trailing: true }); -const mapDispatchToProps = (dispatch: Dispatch): ConnectedDispatch => ({ - onChange: async value => { +const mapDispatchToProps = ( + dispatch: Dispatch, + _ownProps: SelectedAssetAmountInputProps, +): ConnectedDispatch => ({ + onChange: (value, assetData) => { // Update the input dispatch(actions.updateSelectedAssetAmount(value)); // invalidate the last buy quote. @@ -53,11 +62,11 @@ const mapDispatchToProps = (dispatch: Dispatch): ConnectedDispatch => ({ // reset our buy state dispatch(actions.updateSelectedAssetBuyState(AsyncProcessState.NONE)); // tslint:disable-next-line:no-floating-promises - debouncedUpdateBuyQuote(dispatch, value); + debouncedUpdateBuyQuoteAsync(dispatch, assetData, value); }, }); export const SelectedAssetAmountInput: React.ComponentClass = connect( mapStateToProps, mapDispatchToProps, -)(AmountInput); +)(AssetAmountInput); diff --git a/packages/instant/src/data/asset_meta_data.ts b/packages/instant/src/data/asset_meta_data.ts new file mode 100644 index 000000000..e4d3e8f73 --- /dev/null +++ b/packages/instant/src/data/asset_meta_data.ts @@ -0,0 +1,15 @@ +import { AssetProxyId, ObjectMap } from '@0xproject/types'; + +import { zrxAssetData } from '../constants'; +import { AssetMetaData } from '../types'; + +// Map from assetData string to AssetMetaData object +// TODO: import this from somewhere else. +export const assetMetaData: ObjectMap = { + [zrxAssetData]: { + assetProxyId: AssetProxyId.ERC20, + decimals: 18, + primaryColor: 'rgb(54, 50, 60)', + symbol: 'zrx', + }, +}; diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts index 56a4ee236..adecf2ab7 100644 --- a/packages/instant/src/redux/reducer.ts +++ b/packages/instant/src/redux/reducer.ts @@ -2,11 +2,13 @@ import { BuyQuote } from '@0xproject/asset-buyer'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; +import { zrxAssetData } from '../constants'; import { AsyncProcessState } from '../types'; import { Action, ActionTypes } from './actions'; export interface State { + selectedAssetData?: string; selectedAssetAmount?: BigNumber; selectedAssetBuyState: AsyncProcessState; ethUsdPrice?: BigNumber; @@ -14,9 +16,11 @@ export interface State { } export const INITIAL_STATE: State = { - ethUsdPrice: undefined, - selectedAssetBuyState: AsyncProcessState.NONE, + // TODO: Remove hardcoded zrxAssetData + selectedAssetData: zrxAssetData, selectedAssetAmount: undefined, + selectedAssetBuyState: AsyncProcessState.NONE, + ethUsdPrice: undefined, latestBuyQuote: undefined, }; diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index ffa5d679e..bf3ee392f 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -1,4 +1,4 @@ -import { ObjectMap } from '@0xproject/types'; +import { AssetProxyId, ObjectMap } from '@0xproject/types'; // Reusable export enum AsyncProcessState { @@ -11,3 +11,23 @@ export enum AsyncProcessState { export type FunctionType = (...args: any[]) => any; export type ActionCreatorsMapObject = ObjectMap; export type ActionsUnion = ReturnType; + +export interface ERC20AssetMetaData { + assetProxyId: AssetProxyId.ERC20; + decimals: number; + primaryColor?: string; + symbol: string; +} + +export interface ERC721AssetMetaData { + assetProxyId: AssetProxyId.ERC721; + name: string; + primaryColor?: string; +} + +export type AssetMetaData = ERC20AssetMetaData | ERC721AssetMetaData; + +export enum Network { + Kovan = 42, + Mainnet = 1, +} -- cgit v1.2.3