diff options
author | Leonid <logvinov.leon@gmail.com> | 2018-02-09 16:27:08 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-09 16:27:08 +0800 |
commit | 936f6ac10fe55257d846204ce4e5bd39ca27c78d (patch) | |
tree | f76cca84a55f979103a027282b289693a1f78491 /packages/website/ts/components/fill_order.tsx | |
parent | 7e04c4f24b789a2ce8f4a5884212cfb1e508b508 (diff) | |
parent | 43cf8d30bdab025cdcda888897d35b25ad455031 (diff) | |
download | dexon-sol-tools-936f6ac10fe55257d846204ce4e5bd39ca27c78d.tar dexon-sol-tools-936f6ac10fe55257d846204ce4e5bd39ca27c78d.tar.gz dexon-sol-tools-936f6ac10fe55257d846204ce4e5bd39ca27c78d.tar.bz2 dexon-sol-tools-936f6ac10fe55257d846204ce4e5bd39ca27c78d.tar.lz dexon-sol-tools-936f6ac10fe55257d846204ce4e5bd39ca27c78d.tar.xz dexon-sol-tools-936f6ac10fe55257d846204ce4e5bd39ca27c78d.tar.zst dexon-sol-tools-936f6ac10fe55257d846204ce4e5bd39ca27c78d.zip |
Merge pull request #379 from 0xProject/portal_json
Make portal order JSON compatible with 0x.js
Diffstat (limited to 'packages/website/ts/components/fill_order.tsx')
-rw-r--r-- | packages/website/ts/components/fill_order.tsx | 147 |
1 files changed, 55 insertions, 92 deletions
diff --git a/packages/website/ts/components/fill_order.tsx b/packages/website/ts/components/fill_order.tsx index 97f616be2..51e44134c 100644 --- a/packages/website/ts/components/fill_order.tsx +++ b/packages/website/ts/components/fill_order.tsx @@ -18,8 +18,8 @@ import { EthereumAddress } from 'ts/components/ui/ethereum_address'; import { Identicon } from 'ts/components/ui/identicon'; import { VisualOrder } from 'ts/components/visual_order'; import { Dispatcher } from 'ts/redux/dispatcher'; -import { orderSchema } from 'ts/schemas/order_schema'; -import { SchemaValidator } from 'ts/schemas/validator'; +import { portalOrderSchema } from 'ts/schemas/portal_order_schema'; +import { validator } from 'ts/schemas/validator'; import { AlertTypes, BlockchainErrs, Order, Token, TokenByAddress, WebsitePaths } from 'ts/types'; import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; @@ -59,7 +59,6 @@ interface FillOrderState { } export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { - private _validator: SchemaValidator; private _isUnmounted: boolean; constructor(props: FillOrderProps) { super(props); @@ -82,7 +81,6 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { isConfirmingTokenTracking: false, tokensToTrack: [], }; - this._validator = new SchemaValidator(); } public componentWillMount() { if (!_.isEmpty(this.state.orderJSON)) { @@ -109,7 +107,6 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { <FillOrderJSON blockchain={this.props.blockchain} tokenByAddress={this.props.tokenByAddress} - networkId={this.props.networkId} orderJSON={this.state.orderJSON} onFillOrderJSONChanged={this._onFillOrderJSONChanged.bind(this)} /> @@ -136,7 +133,6 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { <FillOrderJSON blockchain={this.props.blockchain} tokenByAddress={this.props.tokenByAddress} - networkId={this.props.networkId} orderJSON={this.state.orderJSON} onFillOrderJSONChanged={this._onFillOrderJSONChanged.bind(this)} /> @@ -182,16 +178,16 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { ); } private _renderVisualOrder() { - const takerTokenAddress = this.state.parsedOrder.taker.token.address; + const takerTokenAddress = this.state.parsedOrder.signedOrder.takerTokenAddress; const takerToken = this.props.tokenByAddress[takerTokenAddress]; - const orderTakerAmount = new BigNumber(this.state.parsedOrder.taker.amount); - const orderMakerAmount = new BigNumber(this.state.parsedOrder.maker.amount); + const orderTakerAmount = new BigNumber(this.state.parsedOrder.signedOrder.takerTokenAmount); + const orderMakerAmount = new BigNumber(this.state.parsedOrder.signedOrder.makerTokenAmount); const takerAssetToken = { amount: orderTakerAmount.minus(this.state.unavailableTakerAmount), symbol: takerToken.symbol, }; - const fillToken = this.props.tokenByAddress[takerToken.address]; - const makerTokenAddress = this.state.parsedOrder.maker.token.address; + const fillToken = this.props.tokenByAddress[takerTokenAddress]; + const makerTokenAddress = this.state.parsedOrder.signedOrder.makerTokenAddress; const makerToken = this.props.tokenByAddress[makerTokenAddress]; const makerAssetToken = { amount: orderMakerAmount.times(takerAssetToken.amount).div(orderTakerAmount), @@ -201,10 +197,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { amount: this.props.orderFillAmount, symbol: takerToken.symbol, }; - const orderTaker = !_.isEmpty(this.state.parsedOrder.taker.address) - ? this.state.parsedOrder.taker.address - : this.props.userAddress; - const parsedOrderExpiration = new BigNumber(this.state.parsedOrder.expiration); + const parsedOrderExpiration = new BigNumber(this.state.parsedOrder.signedOrder.expirationUnixTimestampSec); const exchangeRate = orderMakerAmount.div(orderTakerAmount); let orderReceiveAmount = 0; @@ -213,7 +206,8 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { orderReceiveAmount = this._formatCurrencyAmount(orderReceiveAmountBigNumber, makerToken.decimals); } const isUserMaker = - !_.isUndefined(this.state.parsedOrder) && this.state.parsedOrder.maker.address === this.props.userAddress; + !_.isUndefined(this.state.parsedOrder) && + this.state.parsedOrder.signedOrder.maker === this.props.userAddress; const expiryDate = utils.convertToReadableDateTimeFromUnixTimestamp(parsedOrderExpiration); return ( <div className="pt3 pb1"> @@ -224,11 +218,11 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { Maker: </div> <div className="col col-2 pr1"> - <Identicon address={this.state.parsedOrder.maker.address} diameter={23} /> + <Identicon address={this.state.parsedOrder.signedOrder.maker} diameter={23} /> </div> <div className="col col-6"> <EthereumAddress - address={this.state.parsedOrder.maker.address} + address={this.state.parsedOrder.signedOrder.maker} networkId={this.props.networkId} /> </div> @@ -237,8 +231,6 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { <div className="lg-px4 md-px4 sm-px0"> <div className="lg-px4 md-px4 sm-px1 pt1"> <VisualOrder - orderTakerAddress={orderTaker} - orderMakerAddress={this.state.parsedOrder.maker.address} makerAssetToken={makerAssetToken} takerAssetToken={takerAssetToken} tokenByAddress={this.props.tokenByAddress} @@ -361,15 +353,16 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { return; } - const makerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.maker.token.address]; - const takerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.taker.token.address]; + const makerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.signedOrder.makerTokenAddress]; + const takerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.signedOrder.takerTokenAddress]; - const tokensToTrack = []; + const tokensToTrack: Token[] = []; const isUnseenMakerToken = _.isUndefined(makerTokenIfExists); const isMakerTokenTracked = !_.isUndefined(makerTokenIfExists) && makerTokenIfExists.isTracked; if (isUnseenMakerToken) { tokensToTrack.push({ - ...this.state.parsedOrder.maker.token, + ...this.state.parsedOrder.metadata.makerToken, + address: this.state.parsedOrder.signedOrder.makerTokenAddress, iconUrl: undefined, isTracked: false, isRegistered: false, @@ -381,7 +374,8 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { const isTakerTokenTracked = !_.isUndefined(takerTokenIfExists) && takerTokenIfExists.isTracked; if (isUnseenTakerToken) { tokensToTrack.push({ - ...this.state.parsedOrder.taker.token, + ...this.state.parsedOrder.metadata.takerToken, + address: this.state.parsedOrder.signedOrder.takerTokenAddress, iconUrl: undefined, isTracked: false, isRegistered: false, @@ -403,9 +397,10 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { private async _validateFillOrderFireAndForgetAsync(orderJSON: string) { let orderJSONErrMsg = ''; let parsedOrder: Order; + let orderHash: string; try { const order = JSON.parse(orderJSON); - const validationResult = this._validator.validate(order, orderSchema); + const validationResult = validator.validate(order, portalOrderSchema); if (validationResult.errors.length > 0) { orderJSONErrMsg = 'Submitted order JSON is not a valid order'; utils.consoleLog(`Unexpected order JSON validation error: ${validationResult.errors.join(', ')}`); @@ -413,41 +408,36 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { } parsedOrder = order; - const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists(); - const makerAmount = new BigNumber(parsedOrder.maker.amount); - const takerAmount = new BigNumber(parsedOrder.taker.amount); - const expiration = new BigNumber(parsedOrder.expiration); - const salt = new BigNumber(parsedOrder.salt); - const parsedMakerFee = new BigNumber(parsedOrder.maker.feeAmount); - const parsedTakerFee = new BigNumber(parsedOrder.taker.feeAmount); + const makerAmount = new BigNumber(parsedOrder.signedOrder.makerTokenAmount); + const takerAmount = new BigNumber(parsedOrder.signedOrder.takerTokenAmount); + const expiration = new BigNumber(parsedOrder.signedOrder.expirationUnixTimestampSec); + const salt = new BigNumber(parsedOrder.signedOrder.salt); + const parsedMakerFee = new BigNumber(parsedOrder.signedOrder.makerFee); + const parsedTakerFee = new BigNumber(parsedOrder.signedOrder.takerFee); const zeroExOrder: ZeroExOrder = { - exchangeContractAddress: parsedOrder.exchangeContract, + exchangeContractAddress: parsedOrder.signedOrder.exchangeContractAddress, expirationUnixTimestampSec: expiration, - feeRecipient: parsedOrder.feeRecipient, - maker: parsedOrder.maker.address, + feeRecipient: parsedOrder.signedOrder.feeRecipient, + maker: parsedOrder.signedOrder.maker, makerFee: parsedMakerFee, - makerTokenAddress: parsedOrder.maker.token.address, + makerTokenAddress: parsedOrder.signedOrder.makerTokenAddress, makerTokenAmount: makerAmount, salt, - taker: _.isEmpty(parsedOrder.taker.address) ? constants.NULL_ADDRESS : parsedOrder.taker.address, + taker: _.isEmpty(parsedOrder.signedOrder.taker) + ? constants.NULL_ADDRESS + : parsedOrder.signedOrder.taker, takerFee: parsedTakerFee, - takerTokenAddress: parsedOrder.taker.token.address, + takerTokenAddress: parsedOrder.signedOrder.takerTokenAddress, takerTokenAmount: takerAmount, }; - const orderHash = ZeroEx.getOrderHashHex(zeroExOrder); + orderHash = ZeroEx.getOrderHashHex(zeroExOrder); - const signature = parsedOrder.signature; - const isValidSignature = ZeroEx.isValidSignature(signature.hash, signature, parsedOrder.maker.address); - if (this.props.networkId !== parsedOrder.networkId) { - orderJSONErrMsg = `This order was made on another Ethereum network - (id: ${parsedOrder.networkId}). Connect to this network to fill.`; - parsedOrder = undefined; - } else if (exchangeContractAddr !== parsedOrder.exchangeContract) { - orderJSONErrMsg = 'This order was made using a deprecated 0x Exchange contract.'; - parsedOrder = undefined; - } else if (orderHash !== signature.hash) { - orderJSONErrMsg = 'Order hash does not match supplied plaintext values'; + const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists(); + const signature = parsedOrder.signedOrder.ecSignature; + const isValidSignature = ZeroEx.isValidSignature(orderHash, signature, parsedOrder.signedOrder.maker); + if (exchangeContractAddr !== parsedOrder.signedOrder.exchangeContractAddress) { + orderJSONErrMsg = 'This order was made on another network or using a deprecated Exchange contract'; parsedOrder = undefined; } else if (!isValidSignature) { orderJSONErrMsg = 'Order signature is invalid'; @@ -478,13 +468,12 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { // Clear cache entry if user updates orderJSON to invalid entry this.props.dispatcher.updateUserSuppliedOrderCache(undefined); } else { - const orderHash = parsedOrder.signature.hash; unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash); const isMakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync( - parsedOrder.maker.token.address, + parsedOrder.signedOrder.makerTokenAddress, ); const isTakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync( - parsedOrder.taker.token.address, + parsedOrder.signedOrder.takerTokenAddress, ); this.setState({ isMakerTokenAddressInRegistry, @@ -529,20 +518,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { globalErrMsg = 'You must specify a fill amount'; } - const signedOrder = this.props.blockchain.portalOrderToSignedOrder( - parsedOrder.maker.address, - parsedOrder.taker.address, - parsedOrder.maker.token.address, - parsedOrder.taker.token.address, - new BigNumber(parsedOrder.maker.amount), - new BigNumber(parsedOrder.taker.amount), - new BigNumber(parsedOrder.maker.feeAmount), - new BigNumber(parsedOrder.taker.feeAmount), - new BigNumber(this.state.parsedOrder.expiration), - parsedOrder.feeRecipient, - parsedOrder.signature, - new BigNumber(parsedOrder.salt), - ); + const signedOrder = this.props.blockchain.portalOrderToZeroExOrder(parsedOrder); if (_.isEmpty(globalErrMsg)) { try { await this.props.blockchain.validateFillOrderThrowIfInvalidAsync( @@ -551,7 +527,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { this.props.userAddress, ); } catch (err) { - globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address); + globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.signedOrder.taker); } } if (!_.isEmpty(globalErrMsg)) { @@ -562,7 +538,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { return; } const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; - const eventLabel = `${parsedOrder.taker.token.symbol}-${networkName}`; + const eventLabel = `${parsedOrder.metadata.takerToken.symbol}-${networkName}`; try { const orderFilledAmount: BigNumber = await this.props.blockchain.fillOrderAsync( signedOrder, @@ -572,7 +548,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { category: 'Portal', action: 'Fill Order Success', label: eventLabel, - value: parsedOrder.taker.amount, + value: parsedOrder.signedOrder.takerTokenAmount, }); // After fill completes, let's force fetch the token balances this.props.dispatcher.forceTokenStateRefetch(); @@ -591,7 +567,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { category: 'Portal', action: 'Fill Order Failure', label: eventLabel, - value: parsedOrder.taker.amount, + value: parsedOrder.signedOrder.takerTokenAmount, }); const errMsg = `${err}`; if (utils.didUserDenyWeb3Request(errMsg)) { @@ -618,7 +594,6 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { }); const parsedOrder = this.state.parsedOrder; - const orderHash = parsedOrder.signature.hash; const takerAddress = this.props.userAddress; if (_.isUndefined(takerAddress)) { @@ -630,28 +605,16 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { } let globalErrMsg = ''; - const takerTokenAmount = new BigNumber(parsedOrder.taker.amount); + const takerTokenAmount = new BigNumber(parsedOrder.signedOrder.takerTokenAmount); - const signedOrder = this.props.blockchain.portalOrderToSignedOrder( - parsedOrder.maker.address, - parsedOrder.taker.address, - parsedOrder.maker.token.address, - parsedOrder.taker.token.address, - new BigNumber(parsedOrder.maker.amount), - takerTokenAmount, - new BigNumber(parsedOrder.maker.feeAmount), - new BigNumber(parsedOrder.taker.feeAmount), - new BigNumber(this.state.parsedOrder.expiration), - parsedOrder.feeRecipient, - parsedOrder.signature, - new BigNumber(parsedOrder.salt), - ); + const signedOrder = this.props.blockchain.portalOrderToZeroExOrder(parsedOrder); + const orderHash = ZeroEx.getOrderHashHex(signedOrder); const unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash); const availableTakerTokenAmount = takerTokenAmount.minus(unavailableTakerAmount); try { await this.props.blockchain.validateCancelOrderThrowIfInvalidAsync(signedOrder, availableTakerTokenAmount); } catch (err) { - globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address); + globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.signedOrder.taker); } if (!_.isEmpty(globalErrMsg)) { this.setState({ @@ -661,7 +624,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { return; } const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; - const eventLabel = `${parsedOrder.maker.token.symbol}-${networkName}`; + const eventLabel = `${parsedOrder.metadata.makerToken.symbol}-${networkName}`; try { await this.props.blockchain.cancelOrderAsync(signedOrder, availableTakerTokenAmount); this.setState({ @@ -674,7 +637,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { category: 'Portal', action: 'Cancel Order Success', label: eventLabel, - value: parsedOrder.maker.amount, + value: parsedOrder.signedOrder.makerTokenAmount, }); return; } catch (err) { @@ -689,7 +652,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { category: 'Portal', action: 'Cancel Order Failure', label: eventLabel, - value: parsedOrder.maker.amount, + value: parsedOrder.signedOrder.makerTokenAmount, }); globalErrMsg = 'Failed to cancel order, please refresh and try again'; utils.consoleLog(`${err}`); |