diff options
Diffstat (limited to 'packages/contract-wrappers/src')
4 files changed, 56 insertions, 12 deletions
diff --git a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts index 19de17c0a..f7a89e3be 100644 --- a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts @@ -1,5 +1,5 @@ import { AbiDecoder, intervalUtils, logUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { marshaller, Web3Wrapper } from '@0xproject/web3-wrapper'; import { BlockParamLiteral, ContractAbi, @@ -8,6 +8,7 @@ import { LogEntry, LogWithDecodedArgs, RawLog, + RawLogEntry, } from 'ethereum-types'; import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream'; import * as _ from 'lodash'; @@ -157,7 +158,8 @@ export abstract class ContractWrapper { return addressIfExists; } } - private _onLogStateChanged<ArgsType extends ContractEventArgs>(isRemoved: boolean, log: LogEntry): void { + private _onLogStateChanged<ArgsType extends ContractEventArgs>(isRemoved: boolean, rawLog: RawLogEntry): void { + const log: LogEntry = marshaller.unmarshalLog(rawLog); _.forEach(this._filters, (filter: FilterObject, filterToken: string) => { if (filterUtils.matchesFilter(log, filter)) { const decodedLog = this._tryToDecodeLogOrNoop(log) as LogWithDecodedArgs<ArgsType>; @@ -174,8 +176,8 @@ export abstract class ContractWrapper { throw new Error(ContractWrappersError.SubscriptionAlreadyPresent); } this._blockAndLogStreamerIfExists = new BlockAndLogStreamer( - this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper), - this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper), + this._blockstreamGetBlockOrNullAsync.bind(this), + this._blockstreamGetLogsAsync.bind(this), ContractWrapper._onBlockAndLogStreamerError.bind(this, isVerbose), ); const catchAllLogFilter = {}; @@ -194,6 +196,32 @@ export abstract class ContractWrapper { this._onLogStateChanged.bind(this, isRemoved), ); } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetBlockOrNullAsync(hash: string): Promise<Block | null> { + const shouldIncludeTransactionData = false; + const blockOrNull = await this._web3Wrapper.sendRawPayloadAsync<Block | null>({ + method: 'eth_getBlockByHash', + params: [hash, shouldIncludeTransactionData], + }); + return blockOrNull; + } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetLatestBlockOrNullAsync(): Promise<Block | null> { + const shouldIncludeTransactionData = false; + const blockOrNull = await this._web3Wrapper.sendRawPayloadAsync<Block | null>({ + method: 'eth_getBlockByNumber', + params: [BlockParamLiteral.Latest, shouldIncludeTransactionData], + }); + return blockOrNull; + } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetLogsAsync(filterOptions: FilterObject): Promise<RawLogEntry[]> { + const logs = await this._web3Wrapper.sendRawPayloadAsync<RawLogEntry[]>({ + method: 'eth_getLogs', + params: [filterOptions], + }); + return logs as RawLogEntry[]; + } // HACK: This should be a package-scoped method (which doesn't exist in TS) // We don't want this method available in the public interface for all classes // who inherit from ContractWrapper, and it is only used by the internal implementation @@ -212,11 +240,14 @@ export abstract class ContractWrapper { delete this._blockAndLogStreamerIfExists; } private async _reconcileBlockAsync(): Promise<void> { - const latestBlock = await this._web3Wrapper.getBlockAsync(BlockParamLiteral.Latest); + const latestBlockOrNull = await this._blockstreamGetLatestBlockOrNullAsync(); + if (_.isNull(latestBlockOrNull)) { + return; // noop + } // We need to coerce to Block type cause Web3.Block includes types for mempool blocks if (!_.isUndefined(this._blockAndLogStreamerIfExists)) { // If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined - await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlock as any) as Block); + await this._blockAndLogStreamerIfExists.reconcileNewBlock(latestBlockOrNull); } } } diff --git a/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts index 13ef0fe01..906222731 100644 --- a/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts @@ -12,6 +12,7 @@ import { TransactionOpts } from '../types'; import { assert } from '../utils/assert'; import { calldataOptimizationUtils } from '../utils/calldata_optimization_utils'; import { constants } from '../utils/constants'; +import { utils } from '../utils/utils'; import { ContractWrapper } from './contract_wrapper'; import { ForwarderContract } from './generated/forwarder'; @@ -57,7 +58,7 @@ export class ForwarderWrapper extends ContractWrapper { takerAddress: string, ethAmount: BigNumber, signedFeeOrders: SignedOrder[] = [], - feePercentage: BigNumber = constants.ZERO_AMOUNT, + feePercentage: number = 0, feeRecipientAddress: string = constants.NULL_ADDRESS, txOpts: TransactionOpts = {}, ): Promise<string> { @@ -66,7 +67,7 @@ export class ForwarderWrapper extends ContractWrapper { await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); assert.isBigNumber('ethAmount', ethAmount); assert.doesConformToSchema('signedFeeOrders', signedFeeOrders, schemas.signedOrdersSchema); - assert.isBigNumber('feePercentage', feePercentage); + assert.isNumber('feePercentage', feePercentage); assert.isETHAddressHex('feeRecipientAddress', feeRecipientAddress); assert.doesConformToSchema('txOpts', txOpts, txOptsSchema); // other assertions @@ -76,6 +77,8 @@ export class ForwarderWrapper extends ContractWrapper { this.getZRXTokenAddress(), this.getEtherTokenAddress(), ); + // format feePercentage + const formattedFeePercentage = utils.numberPercentageToEtherTokenAmountPercentage(feePercentage); // lowercase input addresses const normalizedTakerAddress = takerAddress.toLowerCase(); const normalizedFeeRecipientAddress = feeRecipientAddress.toLowerCase(); @@ -89,7 +92,7 @@ export class ForwarderWrapper extends ContractWrapper { _.map(optimizedMarketOrders, order => order.signature), optimizedFeeOrders, _.map(optimizedFeeOrders, order => order.signature), - feePercentage, + formattedFeePercentage, feeRecipientAddress, { value: ethAmount, @@ -124,7 +127,7 @@ export class ForwarderWrapper extends ContractWrapper { takerAddress: string, ethAmount: BigNumber, signedFeeOrders: SignedOrder[] = [], - feePercentage: BigNumber = constants.ZERO_AMOUNT, + feePercentage: number = 0, feeRecipientAddress: string = constants.NULL_ADDRESS, txOpts: TransactionOpts = {}, ): Promise<string> { @@ -134,7 +137,7 @@ export class ForwarderWrapper extends ContractWrapper { await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); assert.isBigNumber('ethAmount', ethAmount); assert.doesConformToSchema('signedFeeOrders', signedFeeOrders, schemas.signedOrdersSchema); - assert.isBigNumber('feePercentage', feePercentage); + assert.isNumber('feePercentage', feePercentage); assert.isETHAddressHex('feeRecipientAddress', feeRecipientAddress); assert.doesConformToSchema('txOpts', txOpts, txOptsSchema); // other assertions @@ -144,6 +147,8 @@ export class ForwarderWrapper extends ContractWrapper { this.getZRXTokenAddress(), this.getEtherTokenAddress(), ); + // format feePercentage + const formattedFeePercentage = utils.numberPercentageToEtherTokenAmountPercentage(feePercentage); // lowercase input addresses const normalizedTakerAddress = takerAddress.toLowerCase(); const normalizedFeeRecipientAddress = feeRecipientAddress.toLowerCase(); @@ -158,7 +163,7 @@ export class ForwarderWrapper extends ContractWrapper { _.map(optimizedMarketOrders, order => order.signature), optimizedFeeOrders, _.map(optimizedFeeOrders, order => order.signature), - feePercentage, + formattedFeePercentage, feeRecipientAddress, { value: ethAmount, diff --git a/packages/contract-wrappers/src/utils/constants.ts b/packages/contract-wrappers/src/utils/constants.ts index 2df11538c..78441decf 100644 --- a/packages/contract-wrappers/src/utils/constants.ts +++ b/packages/contract-wrappers/src/utils/constants.ts @@ -12,4 +12,6 @@ export const constants = { UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1), DEFAULT_BLOCK_POLLING_INTERVAL: 1000, ZERO_AMOUNT: new BigNumber(0), + ONE_AMOUNT: new BigNumber(1), + ETHER_TOKEN_DECIMALS: 18, }; diff --git a/packages/contract-wrappers/src/utils/utils.ts b/packages/contract-wrappers/src/utils/utils.ts index 689a7ee0a..f7949ec34 100644 --- a/packages/contract-wrappers/src/utils/utils.ts +++ b/packages/contract-wrappers/src/utils/utils.ts @@ -1,4 +1,7 @@ import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; + +import { constants } from './constants'; export const utils = { getCurrentUnixTimestampSec(): BigNumber { @@ -8,4 +11,7 @@ export const utils = { getCurrentUnixTimestampMs(): BigNumber { return new BigNumber(Date.now()); }, + numberPercentageToEtherTokenAmountPercentage(percentage: number): BigNumber { + return Web3Wrapper.toBaseUnitAmount(constants.ONE_AMOUNT, constants.ETHER_TOKEN_DECIMALS).mul(percentage); + }, }; |