Address feedback

This commit is contained in:
Leonid Logvinov
2018-02-08 16:23:20 +01:00
parent 8fba0477a6
commit 1233c33116
15 changed files with 57 additions and 157 deletions

View File

@@ -39,7 +39,6 @@ import {
ProviderType,
Side,
SideToAssetToken,
SignatureData,
Token,
TokenByAddress,
} from 'ts/types';
@@ -289,39 +288,6 @@ export class Blockchain {
}),
);
}
public portalOrderToSignedOrder(
maker: string,
taker: string,
makerTokenAddress: string,
takerTokenAddress: string,
makerTokenAmount: BigNumber,
takerTokenAmount: BigNumber,
makerFee: BigNumber,
takerFee: BigNumber,
expirationUnixTimestampSec: BigNumber,
feeRecipient: string,
ecSignature: ECSignature,
salt: BigNumber,
): SignedOrder {
const exchangeContractAddress = this.getExchangeContractAddressIfExists();
const takerOrNullAddress = _.isEmpty(taker) ? constants.NULL_ADDRESS : taker;
const signedOrder = {
ecSignature,
exchangeContractAddress,
expirationUnixTimestampSec,
feeRecipient,
maker,
makerFee,
makerTokenAddress,
makerTokenAmount,
salt,
taker: takerOrNullAddress,
takerFee,
takerTokenAddress,
takerTokenAmount,
};
return signedOrder;
}
public async fillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber): Promise<BigNumber> {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);

View File

@@ -19,7 +19,7 @@ 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 { 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)) {
@@ -199,9 +197,6 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
amount: this.props.orderFillAmount,
symbol: takerToken.symbol,
};
const orderTaker = !_.isEmpty(this.state.parsedOrder.signedOrder.taker)
? this.state.parsedOrder.signedOrder.taker
: this.props.userAddress;
const parsedOrderExpiration = new BigNumber(this.state.parsedOrder.signedOrder.expirationUnixTimestampSec);
const exchangeRate = orderMakerAmount.div(orderTakerAmount);
@@ -236,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.signedOrder.maker}
makerAssetToken={makerAssetToken}
takerAssetToken={takerAssetToken}
tokenByAddress={this.props.tokenByAddress}
@@ -407,7 +400,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
let orderHash: string;
try {
const order = JSON.parse(orderJSON);
const validationResult = this._validator.validate(order, orderSchema);
const validationResult = validator.validate(order, orderSchema);
if (validationResult.errors.length > 0) {
orderJSONErrMsg = 'Submitted order JSON is not a valid order';
utils.consoleLog(`Unexpected order JSON validation error: ${validationResult.errors.join(', ')}`);
@@ -415,7 +408,6 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
}
parsedOrder = order;
const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists();
const makerAmount = new BigNumber(parsedOrder.signedOrder.makerTokenAmount);
const takerAmount = new BigNumber(parsedOrder.signedOrder.takerTokenAmount);
const expiration = new BigNumber(parsedOrder.signedOrder.expirationUnixTimestampSec);
@@ -441,6 +433,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
};
orderHash = ZeroEx.getOrderHashHex(zeroExOrder);
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) {
@@ -525,20 +518,21 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
globalErrMsg = 'You must specify a fill amount';
}
const signedOrder = this.props.blockchain.portalOrderToSignedOrder(
parsedOrder.signedOrder.maker,
parsedOrder.signedOrder.taker,
parsedOrder.signedOrder.makerTokenAddress,
parsedOrder.signedOrder.takerTokenAddress,
new BigNumber(parsedOrder.signedOrder.makerTokenAmount),
new BigNumber(parsedOrder.signedOrder.takerTokenAmount),
new BigNumber(parsedOrder.signedOrder.makerFee),
new BigNumber(parsedOrder.signedOrder.takerFee),
new BigNumber(this.state.parsedOrder.signedOrder.expirationUnixTimestampSec),
parsedOrder.signedOrder.feeRecipient,
parsedOrder.signedOrder.ecSignature,
new BigNumber(parsedOrder.signedOrder.salt),
);
const signedOrder = {
exchangeContractAddress: this.props.blockchain.getExchangeContractAddressIfExists(),
maker: parsedOrder.signedOrder.maker,
taker: _.isEmpty(parsedOrder.signedOrder.taker) ? constants.NULL_ADDRESS : parsedOrder.signedOrder.taker,
makerTokenAddress: parsedOrder.signedOrder.makerTokenAddress,
takerTokenAddress: parsedOrder.signedOrder.takerTokenAddress,
makerTokenAmount: new BigNumber(parsedOrder.signedOrder.makerTokenAmount),
takerTokenAmount: new BigNumber(parsedOrder.signedOrder.takerTokenAmount),
makerFee: new BigNumber(parsedOrder.signedOrder.makerFee),
takerFee: new BigNumber(parsedOrder.signedOrder.takerFee),
expirationUnixTimestampSec: new BigNumber(this.state.parsedOrder.signedOrder.expirationUnixTimestampSec),
feeRecipient: parsedOrder.signedOrder.feeRecipient,
ecSignature: parsedOrder.signedOrder.ecSignature,
salt: new BigNumber(parsedOrder.signedOrder.salt),
};
if (_.isEmpty(globalErrMsg)) {
try {
await this.props.blockchain.validateFillOrderThrowIfInvalidAsync(
@@ -627,20 +621,21 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
const takerTokenAmount = new BigNumber(parsedOrder.signedOrder.takerTokenAmount);
const signedOrder = this.props.blockchain.portalOrderToSignedOrder(
parsedOrder.signedOrder.maker,
parsedOrder.signedOrder.taker,
parsedOrder.signedOrder.makerTokenAddress,
parsedOrder.signedOrder.takerTokenAddress,
new BigNumber(parsedOrder.signedOrder.makerTokenAmount),
takerTokenAmount,
new BigNumber(parsedOrder.signedOrder.makerFee),
new BigNumber(parsedOrder.signedOrder.takerFee),
new BigNumber(this.state.parsedOrder.signedOrder.expirationUnixTimestampSec),
parsedOrder.signedOrder.feeRecipient,
parsedOrder.signedOrder.ecSignature,
new BigNumber(parsedOrder.signedOrder.salt),
);
const signedOrder = {
exchangeContractAddress: this.props.blockchain.getExchangeContractAddressIfExists(),
maker: parsedOrder.signedOrder.maker,
taker: parsedOrder.signedOrder.taker,
makerTokenAddress: parsedOrder.signedOrder.makerTokenAddress,
takerTokenAddress: parsedOrder.signedOrder.takerTokenAddress,
makerTokenAmount: new BigNumber(parsedOrder.signedOrder.makerTokenAmount),
takerTokenAmount: new BigNumber(parsedOrder.signedOrder.takerTokenAmount),
makerFee: new BigNumber(parsedOrder.signedOrder.makerFee),
takerFee: new BigNumber(parsedOrder.signedOrder.takerFee),
expirationUnixTimestampSec: new BigNumber(this.state.parsedOrder.signedOrder.expirationUnixTimestampSec),
feeRecipient: parsedOrder.signedOrder.feeRecipient,
ecSignature: parsedOrder.signedOrder.ecSignature,
salt: new BigNumber(parsedOrder.signedOrder.salt),
};
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
const unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash);
const availableTakerTokenAmount = takerTokenAmount.minus(unavailableTakerAmount);

View File

@@ -18,7 +18,7 @@ import { LifeCycleRaisedButton } from 'ts/components/ui/lifecycle_raised_button'
import { SwapIcon } from 'ts/components/ui/swap_icon';
import { Dispatcher } from 'ts/redux/dispatcher';
import { orderSchema } from 'ts/schemas/order_schema';
import { SchemaValidator } from 'ts/schemas/validator';
import { validator } from 'ts/schemas/validator';
import { AlertTypes, BlockchainErrs, HashData, Side, SideToAssetToken, Token, TokenByAddress } from 'ts/types';
import { colors } from 'ts/utils/colors';
import { constants } from 'ts/utils/constants';
@@ -55,7 +55,6 @@ interface GenerateOrderFormState {
}
export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, GenerateOrderFormState> {
private _validator: SchemaValidator;
constructor(props: GenerateOrderFormProps) {
super(props);
this.state = {
@@ -63,7 +62,6 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
shouldShowIncompleteErrs: false,
signingState: SigningState.UNSIGNED,
};
this._validator = new SchemaValidator();
}
public componentDidMount() {
window.scrollTo(0, 0);
@@ -79,6 +77,8 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
allowed to fill this order. If no taker is<br> \
specified, anyone is able to fill it.';
const exchangeContractIfExists = this.props.blockchain.getExchangeContractAddressIfExists();
const initialTakerAddress =
this.props.orderTakerAddress === ZeroEx.NULL_ADDRESS ? '' : this.props.orderTakerAddress;
return (
<div className="clearfix mb2 lg-px4 md-px4 sm-px2">
<h3>Generate an order</h3>
@@ -159,7 +159,7 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
<div className="pt1 flex mx-auto">
<IdenticonAddressInput
label="Taker"
initialAddress={this.props.orderTakerAddress}
initialAddress={initialTakerAddress}
updateOrderAddress={this._updateOrderAddress.bind(this)}
/>
<div className="pt3">
@@ -317,7 +317,7 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
let globalErrMsg = '';
try {
const signatureData = await this.props.blockchain.signOrderHashAsync(orderHash);
const ecSignature = await this.props.blockchain.signOrderHashAsync(orderHash);
const order = utils.generateOrder(
exchangeContractAddr,
this.props.sideToAssetToken,
@@ -327,11 +327,11 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
hashData.makerFee,
hashData.takerFee,
hashData.feeRecipientAddress,
signatureData,
ecSignature,
this.props.tokenByAddress,
hashData.orderSalt,
);
const validationResult = this._validator.validate(order, orderSchema);
const validationResult = validator.validate(order, orderSchema);
if (validationResult.errors.length > 0) {
globalErrMsg = 'Order signing failed. Please refresh and try again';
utils.consoleLog(`Unexpected error occured: Order validation failed:
@@ -356,7 +356,8 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
}
private _updateOrderAddress(address?: string): void {
if (!_.isUndefined(address)) {
this.props.dispatcher.updateOrderTakerAddress(address);
const normalizedAddress = _.isEmpty(address) ? ZeroEx.NULL_ADDRESS : address;
this.props.dispatcher.updateOrderTakerAddress(normalizedAddress);
}
}
}

View File

@@ -22,7 +22,7 @@ import { GenerateOrderForm } from 'ts/containers/generate_order_form';
import { localStorage } from 'ts/local_storage/local_storage';
import { Dispatcher } from 'ts/redux/dispatcher';
import { orderSchema } from 'ts/schemas/order_schema';
import { SchemaValidator } from 'ts/schemas/validator';
import { validator } from 'ts/schemas/validator';
import { BlockchainErrs, HashData, Order, ProviderType, ScreenWidths, TokenByAddress, WebsitePaths } from 'ts/types';
import { colors } from 'ts/utils/colors';
import { configs } from 'ts/utils/configs';
@@ -367,7 +367,6 @@ export class Portal extends React.Component<PortalAllProps, PortalAllState> {
return undefined;
}
const validator = new SchemaValidator();
const order = JSON.parse(decodeURIComponent(orderPair[1]));
const validationResult = validator.validate(order, orderSchema);
if (validationResult.errors.length > 0) {

View File

@@ -8,8 +8,6 @@ import { utils } from 'ts/utils/utils';
const PRECISION = 5;
interface VisualOrderProps {
orderTakerAddress: string;
orderMakerAddress: string;
makerAssetToken: AssetToken;
takerAssetToken: AssetToken;
makerToken: Token;

View File

@@ -7,7 +7,7 @@ import { Blockchain } from 'ts/blockchain';
import { GenerateOrderForm as GenerateOrderFormComponent } from 'ts/components/generate_order/generate_order_form';
import { Dispatcher } from 'ts/redux/dispatcher';
import { State } from 'ts/redux/reducer';
import { BlockchainErrs, HashData, SideToAssetToken, SignatureData, TokenByAddress } from 'ts/types';
import { BlockchainErrs, HashData, SideToAssetToken, TokenByAddress } from 'ts/types';
interface GenerateOrderFormProps {
blockchain: Blockchain;

View File

@@ -11,7 +11,6 @@ import {
ScreenWidths,
Side,
SideToAssetToken,
SignatureData,
TokenByAddress,
} from 'ts/types';
import { utils } from 'ts/utils/utils';
@@ -64,7 +63,7 @@ const INITIAL_STATE: State = {
s: '',
v: 27,
},
orderTakerAddress: '',
orderTakerAddress: ZeroEx.NULL_ADDRESS,
orderSalt: ZeroEx.generatePseudoRandomSalt(),
nodeVersion: undefined,
screenWidth: utils.getScreenWidth(),

View File

@@ -1,8 +1,8 @@
export const orderMetadataSchema = {
id: '/OrderMetadata',
properties: {
makerToken: { $ref: '/Token' },
takerToken: { $ref: '/Token' },
makerToken: { $ref: '/PortalTokenMetadata' },
takerToken: { $ref: '/PortalTokenMetadata' },
},
required: ['makerToken', 'takerToken'],
type: 'object',

View File

@@ -1,5 +1,5 @@
export const orderSchema = {
id: '/Order',
id: '/PortalOrder',
properties: {
signedOrder: { $ref: '/SignedOrder' },
metadata: { $ref: '/OrderMetadata' },

View File

@@ -1,10 +0,0 @@
export const signatureDataSchema = {
id: '/SignatureData',
properties: {
r: { type: 'string' },
s: { type: 'string' },
v: { type: 'number' },
},
required: ['r', 's', 'v'],
type: 'object',
};

View File

@@ -1,34 +0,0 @@
export const signedOrderSchema = {
id: '/SignedOrder',
properties: {
maker: { type: 'string' },
taker: { type: 'string' },
makerTokenAddress: { type: 'string' },
takerTokenAddress: { type: 'string' },
makerFee: { type: 'string' },
takerFee: { type: 'string' },
makerTokenAmount: { type: 'string' },
takerTokenAmount: { type: 'string' },
salt: { type: 'string' },
ecSignature: { $ref: '/SignatureData' },
expirationUnixTimestampSec: { type: 'string' },
feeRecipient: { type: 'string' },
exchangeContractAddress: { type: 'string' },
},
required: [
'maker',
'taker',
'makerTokenAddress',
'takerTokenAddress',
'makerFee',
'takerFee',
'makerTokenAmount',
'takerTokenAmount',
'salt',
'ecSignature',
'expirationUnixTimestampSec',
'feeRecipient',
'exchangeContractAddress',
],
type: 'object',
};

View File

@@ -1,5 +1,5 @@
export const tokenSchema = {
id: '/Token',
id: '/PortalTokenMetadata',
properties: {
name: { type: 'string' },
symbol: { type: 'string' },

View File

@@ -1,21 +1,12 @@
import { SchemaValidator } from '@0xproject/json-schemas';
import { Schema as JSONSchema, Validator } from 'jsonschema';
import { orderMetadataSchema } from 'ts/schemas/metadata_schema';
import { orderSchema } from 'ts/schemas/order_schema';
import { signatureDataSchema } from 'ts/schemas/signature_data_schema';
import { signedOrderSchema } from 'ts/schemas/signed_order_schema';
import { tokenSchema } from 'ts/schemas/token_schema';
export class SchemaValidator {
private _validator: Validator;
constructor() {
this._validator = new Validator();
this._validator.addSchema(signatureDataSchema as JSONSchema, signatureDataSchema.id);
this._validator.addSchema(tokenSchema as JSONSchema, tokenSchema.id);
this._validator.addSchema(orderMetadataSchema as JSONSchema, orderMetadataSchema.id);
this._validator.addSchema(signedOrderSchema as JSONSchema, signedOrderSchema.id);
this._validator.addSchema(orderSchema as JSONSchema, orderSchema.id);
}
public validate(instance: object, schema: Schema) {
return this._validator.validate(instance, schema);
}
}
const validator = new SchemaValidator();
validator.addSchema(tokenSchema);
validator.addSchema(orderMetadataSchema);
validator.addSchema(orderSchema);
export { validator };

View File

@@ -35,10 +35,6 @@ export interface SideToAssetToken {
[side: string]: AssetToken;
}
export interface SignatureData extends ECSignature {
hash: string;
}
export interface HashData {
depositAmount: BigNumber;
depositTokenContractAddr: string;

View File

@@ -1,4 +1,4 @@
import { ECSignature, ExchangeContractErrs, ZeroExError } from '0x.js';
import { ECSignature, ExchangeContractErrs, ZeroEx, ZeroExError } from '0x.js';
import { BigNumber } from '@0xproject/utils';
import deepEqual = require('deep-equal');
import isMobile = require('is-mobile');
@@ -11,7 +11,6 @@ import {
ScreenWidths,
Side,
SideToAssetToken,
SignatureData,
Token,
TokenByAddress,
} from 'ts/types';