Introduce makerToken and takerToken fields for unsigned token metadata

This commit is contained in:
Leonid Logvinov 2018-02-07 15:26:53 +01:00
parent 223df8006a
commit 10fb6061cc
No known key found for this signature in database
GPG Key ID: 0DD294BFDE8C95D4
7 changed files with 68 additions and 72 deletions

View File

@ -182,7 +182,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
); );
} }
private _renderVisualOrder() { private _renderVisualOrder() {
const takerTokenAddress = this.state.parsedOrder.taker.token.address; const takerTokenAddress = this.state.parsedOrder.takerTokenAddress;
const takerToken = this.props.tokenByAddress[takerTokenAddress]; const takerToken = this.props.tokenByAddress[takerTokenAddress];
const orderTakerAmount = new BigNumber(this.state.parsedOrder.takerTokenAmount); const orderTakerAmount = new BigNumber(this.state.parsedOrder.takerTokenAmount);
const orderMakerAmount = new BigNumber(this.state.parsedOrder.makerTokenAmount); const orderMakerAmount = new BigNumber(this.state.parsedOrder.makerTokenAmount);
@ -190,8 +190,8 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
amount: orderTakerAmount.minus(this.state.unavailableTakerAmount), amount: orderTakerAmount.minus(this.state.unavailableTakerAmount),
symbol: takerToken.symbol, symbol: takerToken.symbol,
}; };
const fillToken = this.props.tokenByAddress[takerToken.address]; const fillToken = this.props.tokenByAddress[takerTokenAddress];
const makerTokenAddress = this.state.parsedOrder.maker.token.address; const makerTokenAddress = this.state.parsedOrder.makerTokenAddress;
const makerToken = this.props.tokenByAddress[makerTokenAddress]; const makerToken = this.props.tokenByAddress[makerTokenAddress];
const makerAssetToken = { const makerAssetToken = {
amount: orderMakerAmount.times(takerAssetToken.amount).div(orderTakerAmount), amount: orderMakerAmount.times(takerAssetToken.amount).div(orderTakerAmount),
@ -201,8 +201,8 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
amount: this.props.orderFillAmount, amount: this.props.orderFillAmount,
symbol: takerToken.symbol, symbol: takerToken.symbol,
}; };
const orderTaker = !_.isEmpty(this.state.parsedOrder.taker.address) const orderTaker = !_.isEmpty(this.state.parsedOrder.taker)
? this.state.parsedOrder.taker.address ? this.state.parsedOrder.taker
: this.props.userAddress; : this.props.userAddress;
const parsedOrderExpiration = new BigNumber(this.state.parsedOrder.expirationUnixTimestampSec); const parsedOrderExpiration = new BigNumber(this.state.parsedOrder.expirationUnixTimestampSec);
const exchangeRate = orderMakerAmount.div(orderTakerAmount); const exchangeRate = orderMakerAmount.div(orderTakerAmount);
@ -213,7 +213,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
orderReceiveAmount = this._formatCurrencyAmount(orderReceiveAmountBigNumber, makerToken.decimals); orderReceiveAmount = this._formatCurrencyAmount(orderReceiveAmountBigNumber, makerToken.decimals);
} }
const isUserMaker = const isUserMaker =
!_.isUndefined(this.state.parsedOrder) && this.state.parsedOrder.maker.address === this.props.userAddress; !_.isUndefined(this.state.parsedOrder) && this.state.parsedOrder.maker === this.props.userAddress;
const expiryDate = utils.convertToReadableDateTimeFromUnixTimestamp(parsedOrderExpiration); const expiryDate = utils.convertToReadableDateTimeFromUnixTimestamp(parsedOrderExpiration);
return ( return (
<div className="pt3 pb1"> <div className="pt3 pb1">
@ -224,13 +224,10 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
Maker: Maker:
</div> </div>
<div className="col col-2 pr1"> <div className="col col-2 pr1">
<Identicon address={this.state.parsedOrder.maker.address} diameter={23} /> <Identicon address={this.state.parsedOrder.maker} diameter={23} />
</div> </div>
<div className="col col-6"> <div className="col col-6">
<EthereumAddress <EthereumAddress address={this.state.parsedOrder.maker} networkId={this.props.networkId} />
address={this.state.parsedOrder.maker.address}
networkId={this.props.networkId}
/>
</div> </div>
</div> </div>
</div> </div>
@ -238,7 +235,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
<div className="lg-px4 md-px4 sm-px1 pt1"> <div className="lg-px4 md-px4 sm-px1 pt1">
<VisualOrder <VisualOrder
orderTakerAddress={orderTaker} orderTakerAddress={orderTaker}
orderMakerAddress={this.state.parsedOrder.maker.address} orderMakerAddress={this.state.parsedOrder.maker}
makerAssetToken={makerAssetToken} makerAssetToken={makerAssetToken}
takerAssetToken={takerAssetToken} takerAssetToken={takerAssetToken}
tokenByAddress={this.props.tokenByAddress} tokenByAddress={this.props.tokenByAddress}
@ -361,15 +358,16 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
return; return;
} }
const makerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.maker.token.address]; const makerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.makerTokenAddress];
const takerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.taker.token.address]; const takerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.takerTokenAddress];
const tokensToTrack = []; const tokensToTrack: Token[] = [];
const isUnseenMakerToken = _.isUndefined(makerTokenIfExists); const isUnseenMakerToken = _.isUndefined(makerTokenIfExists);
const isMakerTokenTracked = !_.isUndefined(makerTokenIfExists) && makerTokenIfExists.isTracked; const isMakerTokenTracked = !_.isUndefined(makerTokenIfExists) && makerTokenIfExists.isTracked;
if (isUnseenMakerToken) { if (isUnseenMakerToken) {
tokensToTrack.push({ tokensToTrack.push({
...this.state.parsedOrder.maker.token, ...this.state.parsedOrder.makerToken,
address: this.state.parsedOrder.makerTokenAddress,
iconUrl: undefined, iconUrl: undefined,
isTracked: false, isTracked: false,
isRegistered: false, isRegistered: false,
@ -381,7 +379,8 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
const isTakerTokenTracked = !_.isUndefined(takerTokenIfExists) && takerTokenIfExists.isTracked; const isTakerTokenTracked = !_.isUndefined(takerTokenIfExists) && takerTokenIfExists.isTracked;
if (isUnseenTakerToken) { if (isUnseenTakerToken) {
tokensToTrack.push({ tokensToTrack.push({
...this.state.parsedOrder.taker.token, ...this.state.parsedOrder.takerToken,
address: this.state.parsedOrder.takerTokenAddress,
iconUrl: undefined, iconUrl: undefined,
isTracked: false, isTracked: false,
isRegistered: false, isRegistered: false,
@ -425,20 +424,20 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
exchangeContractAddress: parsedOrder.exchangeContractAddress, exchangeContractAddress: parsedOrder.exchangeContractAddress,
expirationUnixTimestampSec: expiration, expirationUnixTimestampSec: expiration,
feeRecipient: parsedOrder.feeRecipient, feeRecipient: parsedOrder.feeRecipient,
maker: parsedOrder.maker.address, maker: parsedOrder.maker,
makerFee: parsedMakerFee, makerFee: parsedMakerFee,
makerTokenAddress: parsedOrder.maker.token.address, makerTokenAddress: parsedOrder.makerTokenAddress,
makerTokenAmount: makerAmount, makerTokenAmount: makerAmount,
salt, salt,
taker: _.isEmpty(parsedOrder.taker.address) ? constants.NULL_ADDRESS : parsedOrder.taker.address, taker: _.isEmpty(parsedOrder.taker) ? constants.NULL_ADDRESS : parsedOrder.taker,
takerFee: parsedTakerFee, takerFee: parsedTakerFee,
takerTokenAddress: parsedOrder.taker.token.address, takerTokenAddress: parsedOrder.takerTokenAddress,
takerTokenAmount: takerAmount, takerTokenAmount: takerAmount,
}; };
const orderHash = ZeroEx.getOrderHashHex(zeroExOrder); const orderHash = ZeroEx.getOrderHashHex(zeroExOrder);
const signature = parsedOrder.ecSignature; const signature = parsedOrder.ecSignature;
const isValidSignature = ZeroEx.isValidSignature(signature.hash, signature, parsedOrder.maker.address); const isValidSignature = ZeroEx.isValidSignature(signature.hash, signature, parsedOrder.maker);
if (this.props.networkId !== parsedOrder.networkId) { if (this.props.networkId !== parsedOrder.networkId) {
orderJSONErrMsg = `This order was made on another Ethereum network orderJSONErrMsg = `This order was made on another Ethereum network
(id: ${parsedOrder.networkId}). Connect to this network to fill.`; (id: ${parsedOrder.networkId}). Connect to this network to fill.`;
@ -481,10 +480,10 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
const orderHash = parsedOrder.ecSignature.hash; const orderHash = parsedOrder.ecSignature.hash;
unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash); unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash);
const isMakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync( const isMakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync(
parsedOrder.maker.token.address, parsedOrder.makerTokenAddress,
); );
const isTakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync( const isTakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync(
parsedOrder.taker.token.address, parsedOrder.takerTokenAddress,
); );
this.setState({ this.setState({
isMakerTokenAddressInRegistry, isMakerTokenAddressInRegistry,
@ -530,10 +529,10 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
} }
const signedOrder = this.props.blockchain.portalOrderToSignedOrder( const signedOrder = this.props.blockchain.portalOrderToSignedOrder(
parsedOrder.maker.address, parsedOrder.maker,
parsedOrder.taker.address, parsedOrder.taker,
parsedOrder.maker.token.address, parsedOrder.makerTokenAddress,
parsedOrder.taker.token.address, parsedOrder.takerTokenAddress,
new BigNumber(parsedOrder.makerTokenAmount), new BigNumber(parsedOrder.makerTokenAmount),
new BigNumber(parsedOrder.takerTokenAmount), new BigNumber(parsedOrder.takerTokenAmount),
new BigNumber(parsedOrder.makerFee), new BigNumber(parsedOrder.makerFee),
@ -551,7 +550,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
this.props.userAddress, this.props.userAddress,
); );
} catch (err) { } catch (err) {
globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address); globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker);
} }
} }
if (!_.isEmpty(globalErrMsg)) { if (!_.isEmpty(globalErrMsg)) {
@ -562,7 +561,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
return; return;
} }
const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId];
const eventLabel = `${parsedOrder.taker.token.symbol}-${networkName}`; const eventLabel = `${parsedOrder.takerToken.symbol}-${networkName}`;
try { try {
const orderFilledAmount: BigNumber = await this.props.blockchain.fillOrderAsync( const orderFilledAmount: BigNumber = await this.props.blockchain.fillOrderAsync(
signedOrder, signedOrder,
@ -633,10 +632,10 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
const takerTokenAmount = new BigNumber(parsedOrder.takerTokenAmount); const takerTokenAmount = new BigNumber(parsedOrder.takerTokenAmount);
const signedOrder = this.props.blockchain.portalOrderToSignedOrder( const signedOrder = this.props.blockchain.portalOrderToSignedOrder(
parsedOrder.maker.address, parsedOrder.maker,
parsedOrder.taker.address, parsedOrder.taker,
parsedOrder.maker.token.address, parsedOrder.makerTokenAddress,
parsedOrder.taker.token.address, parsedOrder.takerTokenAddress,
new BigNumber(parsedOrder.makerTokenAmount), new BigNumber(parsedOrder.makerTokenAmount),
takerTokenAmount, takerTokenAmount,
new BigNumber(parsedOrder.makerFee), new BigNumber(parsedOrder.makerFee),
@ -651,7 +650,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
try { try {
await this.props.blockchain.validateCancelOrderThrowIfInvalidAsync(signedOrder, availableTakerTokenAmount); await this.props.blockchain.validateCancelOrderThrowIfInvalidAsync(signedOrder, availableTakerTokenAmount);
} catch (err) { } catch (err) {
globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker.address); globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.taker);
} }
if (!_.isEmpty(globalErrMsg)) { if (!_.isEmpty(globalErrMsg)) {
this.setState({ this.setState({
@ -661,7 +660,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
return; return;
} }
const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId];
const eventLabel = `${parsedOrder.maker.token.symbol}-${networkName}`; const eventLabel = `${parsedOrder.makerToken.symbol}-${networkName}`;
try { try {
await this.props.blockchain.cancelOrderAsync(signedOrder, availableTakerTokenAmount); await this.props.blockchain.cancelOrderAsync(signedOrder, availableTakerTokenAmount);
this.setState({ this.setState({

View File

@ -1,8 +1,12 @@
export const orderSchema = { export const orderSchema = {
id: '/Order', id: '/Order',
properties: { properties: {
maker: { $ref: '/OrderTaker' }, maker: { type: 'string' },
taker: { $ref: '/OrderTaker' }, taker: { type: 'string' },
makerTokenAddress: { type: 'string' },
takerTokenAddress: { type: 'string' },
makerToken: { $ref: '/Token' },
takerToken: { $ref: '/Token' },
makerFee: { type: 'string' }, makerFee: { type: 'string' },
takerFee: { type: 'string' }, takerFee: { type: 'string' },
makerTokenAmount: { type: 'string' }, makerTokenAmount: { type: 'string' },
@ -17,6 +21,10 @@ export const orderSchema = {
required: [ required: [
'maker', 'maker',
'taker', 'taker',
'makerTokenAddress',
'takerTokenAddress',
'makerToken',
'takerToken',
'makerFee', 'makerFee',
'takerFee', 'takerFee',
'makerTokenAmount', 'makerTokenAmount',

View File

@ -1,9 +0,0 @@
export const orderTakerSchema = {
id: '/OrderTaker',
properties: {
address: { type: 'string' },
token: { $ref: '/Token' },
},
required: ['address', 'token'],
type: 'object',
};

View File

@ -4,8 +4,7 @@ export const tokenSchema = {
name: { type: 'string' }, name: { type: 'string' },
symbol: { type: 'string' }, symbol: { type: 'string' },
decimals: { type: 'number' }, decimals: { type: 'number' },
address: { type: 'string' },
}, },
required: ['name', 'symbol', 'decimals', 'address'], required: ['name', 'symbol', 'decimals'],
type: 'object', type: 'object',
}; };

View File

@ -1,6 +1,5 @@
import { Schema as JSONSchema, Validator } from 'jsonschema'; import { Schema as JSONSchema, Validator } from 'jsonschema';
import { orderSchema } from 'ts/schemas/order_schema'; import { orderSchema } from 'ts/schemas/order_schema';
import { orderTakerSchema } from 'ts/schemas/order_taker_schema';
import { signatureDataSchema } from 'ts/schemas/signature_data_schema'; import { signatureDataSchema } from 'ts/schemas/signature_data_schema';
import { tokenSchema } from 'ts/schemas/token_schema'; import { tokenSchema } from 'ts/schemas/token_schema';
@ -10,7 +9,6 @@ export class SchemaValidator {
this._validator = new Validator(); this._validator = new Validator();
this._validator.addSchema(signatureDataSchema as JSONSchema, signatureDataSchema.id); this._validator.addSchema(signatureDataSchema as JSONSchema, signatureDataSchema.id);
this._validator.addSchema(tokenSchema as JSONSchema, tokenSchema.id); this._validator.addSchema(tokenSchema as JSONSchema, tokenSchema.id);
this._validator.addSchema(orderTakerSchema as JSONSchema, orderTakerSchema.id);
this._validator.addSchema(orderSchema as JSONSchema, orderSchema.id); this._validator.addSchema(orderSchema as JSONSchema, orderSchema.id);
} }
public validate(instance: object, schema: Schema) { public validate(instance: object, schema: Schema) {

View File

@ -80,14 +80,19 @@ export interface Order {
networkId: number; networkId: number;
} }
export interface SerializedOrderParty { export interface SerializedOrderToken {
address: string; name: string;
token: OrderToken; symbol: string;
decimals: number;
} }
export interface SerializedOrder { export interface SerializedOrder {
maker: SerializedOrderParty; maker: string;
taker: SerializedOrderParty; taker: string;
makerTokenAddress: string;
takerTokenAddress: string;
makerToken: SerializedOrderToken;
takerToken: SerializedOrderToken;
makerFee: string; makerFee: string;
takerFee: string; takerFee: string;
makerTokenAmount: string; makerTokenAmount: string;

View File

@ -75,27 +75,23 @@ export const utils = {
const makerToken = tokenByAddress[sideToAssetToken[Side.Deposit].address]; const makerToken = tokenByAddress[sideToAssetToken[Side.Deposit].address];
const takerToken = tokenByAddress[sideToAssetToken[Side.Receive].address]; const takerToken = tokenByAddress[sideToAssetToken[Side.Receive].address];
const order = { const order = {
maker: orderMakerAddress,
taker: orderTakerAddress,
makerFee: makerFee.toString(), makerFee: makerFee.toString(),
takerFee: takerFee.toString(), takerFee: takerFee.toString(),
makerTokenAmount: sideToAssetToken[Side.Deposit].amount.toString(), makerTokenAmount: sideToAssetToken[Side.Deposit].amount.toString(),
takerTokenAmount: sideToAssetToken[Side.Receive].amount.toString(), takerTokenAmount: sideToAssetToken[Side.Receive].amount.toString(),
maker: { makerTokenAddress: makerToken.address,
address: orderMakerAddress, takerTokenAddress: takerToken.address,
token: { makerToken: {
name: makerToken.name, name: makerToken.name,
symbol: makerToken.symbol, symbol: makerToken.symbol,
decimals: makerToken.decimals, decimals: makerToken.decimals,
address: makerToken.address,
}, },
}, takerToken: {
taker: {
address: orderTakerAddress,
token: {
name: takerToken.name, name: takerToken.name,
symbol: takerToken.symbol, symbol: takerToken.symbol,
decimals: takerToken.decimals, decimals: takerToken.decimals,
address: takerToken.address,
},
}, },
expirationUnixTimestampSec: expirationUnixTimestampSec.toString(), expirationUnixTimestampSec: expirationUnixTimestampSec.toString(),
feeRecipient, feeRecipient,