Update generate and fill order flows

This commit is contained in:
Brandon Millman 2018-08-29 23:41:09 -07:00
parent 052824f4e3
commit 660e670d38
7 changed files with 41 additions and 30 deletions

View File

@ -414,6 +414,15 @@ export class Blockchain {
const lowercaseAddress = address.toLowerCase(); const lowercaseAddress = address.toLowerCase();
return Web3Wrapper.isAddress(lowercaseAddress); return Web3Wrapper.isAddress(lowercaseAddress);
} }
public async isValidSignatureAsync(data: string, signature: string, signerAddress: string): Promise<boolean> {
const result = await signatureUtils.isValidSignatureAsync(
this._contractWrappers.getProvider(),
data,
signature,
signerAddress,
);
return result;
}
public async pollTokenBalanceAsync(token: Token): Promise<BigNumber> { public async pollTokenBalanceAsync(token: Token): Promise<BigNumber> {
utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses); utils.assert(this._doesUserAddressExist(), BlockchainCallErrs.UserHasNoAssociatedAddresses);
@ -451,10 +460,10 @@ export class Blockchain {
throw new Error('Tried to send a sign request but user has no associated addresses'); throw new Error('Tried to send a sign request but user has no associated addresses');
} }
this._showFlashMessageIfLedger(); this._showFlashMessageIfLedger();
const provider = this._contractWrappers.getProvider(); const provider = this._contractWrappers.getProvider();
const isLedgerSigner = !_.isUndefined(this._ledgerSubprovider); const isLedgerSigner = !_.isUndefined(this._ledgerSubprovider);
const isMetaMaskSigner = utils.getProviderType(provider) === Providers.Metamask; const injectedProvider = Blockchain._getInjectedWeb3().currentProvider;
const isMetaMaskSigner = utils.getProviderType(injectedProvider) === Providers.Metamask;
let signerType = SignerType.Default; let signerType = SignerType.Default;
if (isLedgerSigner) { if (isLedgerSigner) {
signerType = SignerType.Ledger; signerType = SignerType.Ledger;

View File

@ -26,6 +26,7 @@ import { AlertTypes, BlockchainErrs, PortalOrder, Token, TokenByAddress, Website
import { analytics } from 'ts/utils/analytics'; import { analytics } from 'ts/utils/analytics';
import { constants } from 'ts/utils/constants'; import { constants } from 'ts/utils/constants';
import { errorReporter } from 'ts/utils/error_reporter'; import { errorReporter } from 'ts/utils/error_reporter';
import { orderParser } from 'ts/utils/order_parser';
import { utils } from 'ts/utils/utils'; import { utils } from 'ts/utils/utils';
interface FillOrderProps { interface FillOrderProps {
@ -418,7 +419,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
let parsedOrder: PortalOrder; let parsedOrder: PortalOrder;
let orderHash: string; let orderHash: string;
try { try {
const order = JSON.parse(orderJSON); const order = orderParser.parseJsonString(orderJSON);
const validationResult = validator.validate(order, portalOrderSchema); const validationResult = validator.validate(order, portalOrderSchema);
if (validationResult.errors.length > 0) { if (validationResult.errors.length > 0) {
orderJSONErrMsg = 'Submitted order JSON is not a valid order'; orderJSONErrMsg = 'Submitted order JSON is not a valid order';
@ -427,28 +428,12 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
} }
parsedOrder = order; parsedOrder = order;
const signedOrder = parsedOrder.signedOrder; const signedOrder = parsedOrder.signedOrder;
const zeroExOrder: ZeroExOrder = { orderHash = orderHashUtils.getOrderHashHex(signedOrder);
exchangeAddress: signedOrder.exchangeAddress,
expirationTimeSeconds: signedOrder.expirationTimeSeconds,
feeRecipientAddress: signedOrder.feeRecipientAddress,
makerAddress: signedOrder.makerAddress,
makerFee: signedOrder.makerFee,
makerAssetData: signedOrder.makerAssetData,
makerAssetAmount: signedOrder.makerAssetAmount,
salt: signedOrder.salt,
takerAddress: _.isEmpty(signedOrder.takerAddress) ? constants.NULL_ADDRESS : signedOrder.takerAddress,
takerFee: signedOrder.takerFee,
takerAssetData: signedOrder.takerAssetData,
takerAssetAmount: signedOrder.takerAssetAmount,
senderAddress: signedOrder.senderAddress,
};
orderHash = orderHashUtils.getOrderHashHex(zeroExOrder);
const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists(); const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists();
const signature = signedOrder.signature; const signature = signedOrder.signature;
const ecSignature = signatureUtils.parseECSignature(signature); const isSignatureValid = await this.props.blockchain.isValidSignatureAsync(
const isSignatureValid = signatureUtils.isValidECSignature(
orderHash, orderHash,
ecSignature, signature,
signedOrder.makerAddress, signedOrder.makerAddress,
); );
if (exchangeContractAddr !== signedOrder.exchangeAddress) { if (exchangeContractAddr !== signedOrder.exchangeAddress) {
@ -500,6 +485,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
}); });
} }
console.log(parsedOrder);
this.setState({ this.setState({
didOrderValidationRun: true, didOrderValidationRun: true,
orderJSON, orderJSON,

View File

@ -331,7 +331,7 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
salt: hashData.orderSalt, salt: hashData.orderSalt,
takerAddress: hashData.orderTakerAddress, takerAddress: hashData.orderTakerAddress,
takerFee: hashData.takerFee, takerFee: hashData.takerFee,
takerAssetData: hashData.receiveTokenContractAddr, takerAssetData,
takerAssetAmount: hashData.receiveAmount, takerAssetAmount: hashData.receiveAmount,
}; };
const orderHash = orderHashUtils.getOrderHashHex(zeroExOrder); const orderHash = orderHashUtils.getOrderHashHex(zeroExOrder);
@ -339,7 +339,7 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
let globalErrMsg = ''; let globalErrMsg = '';
let order; let order;
try { try {
const ecSignature = await this.props.blockchain.signOrderHashAsync(orderHash); const signature = await this.props.blockchain.signOrderHashAsync(orderHash);
order = utils.generateOrder( order = utils.generateOrder(
exchangeAddress, exchangeAddress,
this.props.sideToAssetToken, this.props.sideToAssetToken,
@ -349,10 +349,11 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
hashData.makerFee, hashData.makerFee,
hashData.takerFee, hashData.takerFee,
hashData.feeRecipientAddress, hashData.feeRecipientAddress,
ecSignature, signature,
this.props.tokenByAddress, this.props.tokenByAddress,
hashData.orderSalt, hashData.orderSalt,
); );
console.log(order);
const validationResult = validator.validate(order, portalOrderSchema); const validationResult = validator.validate(order, portalOrderSchema);
if (validationResult.errors.length > 0) { if (validationResult.errors.length > 0) {
globalErrMsg = 'Order signing failed. Please refresh and try again'; globalErrMsg = 'Order signing failed. Please refresh and try again';

View File

@ -118,7 +118,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
private readonly _throttledScreenWidthUpdate: () => void; private readonly _throttledScreenWidthUpdate: () => void;
constructor(props: PortalProps) { constructor(props: PortalProps) {
super(props); super(props);
this._sharedOrderIfExists = orderParser.parse(window.location.search); this._sharedOrderIfExists = orderParser.parseQueryString(window.location.search);
this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT); this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
const didAcceptPortalDisclaimer = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER); const didAcceptPortalDisclaimer = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER);
const hasAcceptedDisclaimer = const hasAcceptedDisclaimer =

View File

@ -1,7 +1,7 @@
export const portalOrderSchema = { export const portalOrderSchema = {
id: '/PortalOrder', id: '/PortalOrder',
properties: { properties: {
signedOrder: { $ref: '/SignedOrder' }, signedOrder: { $ref: '/signedOrderSchema' },
metadata: { $ref: '/OrderMetadata' }, metadata: { $ref: '/OrderMetadata' },
}, },
required: ['signedOrder', 'metadata'], required: ['signedOrder', 'metadata'],

View File

@ -6,7 +6,7 @@ import { validator } from 'ts/schemas/validator';
import { PortalOrder } from 'ts/types'; import { PortalOrder } from 'ts/types';
export const orderParser = { export const orderParser = {
parse(queryString: string): PortalOrder | undefined { parseQueryString(queryString: string): PortalOrder | undefined {
if (queryString.length === 0) { if (queryString.length === 0) {
return undefined; return undefined;
} }
@ -28,7 +28,22 @@ export const orderParser = {
logUtils.log(`Invalid shared order: ${validationResult.errors}`); logUtils.log(`Invalid shared order: ${validationResult.errors}`);
return undefined; return undefined;
} }
const result = convertOrderStringFieldsToBigNumber(order); const signedOrder = _.get(order, 'signedOrder');
const convertedSignedOrder = convertOrderStringFieldsToBigNumber(signedOrder);
const result = {
...order,
signedOrder: convertedSignedOrder,
};
return result;
},
parseJsonString(orderJson: string): PortalOrder {
const order = JSON.parse(orderJson);
const signedOrder = _.get(order, 'signedOrder');
const convertedSignedOrder = convertOrderStringFieldsToBigNumber(signedOrder);
const result = {
...order,
signedOrder: convertedSignedOrder,
};
return result; return result;
}, },
}; };

View File

@ -1,5 +1,5 @@
import { ContractWrappersError } from '@0xproject/contract-wrappers'; import { ContractWrappersError } from '@0xproject/contract-wrappers';
import { assetDataUtils, OrderError, signatureUtils } from '@0xproject/order-utils'; import { assetDataUtils, OrderError } from '@0xproject/order-utils';
import { constants as sharedConstants, Networks } from '@0xproject/react-shared'; import { constants as sharedConstants, Networks } from '@0xproject/react-shared';
import { ECSignature, ExchangeContractErrs } from '@0xproject/types'; import { ECSignature, ExchangeContractErrs } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils'; import { BigNumber } from '@0xproject/utils';