Fix utils to work with new ABI

This commit is contained in:
Amir Bandeali
2018-02-08 11:48:03 -08:00
parent 1ad31ab007
commit 389f1cde51
5 changed files with 148 additions and 68 deletions

View File

@@ -18,22 +18,16 @@ export class ExchangeWrapper {
public async fillOrderAsync(
signedOrder: SignedOrder,
from: string,
opts: {
fillTakerTokenAmount?: BigNumber;
shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
} = {},
opts: { takerTokenFillAmount?: BigNumber } = {},
): Promise<TransactionReceiptWithDecodedLogs> {
const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
const params = signedOrderUtils.createFill(
signedOrder,
shouldThrowOnInsufficientBalanceOrAllowance,
opts.fillTakerTokenAmount,
opts.takerTokenFillAmount,
);
const txHash = await this._exchange.fillOrder.sendTransactionAsync(
params.orderAddresses,
params.orderValues,
params.fillTakerTokenAmount,
params.shouldThrowOnInsufficientBalanceOrAllowance,
params.takerTokenFillAmount,
params.v,
params.r,
params.s,
@@ -47,13 +41,13 @@ export class ExchangeWrapper {
public async cancelOrderAsync(
signedOrder: SignedOrder,
from: string,
opts: { cancelTakerTokenAmount?: BigNumber } = {},
opts: { takerTokenCancelAmount?: BigNumber } = {},
): Promise<TransactionReceiptWithDecodedLogs> {
const params = signedOrderUtils.createCancel(signedOrder, opts.cancelTakerTokenAmount);
const params = signedOrderUtils.createCancel(signedOrder, opts.takerTokenCancelAmount);
const txHash = await this._exchange.cancelOrder.sendTransactionAsync(
params.orderAddresses,
params.orderValues,
params.cancelTakerTokenAmount,
params.takerTokenCancelAmount,
{ from },
);
const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash);
@@ -64,18 +58,16 @@ export class ExchangeWrapper {
public async fillOrKillOrderAsync(
signedOrder: SignedOrder,
from: string,
opts: { fillTakerTokenAmount?: BigNumber } = {},
opts: { takerTokenFillAmount?: BigNumber } = {},
): Promise<TransactionReceiptWithDecodedLogs> {
const shouldThrowOnInsufficientBalanceOrAllowance = true;
const params = signedOrderUtils.createFill(
signedOrder,
shouldThrowOnInsufficientBalanceOrAllowance,
opts.fillTakerTokenAmount,
opts.takerTokenFillAmount,
);
const txHash = await this._exchange.fillOrKillOrder.sendTransactionAsync(
params.orderAddresses,
params.orderValues,
params.fillTakerTokenAmount,
params.takerTokenFillAmount,
params.v,
params.r,
params.s,
@@ -90,21 +82,18 @@ export class ExchangeWrapper {
orders: SignedOrder[],
from: string,
opts: {
fillTakerTokenAmounts?: BigNumber[];
takerTokenFillAmounts?: BigNumber[];
shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
} = {},
): Promise<TransactionReceiptWithDecodedLogs> {
const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
const params = formatters.createBatchFill(
orders,
shouldThrowOnInsufficientBalanceOrAllowance,
opts.fillTakerTokenAmounts,
opts.takerTokenFillAmounts,
);
const txHash = await this._exchange.batchFillOrders.sendTransactionAsync(
params.orderAddresses,
params.orderValues,
params.fillTakerTokenAmounts,
params.shouldThrowOnInsufficientBalanceOrAllowance,
params.takerTokenFillAmounts,
params.v,
params.r,
params.s,
@@ -118,18 +107,16 @@ export class ExchangeWrapper {
public async batchFillOrKillOrdersAsync(
orders: SignedOrder[],
from: string,
opts: { fillTakerTokenAmounts?: BigNumber[]; shouldThrowOnInsufficientBalanceOrAllowance?: boolean } = {},
opts: { takerTokenFillAmounts?: BigNumber[] } = {},
): Promise<TransactionReceiptWithDecodedLogs> {
const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
const params = formatters.createBatchFill(
orders,
shouldThrowOnInsufficientBalanceOrAllowance,
opts.fillTakerTokenAmounts,
opts.takerTokenFillAmounts,
);
const txHash = await this._exchange.batchFillOrKillOrders.sendTransactionAsync(
params.orderAddresses,
params.orderValues,
params.fillTakerTokenAmounts,
params.takerTokenFillAmounts,
params.v,
params.r,
params.s,
@@ -140,22 +127,19 @@ export class ExchangeWrapper {
_.each(tx.logs, log => wrapLogBigNumbers(log));
return tx;
}
public async fillOrdersUpToAsync(
public async marketFillOrdersAsync(
orders: SignedOrder[],
from: string,
opts: { fillTakerTokenAmount: BigNumber; shouldThrowOnInsufficientBalanceOrAllowance?: boolean },
opts: { takerTokenFillAmount: BigNumber },
): Promise<TransactionReceiptWithDecodedLogs> {
const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
const params = formatters.createFillUpTo(
const params = formatters.createMarketFillOrders(
orders,
shouldThrowOnInsufficientBalanceOrAllowance,
opts.fillTakerTokenAmount,
opts.takerTokenFillAmount,
);
const txHash = await this._exchange.fillOrdersUpTo.sendTransactionAsync(
const txHash = await this._exchange.marketFillOrders.sendTransactionAsync(
params.orderAddresses,
params.orderValues,
params.fillTakerTokenAmount,
params.shouldThrowOnInsufficientBalanceOrAllowance,
params.takerTokenFillAmount,
params.v,
params.r,
params.s,
@@ -184,7 +168,6 @@ export class ExchangeWrapper {
return tx;
}
public async getOrderHashAsync(signedOrder: SignedOrder): Promise<string> {
const shouldThrowOnInsufficientBalanceOrAllowance = false;
const params = signedOrderUtils.getOrderAddressesAndValues(signedOrder);
const orderHash = await this._exchange.getOrderHash.callAsync(params.orderAddresses, params.orderValues);
return orderHash;

View File

@@ -2,19 +2,17 @@ import { SignedOrder } from '0x.js';
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import { BatchCancelOrders, BatchFillOrders, FillOrdersUpTo } from './types';
import { BatchCancelOrders, BatchFillOrders, MarketFillOrders } from './types';
export const formatters = {
createBatchFill(
signedOrders: SignedOrder[],
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
fillTakerTokenAmounts: BigNumber[] = [],
takerTokenFillAmounts: BigNumber[] = [],
) {
const batchFill: BatchFillOrders = {
orderAddresses: [],
orderValues: [],
fillTakerTokenAmounts,
shouldThrowOnInsufficientBalanceOrAllowance,
takerTokenFillAmounts,
v: [],
r: [],
s: [],
@@ -38,35 +36,33 @@ export const formatters = {
batchFill.v.push(signedOrder.ecSignature.v);
batchFill.r.push(signedOrder.ecSignature.r);
batchFill.s.push(signedOrder.ecSignature.s);
if (fillTakerTokenAmounts.length < signedOrders.length) {
batchFill.fillTakerTokenAmounts.push(signedOrder.takerTokenAmount);
if (takerTokenFillAmounts.length < signedOrders.length) {
batchFill.takerTokenFillAmounts.push(signedOrder.takerTokenAmount);
}
});
return batchFill;
},
createFillUpTo(
createMarketFillOrders(
signedOrders: SignedOrder[],
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
fillTakerTokenAmount: BigNumber,
takerTokenFillAmount: BigNumber,
) {
const fillUpTo: FillOrdersUpTo = {
const marketFillOrders: MarketFillOrders = {
orderAddresses: [],
orderValues: [],
fillTakerTokenAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
takerTokenFillAmount,
v: [],
r: [],
s: [],
};
signedOrders.forEach(signedOrder => {
fillUpTo.orderAddresses.push([
marketFillOrders.orderAddresses.push([
signedOrder.maker,
signedOrder.taker,
signedOrder.makerTokenAddress,
signedOrder.takerTokenAddress,
signedOrder.feeRecipient,
]);
fillUpTo.orderValues.push([
marketFillOrders.orderValues.push([
signedOrder.makerTokenAmount,
signedOrder.takerTokenAmount,
signedOrder.makerFee,
@@ -74,11 +70,11 @@ export const formatters = {
signedOrder.expirationUnixTimestampSec,
signedOrder.salt,
]);
fillUpTo.v.push(signedOrder.ecSignature.v);
fillUpTo.r.push(signedOrder.ecSignature.r);
fillUpTo.s.push(signedOrder.ecSignature.s);
marketFillOrders.v.push(signedOrder.ecSignature.v);
marketFillOrders.r.push(signedOrder.ecSignature.r);
marketFillOrders.s.push(signedOrder.ecSignature.s);
});
return fillUpTo;
return marketFillOrders;
},
createBatchCancel(signedOrders: SignedOrder[], cancelTakerTokenAmounts: BigNumber[] = []) {
const batchCancel: BatchCancelOrders = {

View File

@@ -0,0 +1,105 @@
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import ethUtil = require('ethereumjs-util');
import * as _ from 'lodash';
import { crypto } from './crypto';
import { OrderParams } from './types';
export class Order {
public params: OrderParams;
private _web3Wrapper: Web3Wrapper;
constructor(web3Wrapper: Web3Wrapper, params: OrderParams) {
this.params = params;
this._web3Wrapper = web3Wrapper;
}
public isValidSignature() {
const { v, r, s } = this.params;
if (_.isUndefined(v) || _.isUndefined(r) || _.isUndefined(s)) {
throw new Error('Cannot call isValidSignature on unsigned order');
}
const orderHash = this._getOrderHash();
const msgHash = ethUtil.hashPersonalMessage(ethUtil.toBuffer(orderHash));
try {
const pubKey = ethUtil.ecrecover(msgHash, v, ethUtil.toBuffer(r), ethUtil.toBuffer(s));
const recoveredAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
return recoveredAddress === this.params.maker;
} catch (err) {
return false;
}
}
public async signAsync() {
const orderHash = this._getOrderHash();
const signature = await this._web3Wrapper.signTransactionAsync(this.params.maker, orderHash);
const { v, r, s } = ethUtil.fromRpcSig(signature);
this.params = _.assign(this.params, {
orderHashHex: orderHash,
v,
r: ethUtil.bufferToHex(r),
s: ethUtil.bufferToHex(s),
});
}
public createFill(takerTokenFillAmount?: BigNumber) {
const fill = {
orderAddresses: [
this.params.maker,
this.params.taker,
this.params.makerToken,
this.params.takerToken,
this.params.feeRecipient,
],
orderValues: [
this.params.makerTokenAmount,
this.params.takerTokenAmount,
this.params.makerFee,
this.params.takerFee,
this.params.expirationTimestampInSec,
this.params.salt,
],
takerTokenFillAmount: takerTokenFillAmount || this.params.takerTokenAmount,
v: this.params.v,
r: this.params.r,
s: this.params.s,
};
return fill;
}
public createCancel(takerTokenCancelAmount?: BigNumber) {
const cancel = {
orderAddresses: [
this.params.maker,
this.params.taker,
this.params.makerToken,
this.params.takerToken,
this.params.feeRecipient,
],
orderValues: [
this.params.makerTokenAmount,
this.params.takerTokenAmount,
this.params.makerFee,
this.params.takerFee,
this.params.expirationTimestampInSec,
this.params.salt,
],
takerTokenCancelAmount: takerTokenCancelAmount || this.params.takerTokenAmount,
};
return cancel;
}
private _getOrderHash(): string {
const orderHash = crypto.solSHA3([
this.params.exchangeContractAddress,
this.params.maker,
this.params.taker,
this.params.makerToken,
this.params.takerToken,
this.params.feeRecipient,
this.params.makerTokenAmount,
this.params.takerTokenAmount,
this.params.makerFee,
this.params.takerFee,
this.params.expirationTimestampInSec,
this.params.salt,
]);
const orderHashHex = ethUtil.bufferToHex(orderHash);
return orderHashHex;
}
}

View File

@@ -9,21 +9,19 @@ import { crypto } from './crypto';
export const signedOrderUtils = {
createFill: (
signedOrder: SignedOrder,
shouldThrowOnInsufficientBalanceOrAllowance?: boolean,
fillTakerTokenAmount?: BigNumber,
takerTokenFillAmount?: BigNumber,
) => {
const fill = {
...signedOrderUtils.getOrderAddressesAndValues(signedOrder),
fillTakerTokenAmount: fillTakerTokenAmount || signedOrder.takerTokenAmount,
shouldThrowOnInsufficientBalanceOrAllowance: !!shouldThrowOnInsufficientBalanceOrAllowance,
takerTokenFillAmount: takerTokenFillAmount || signedOrder.takerTokenAmount,
...signedOrder.ecSignature,
};
return fill;
},
createCancel(signedOrder: SignedOrder, cancelTakerTokenAmount?: BigNumber) {
createCancel(signedOrder: SignedOrder, takerTokenCancelAmount?: BigNumber) {
const cancel = {
...signedOrderUtils.getOrderAddressesAndValues(signedOrder),
cancelTakerTokenAmount: cancelTakerTokenAmount || signedOrder.takerTokenAmount,
takerTokenCancelAmount: takerTokenCancelAmount || signedOrder.takerTokenAmount,
};
return cancel;
},

View File

@@ -14,18 +14,16 @@ export interface SubmissionContractEventArgs {
export interface BatchFillOrders {
orderAddresses: string[][];
orderValues: BigNumber[][];
fillTakerTokenAmounts: BigNumber[];
shouldThrowOnInsufficientBalanceOrAllowance: boolean;
takerTokenFillAmounts: BigNumber[];
v: number[];
r: string[];
s: string[];
}
export interface FillOrdersUpTo {
export interface MarketFillOrders {
orderAddresses: string[][];
orderValues: BigNumber[][];
fillTakerTokenAmount: BigNumber;
shouldThrowOnInsufficientBalanceOrAllowance: boolean;
takerTokenFillAmount: BigNumber;
v: number[];
r: string[];
s: string[];