From 36668f94090fa5c35f636f6b7ba597fcb89c068d Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Thu, 16 Aug 2018 15:28:59 +1000 Subject: [Contract-wrappers] Exchange execute transaction encoder --- .../src/contract_wrappers/exchange_wrapper.ts | 6 + .../src/utils/execute_transaction_encoder.ts | 124 +++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 packages/contract-wrappers/src/utils/execute_transaction_encoder.ts (limited to 'packages/contract-wrappers/src') diff --git a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts index 48bd00f90..12d6a8fd3 100644 --- a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts @@ -21,6 +21,7 @@ import { } from '../types'; import { assert } from '../utils/assert'; import { decorators } from '../utils/decorators'; +import { ExecuteTransactionEncoder } from '../utils/execute_transaction_encoder'; import { ContractWrapper } from './contract_wrapper'; import { ExchangeContract, ExchangeEventArgs, ExchangeEvents } from './generated/exchange'; @@ -1097,6 +1098,11 @@ export class ExchangeWrapper extends ContractWrapper { const zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxTokenAddress); return zrxAssetData; } + public async executeTransactionEncoderAsync(): Promise { + const exchangeInstance = await this._getExchangeContractAsync(); + const encoder = new ExecuteTransactionEncoder(exchangeInstance); + return encoder; + } // tslint:disable:no-unused-variable private _invalidateContractInstances(): void { this.unsubscribeAll(); diff --git a/packages/contract-wrappers/src/utils/execute_transaction_encoder.ts b/packages/contract-wrappers/src/utils/execute_transaction_encoder.ts new file mode 100644 index 000000000..9c941c550 --- /dev/null +++ b/packages/contract-wrappers/src/utils/execute_transaction_encoder.ts @@ -0,0 +1,124 @@ +import { schemas } from '@0xproject/json-schemas'; +import { EIP712Schema, EIP712Types, EIP712Utils } from '@0xproject/order-utils'; +import { Order, SignedOrder } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import _ = require('lodash'); + +import { ExchangeContract } from '../contract_wrappers/generated/exchange'; + +import { assert } from './assert'; + +const EIP712_ZEROEX_TRANSACTION_SCHEMA: EIP712Schema = { + name: 'ZeroExTransaction', + parameters: [ + { name: 'salt', type: EIP712Types.Uint256 }, + { name: 'signerAddress', type: EIP712Types.Address }, + { name: 'data', type: EIP712Types.Bytes }, + ], +}; + +export class ExecuteTransactionEncoder { + private _exchangeInstance: ExchangeContract; + constructor(exchangeInstance: ExchangeContract) { + this._exchangeInstance = exchangeInstance; + } + public getExecuteTransactionHex(data: string, salt: BigNumber, signerAddress: string): string { + const exchangeAddress = this._exchangeInstance.address; + const executeTransactionData = { + salt, + signerAddress, + data, + }; + const executeTransactionHashBuff = EIP712Utils.structHash( + EIP712_ZEROEX_TRANSACTION_SCHEMA, + executeTransactionData, + ); + const eip721MessageBuffer = EIP712Utils.createEIP712Message(executeTransactionHashBuff, exchangeAddress); + const messageHex = `0x${eip721MessageBuffer.toString('hex')}`; + return messageHex; + } + public fillOrder(signedOrder: SignedOrder, takerAssetFillAmount: BigNumber): string { + assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); + assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount); + const abiEncodedData = this._exchangeInstance.fillOrder.getABIEncodedTransactionData( + signedOrder, + takerAssetFillAmount, + signedOrder.signature, + ); + return abiEncodedData; + } + public fillOrderNoThrow(signedOrder: SignedOrder, takerAssetFillAmount: BigNumber): string { + assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); + assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount); + const abiEncodedData = this._exchangeInstance.fillOrderNoThrow.getABIEncodedTransactionData( + signedOrder, + takerAssetFillAmount, + signedOrder.signature, + ); + return abiEncodedData; + } + public fillOrKillOrder(signedOrder: SignedOrder, takerAssetFillAmount: BigNumber): string { + assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); + assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount); + const abiEncodedData = this._exchangeInstance.fillOrKillOrder.getABIEncodedTransactionData( + signedOrder, + takerAssetFillAmount, + signedOrder.signature, + ); + return abiEncodedData; + } + public cancelOrdersUpTo(targetOrderEpoch: BigNumber): string { + assert.isBigNumber('targetOrderEpoch', targetOrderEpoch); + const abiEncodedData = this._exchangeInstance.cancelOrdersUpTo.getABIEncodedTransactionData(targetOrderEpoch); + return abiEncodedData; + } + public cancelOrder(order: Order | SignedOrder): string { + assert.doesConformToSchema('order', order, schemas.orderSchema); + const abiEncodedData = this._exchangeInstance.cancelOrder.getABIEncodedTransactionData(order); + return abiEncodedData; + } + public marketSellOrders(signedOrders: SignedOrder[], takerAssetFillAmount: BigNumber): string { + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); + assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount); + const signatures = _.map(signedOrders, signedOrder => signedOrder.signature); + const abiEncodedData = this._exchangeInstance.marketSellOrders.getABIEncodedTransactionData( + signedOrders, + takerAssetFillAmount, + signatures, + ); + return abiEncodedData; + } + public marketSellOrdersNoThrow(signedOrders: SignedOrder[], takerAssetFillAmount: BigNumber): string { + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); + assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount); + const signatures = _.map(signedOrders, signedOrder => signedOrder.signature); + const abiEncodedData = this._exchangeInstance.marketSellOrdersNoThrow.getABIEncodedTransactionData( + signedOrders, + takerAssetFillAmount, + signatures, + ); + return abiEncodedData; + } + public marketBuyOrders(signedOrders: SignedOrder[], makerAssetFillAmount: BigNumber): string { + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); + assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount); + const signatures = _.map(signedOrders, signedOrder => signedOrder.signature); + const abiEncodedData = this._exchangeInstance.marketBuyOrders.getABIEncodedTransactionData( + signedOrders, + makerAssetFillAmount, + signatures, + ); + return abiEncodedData; + } + public marketBuyOrdersNoThrow(signedOrders: SignedOrder[], makerAssetFillAmount: BigNumber): string { + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); + assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount); + const signatures = _.map(signedOrders, signedOrder => signedOrder.signature); + const abiEncodedData = this._exchangeInstance.marketBuyOrdersNoThrow.getABIEncodedTransactionData( + signedOrders, + makerAssetFillAmount, + signatures, + ); + return abiEncodedData; + } +} -- cgit v1.2.3