import { AssetProxyId, SignedOrder } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import * as _ from 'lodash'; import { ExchangeContract } from '../generated_contract_wrappers/exchange'; import { constants } from './constants'; import { formatters } from './formatters'; import { LogDecoder } from './log_decoder'; import { orderUtils } from './order_utils'; import { OrderInfo, SignedTransaction } from './types'; export class ExchangeWrapper { private _exchange: ExchangeContract; private _web3Wrapper: Web3Wrapper; private _logDecoder: LogDecoder; constructor(exchangeContract: ExchangeContract, provider: Provider) { this._exchange = exchangeContract; this._web3Wrapper = new Web3Wrapper(provider); this._logDecoder = new LogDecoder(this._web3Wrapper, this._exchange.address); } public async fillOrderAsync( signedOrder: SignedOrder, from: string, opts: { takerAssetFillAmount?: BigNumber } = {}, ): Promise { const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount); const txHash = await this._exchange.fillOrder.sendTransactionAsync( params.order, params.takerAssetFillAmount, params.signature, { from }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async cancelOrderAsync(signedOrder: SignedOrder, from: string): Promise { const params = orderUtils.createCancel(signedOrder); const txHash = await this._exchange.cancelOrder.sendTransactionAsync(params.order, { from }); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async fillOrKillOrderAsync( signedOrder: SignedOrder, from: string, opts: { takerAssetFillAmount?: BigNumber } = {}, ): Promise { const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount); const txHash = await this._exchange.fillOrKillOrder.sendTransactionAsync( params.order, params.takerAssetFillAmount, params.signature, { from }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async fillOrderNoThrowAsync( signedOrder: SignedOrder, from: string, opts: { takerAssetFillAmount?: BigNumber; gas?: number } = {}, ): Promise { const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount); const txHash = await this._exchange.fillOrderNoThrow.sendTransactionAsync( params.order, params.takerAssetFillAmount, params.signature, { from, gas: opts.gas }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async batchFillOrdersAsync( orders: SignedOrder[], from: string, opts: { takerAssetFillAmounts?: BigNumber[] } = {}, ): Promise { const params = formatters.createBatchFill(orders, opts.takerAssetFillAmounts); const txHash = await this._exchange.batchFillOrders.sendTransactionAsync( params.orders, params.takerAssetFillAmounts, params.signatures, { from }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async batchFillOrKillOrdersAsync( orders: SignedOrder[], from: string, opts: { takerAssetFillAmounts?: BigNumber[] } = {}, ): Promise { const params = formatters.createBatchFill(orders, opts.takerAssetFillAmounts); const txHash = await this._exchange.batchFillOrKillOrders.sendTransactionAsync( params.orders, params.takerAssetFillAmounts, params.signatures, { from }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async batchFillOrdersNoThrowAsync( orders: SignedOrder[], from: string, opts: { takerAssetFillAmounts?: BigNumber[]; gas?: number } = {}, ): Promise { const params = formatters.createBatchFill(orders, opts.takerAssetFillAmounts); const txHash = await this._exchange.batchFillOrdersNoThrow.sendTransactionAsync( params.orders, params.takerAssetFillAmounts, params.signatures, { from, gas: opts.gas }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async marketSellOrdersAsync( orders: SignedOrder[], from: string, opts: { takerAssetFillAmount: BigNumber }, ): Promise { const params = formatters.createMarketSellOrders(orders, opts.takerAssetFillAmount); const txHash = await this._exchange.marketSellOrders.sendTransactionAsync( params.orders, params.takerAssetFillAmount, params.signatures, { from }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async marketSellOrdersNoThrowAsync( orders: SignedOrder[], from: string, opts: { takerAssetFillAmount: BigNumber; gas?: number }, ): Promise { const params = formatters.createMarketSellOrders(orders, opts.takerAssetFillAmount); const txHash = await this._exchange.marketSellOrdersNoThrow.sendTransactionAsync( params.orders, params.takerAssetFillAmount, params.signatures, { from, gas: opts.gas }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async marketBuyOrdersAsync( orders: SignedOrder[], from: string, opts: { makerAssetFillAmount: BigNumber }, ): Promise { const params = formatters.createMarketBuyOrders(orders, opts.makerAssetFillAmount); const txHash = await this._exchange.marketBuyOrders.sendTransactionAsync( params.orders, params.makerAssetFillAmount, params.signatures, { from }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async marketBuyOrdersNoThrowAsync( orders: SignedOrder[], from: string, opts: { makerAssetFillAmount: BigNumber; gas?: number }, ): Promise { const params = formatters.createMarketBuyOrders(orders, opts.makerAssetFillAmount); const txHash = await this._exchange.marketBuyOrdersNoThrow.sendTransactionAsync( params.orders, params.makerAssetFillAmount, params.signatures, { from, gas: opts.gas }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async batchCancelOrdersAsync( orders: SignedOrder[], from: string, ): Promise { const params = formatters.createBatchCancel(orders); const txHash = await this._exchange.batchCancelOrders.sendTransactionAsync(params.orders, { from }); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async cancelOrdersUpToAsync(salt: BigNumber, from: string): Promise { const txHash = await this._exchange.cancelOrdersUpTo.sendTransactionAsync(salt, { from }); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async registerAssetProxyAsync( assetProxyId: AssetProxyId, assetProxyAddress: string, from: string, opts: { oldAssetProxyAddressIfExists?: string } = {}, ): Promise { const oldAssetProxyAddress = _.isUndefined(opts.oldAssetProxyAddressIfExists) ? constants.NULL_ADDRESS : opts.oldAssetProxyAddressIfExists; const txHash = await this._exchange.registerAssetProxy.sendTransactionAsync( assetProxyId, assetProxyAddress, oldAssetProxyAddress, { from }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async executeTransactionAsync( signedTx: SignedTransaction, from: string, ): Promise { const txHash = await this._exchange.executeTransaction.sendTransactionAsync( signedTx.salt, signedTx.signer, signedTx.data, signedTx.signature, { from }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } public async getTakerAssetFilledAmountAsync(orderHashHex: string): Promise { const filledAmount = new BigNumber(await this._exchange.filled.callAsync(orderHashHex)); return filledAmount; } public async getOrderInfoAsync(signedOrder: SignedOrder): Promise { const orderInfo = (await this._exchange.getOrderInfo.callAsync(signedOrder)) as OrderInfo; return orderInfo; } public async matchOrdersAsync( signedOrderLeft: SignedOrder, signedOrderRight: SignedOrder, from: string, ): Promise { const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight); const txHash = await this._exchange.matchOrders.sendTransactionAsync( params.left, params.right, params.leftSignature, params.rightSignature, { from }, ); const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash); return tx; } }