From 5410924810fa597b495b1ee065a68195d3725b7c Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 11:38:16 +0300 Subject: Add type aliases for web3 types --- src/types.ts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/types.ts b/src/types.ts index 02230b0ab..d9059e7be 100644 --- a/src/types.ts +++ b/src/types.ts @@ -234,6 +234,8 @@ export enum ExchangeContractErrs { BatchOrdersMustHaveAtLeastOneItem = 'BATCH_ORDERS_MUST_HAVE_AT_LEAST_ONE_ITEM', } +export type RawLog = Web3.LogEntry; + export interface ContractEvent { logIndex: number; transactionIndex: number; @@ -460,3 +462,5 @@ export interface MethodOpts { export interface OrderTransactionOpts { shouldValidate: boolean; } + +export type FilterObject = Web3.FilterObject; -- cgit v1.2.3 From ea08fc8642018a348f130d829758601b6752f4a8 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 11:38:47 +0300 Subject: Add getLogsAsync to web3_wrapper --- src/web3_wrapper.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src') diff --git a/src/web3_wrapper.ts b/src/web3_wrapper.ts index 0bf80a6e4..653205988 100644 --- a/src/web3_wrapper.ts +++ b/src/web3_wrapper.ts @@ -9,10 +9,12 @@ export class Web3Wrapper { private web3: Web3; private defaults: Partial; private networkIdIfExists?: number; + private jsonRpcRequestId: number; constructor(provider: Web3.Provider, defaults: Partial) { this.web3 = new Web3(); this.web3.setProvider(provider); this.defaults = defaults; + this.jsonRpcRequestId = 0; } public setProvider(provider: Web3.Provider) { delete this.networkIdIfExists; @@ -100,6 +102,16 @@ export class Web3Wrapper { const addresses: string[] = await promisify(this.web3.eth.getAccounts)(); return addresses; } + public async getLogsAsync(filter: Web3.FilterObject): Promise { + const payload = { + jsonrpc: '2.0', + id: this.jsonRpcRequestId++, + method: 'eth_getLogs', + params: [filter], + }; + const logs = await this.sendRawPayloadAsync(payload); + return logs; + } private getContractInstance(abi: Web3.ContractAbi, address: string): A { const web3ContractInstance = this.web3.eth.contract(abi).at(address); const contractInstance = new Contract(web3ContractInstance, this.defaults) as any as A; @@ -109,4 +121,10 @@ export class Web3Wrapper { const networkId = await promisify(this.web3.version.getNetwork)(); return networkId; } + private async sendRawPayloadAsync(payload: Web3.JSONRPCRequestPayload): Promise { + const sendAsync = this.web3.currentProvider.sendAsync.bind(this.web3.currentProvider); + const response = await promisify(sendAsync)(payload); + const result = response.result; + return result; + } } -- cgit v1.2.3 From 7b545aa0e0dfcdb923d64494614f303bc3b3036a Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 11:39:11 +0300 Subject: Re-export new types --- src/index.ts | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/index.ts b/src/index.ts index 9730d3fef..8e81d83a7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,4 +35,6 @@ export { DecodedLogArgs, MethodOpts, OrderTransactionOpts, + FilterObject, + RawLog, } from './types'; -- cgit v1.2.3 From 835c17c9612b184208c72c15a3ca0c815057ccf3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 11:39:34 +0300 Subject: Add zeroEx.getLogsAsync --- src/0x.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/0x.ts b/src/0x.ts index e6fdf68e1..ae29b8d70 100644 --- a/src/0x.ts +++ b/src/0x.ts @@ -31,6 +31,8 @@ import { DecodedLogArgs, TransactionReceiptWithDecodedLogs, LogWithDecodedArgs, + FilterObject, + RawLog, } from './types'; import {zeroExConfigSchema} from './schemas/zero_ex_config_schema'; @@ -321,6 +323,15 @@ export class ZeroEx { }); return txReceiptPromise; } + /** + * Gets historical logs without creating a subscription + * @param filter Filter object + * @return Array of logs that match the filter + */ + public async getLogsAsync(filter: FilterObject): Promise { + const logs = await this._web3Wrapper.getLogsAsync(filter); + return logs; + } /* * HACK: `TokenWrapper` needs a token transfer proxy address. `TokenTransferProxy` address is fetched from * an `ExchangeWrapper`. `ExchangeWrapper` needs `TokenWrapper` to validate orders, creating a dependency cycle. -- cgit v1.2.3 From a9681072ee4b45bda23b754fa46175b68c09b8b9 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 12:20:33 +0300 Subject: Factor out tryToDecodeLogOrNoOp --- src/0x.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/0x.ts b/src/0x.ts index ae29b8d70..275689f30 100644 --- a/src/0x.ts +++ b/src/0x.ts @@ -302,17 +302,7 @@ export class ZeroEx { const transactionReceipt = await this._web3Wrapper.getTransactionReceiptAsync(txHash); if (!_.isNull(transactionReceipt)) { intervalUtils.clearAsyncExcludingInterval(intervalId); - const logsWithDecodedArgs = _.map(transactionReceipt.logs, (log: Web3.LogEntry) => { - const decodedLog = this._abiDecoder.decodeLog(log); - if (_.isUndefined(decodedLog)) { - return log; - } - const logWithDecodedArgs: LogWithDecodedArgs = { - ...log, - ...decodedLog, - }; - return logWithDecodedArgs; - }); + const logsWithDecodedArgs = _.map(transactionReceipt.logs, this.tryToDecodeLogOrNoOp.bind(this)); const transactionReceiptWithDecodedLogArgs: TransactionReceiptWithDecodedLogs = { ...transactionReceipt, logs: logsWithDecodedArgs, @@ -332,6 +322,17 @@ export class ZeroEx { const logs = await this._web3Wrapper.getLogsAsync(filter); return logs; } + private tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|Web3.LogEntry { + const decodedLog = this._abiDecoder.decodeLog(log); + if (_.isUndefined(decodedLog)) { + return log; + } + const logWithDecodedArgs: LogWithDecodedArgs = { + ...log, + ...decodedLog, + }; + return logWithDecodedArgs; + } /* * HACK: `TokenWrapper` needs a token transfer proxy address. `TokenTransferProxy` address is fetched from * an `ExchangeWrapper`. `ExchangeWrapper` needs `TokenWrapper` to validate orders, creating a dependency cycle. -- cgit v1.2.3 From 6bbdc98ba29633828f0533c8bb40a200cf142436 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 12:31:46 +0300 Subject: Move log decoding to AbiDecoder --- src/0x.ts | 23 ++--------------- src/utils/abi_decoder.ts | 67 +++++++++++++++++++++++++----------------------- 2 files changed, 37 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/0x.ts b/src/0x.ts index 275689f30..d89c07aa6 100644 --- a/src/0x.ts +++ b/src/0x.ts @@ -302,7 +302,8 @@ export class ZeroEx { const transactionReceipt = await this._web3Wrapper.getTransactionReceiptAsync(txHash); if (!_.isNull(transactionReceipt)) { intervalUtils.clearAsyncExcludingInterval(intervalId); - const logsWithDecodedArgs = _.map(transactionReceipt.logs, this.tryToDecodeLogOrNoOp.bind(this)); + const tryToDecodeLogOrNoOp = this._abiDecoder.tryToDecodeLogOrNoOp.bind(this._abiDecoder); + const logsWithDecodedArgs = _.map(transactionReceipt.logs, tryToDecodeLogOrNoOp); const transactionReceiptWithDecodedLogArgs: TransactionReceiptWithDecodedLogs = { ...transactionReceipt, logs: logsWithDecodedArgs, @@ -313,26 +314,6 @@ export class ZeroEx { }); return txReceiptPromise; } - /** - * Gets historical logs without creating a subscription - * @param filter Filter object - * @return Array of logs that match the filter - */ - public async getLogsAsync(filter: FilterObject): Promise { - const logs = await this._web3Wrapper.getLogsAsync(filter); - return logs; - } - private tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|Web3.LogEntry { - const decodedLog = this._abiDecoder.decodeLog(log); - if (_.isUndefined(decodedLog)) { - return log; - } - const logWithDecodedArgs: LogWithDecodedArgs = { - ...log, - ...decodedLog, - }; - return logWithDecodedArgs; - } /* * HACK: `TokenWrapper` needs a token transfer proxy address. `TokenTransferProxy` address is fetched from * an `ExchangeWrapper`. `ExchangeWrapper` needs `TokenWrapper` to validate orders, creating a dependency cycle. diff --git a/src/utils/abi_decoder.ts b/src/utils/abi_decoder.ts index 61c8eecd4..88053aade 100644 --- a/src/utils/abi_decoder.ts +++ b/src/utils/abi_decoder.ts @@ -1,7 +1,7 @@ import * as Web3 from 'web3'; import * as _ from 'lodash'; import * as BigNumber from 'bignumber.js'; -import {AbiType, DecodedLogArgs, DecodedArgs} from '../types'; +import {AbiType, DecodedLogArgs, DecodedArgs, LogWithDecodedArgs} from '../types'; import * as SolidityCoder from 'web3/lib/solidity/coder'; export class AbiDecoder { @@ -10,40 +10,43 @@ export class AbiDecoder { constructor(abiArrays: Web3.AbiDefinition[][]) { _.map(abiArrays, this.addABI.bind(this)); } - public decodeLog(logItem: Web3.LogEntry): DecodedArgs|undefined { - const methodId = logItem.topics[0]; + public tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|Web3.LogEntry { + const methodId = log.topics[0]; const event = this.methodIds[methodId]; - if (!_.isUndefined(event)) { - const logData = logItem.data; - const decodedParams: DecodedLogArgs = {}; - let dataIndex = 0; - let topicsIndex = 1; + if (_.isUndefined(event)) { + return log; + } + const logData = log.data; + const decodedParams: DecodedLogArgs = {}; + let dataIndex = 0; + let topicsIndex = 1; - const nonIndexedInputs = _.filter(event.inputs, input => !input.indexed); - const dataTypes = _.map(nonIndexedInputs, input => input.type); - const decodedData = SolidityCoder.decodeParams(dataTypes, logData.slice(2)); - _.map(event.inputs, (param: Web3.EventParameter) => { - let value; - if (param.indexed) { - value = logItem.topics[topicsIndex]; - topicsIndex++; - } else { - value = decodedData[dataIndex]; - dataIndex++; - } - if (param.type === 'address') { - value = this.padZeros(new BigNumber(value).toString(16)); - } else if (param.type === 'uint256' || param.type === 'uint8' || param.type === 'int' ) { - value = new BigNumber(value); - } - decodedParams[param.name] = value; - }); + const nonIndexedInputs = _.filter(event.inputs, input => !input.indexed); + const dataTypes = _.map(nonIndexedInputs, input => input.type); + const decodedData = SolidityCoder.decodeParams(dataTypes, logData.slice(2)); - return { - event: event.name, - args: decodedParams, - }; - } + _.map(event.inputs, (param: Web3.EventParameter) => { + let value; + if (param.indexed) { + value = log.topics[topicsIndex]; + topicsIndex++; + } else { + value = decodedData[dataIndex]; + dataIndex++; + } + if (param.type === 'address') { + value = this.padZeros(new BigNumber(value).toString(16)); + } else if (param.type === 'uint256' || param.type === 'uint8' || param.type === 'int' ) { + value = new BigNumber(value); + } + decodedParams[param.name] = value; + }); + + return { + ...log, + event: event.name, + args: decodedParams, + }; } private addABI(abiArray: Web3.AbiDefinition[]): void { _.map(abiArray, (abi: Web3.AbiDefinition) => { -- cgit v1.2.3 From 671bc7c91731828a4ee484994dacf7d3beb800e3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 15:49:37 +0300 Subject: Add NO_ABI_DECODER and ContractEvents --- src/types.ts | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/types.ts b/src/types.ts index d9059e7be..0567b5e6a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -15,6 +15,7 @@ export enum ZeroExError { InvalidJump = 'INVALID_JUMP', OutOfGas = 'OUT_OF_GAS', NoNetworkId = 'NO_NETWORK_ID', + NoAbiDecoder = 'NO_ABI_DECODER', } /** @@ -340,6 +341,8 @@ export enum TokenEvents { Approval = 'Approval', } +export type ContractEvents = TokenEvents|ExchangeEvents; + export interface IndexedFilterValues { [index: string]: ContractEventArg; } -- cgit v1.2.3 From 44abf283ec80cbb33f0b6aad12cd1a7dc657debd Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 15:50:25 +0300 Subject: Add keccak256 on web3_wrapper --- src/web3_wrapper.ts | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/web3_wrapper.ts b/src/web3_wrapper.ts index 653205988..7576f3d40 100644 --- a/src/web3_wrapper.ts +++ b/src/web3_wrapper.ts @@ -112,6 +112,10 @@ export class Web3Wrapper { const logs = await this.sendRawPayloadAsync(payload); return logs; } + public keccak256(data: string): string { + const hash = this.web3.sha3(data); + return hash; + } private getContractInstance(abi: Web3.ContractAbi, address: string): A { const web3ContractInstance = this.web3.eth.contract(abi).at(address); const contractInstance = new Contract(web3ContractInstance, this.defaults) as any as A; -- cgit v1.2.3 From db08896274699aaf967751927dcacd0c21e3aaaf Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 15:51:09 +0300 Subject: Remove old tests --- src/0x.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/0x.ts b/src/0x.ts index d89c07aa6..c187fc5c2 100644 --- a/src/0x.ts +++ b/src/0x.ts @@ -202,6 +202,7 @@ export class ZeroEx { this._web3Wrapper = new Web3Wrapper(provider, defaults); this.token = new TokenWrapper( this._web3Wrapper, + this._abiDecoder, this._getTokenTransferProxyAddressAsync.bind(this), ); const exchageContractAddressIfExists = _.isUndefined(config) ? undefined : config.exchangeContractAddress; -- cgit v1.2.3 From efa85f844bcf59aa63d940a89d5899462239878a Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 15:51:52 +0300 Subject: Add tryToDecodeLogOrNoOp and _getEventSignatureFromAbiByName on contract_wrapper --- src/contract_wrappers/contract_wrapper.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index 2a55b53d9..bc65f692d 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -1,13 +1,23 @@ import * as _ from 'lodash'; import * as Web3 from 'web3'; import {Web3Wrapper} from '../web3_wrapper'; -import {ZeroExError, Artifact} from '../types'; +import {AbiDecoder} from '../utils/abi_decoder'; +import {ZeroExError, Artifact, LogWithDecodedArgs, RawLog, ContractEvents} from '../types'; import {utils} from '../utils/utils'; export class ContractWrapper { protected _web3Wrapper: Web3Wrapper; - constructor(web3Wrapper: Web3Wrapper) { + private _abiDecoder?: AbiDecoder; + constructor(web3Wrapper: Web3Wrapper, abiDecoder?: AbiDecoder) { this._web3Wrapper = web3Wrapper; + this._abiDecoder = abiDecoder; + } + protected tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|RawLog { + if (_.isUndefined(this._abiDecoder)) { + throw new Error(ZeroExError.NoAbiDecoder); + } + const logWithDecodedArgs = this._abiDecoder.tryToDecodeLogOrNoOp(log); + return logWithDecodedArgs; } protected async _instantiateContractIfExistsAsync(artifact: Artifact, addressIfExists?: string, @@ -16,4 +26,10 @@ export class ContractWrapper { await this._web3Wrapper.getContractInstanceFromArtifactAsync(artifact, addressIfExists); return contractInstance; } + protected _getEventSignatureFromAbiByName(abi: Web3.ContractAbi, eventName: ContractEvents): string { + const eventAbi = _.filter(abi, {name: eventName})[0] as Web3.EventAbi; + const types = _.map(eventAbi.inputs, 'type'); + const signature = `${eventAbi.name}(${types.join(',')})`; + return signature; + } } -- cgit v1.2.3 From 87374d7f46b6365078d20e8e0660520080facebe Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 15:52:28 +0300 Subject: Refactor abi decoder --- src/utils/abi_decoder.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/utils/abi_decoder.ts b/src/utils/abi_decoder.ts index 88053aade..2b420bd1f 100644 --- a/src/utils/abi_decoder.ts +++ b/src/utils/abi_decoder.ts @@ -1,7 +1,7 @@ import * as Web3 from 'web3'; import * as _ from 'lodash'; import * as BigNumber from 'bignumber.js'; -import {AbiType, DecodedLogArgs, DecodedArgs, LogWithDecodedArgs} from '../types'; +import {AbiType, DecodedLogArgs, DecodedArgs, LogWithDecodedArgs, RawLog} from '../types'; import * as SolidityCoder from 'web3/lib/solidity/coder'; export class AbiDecoder { @@ -10,7 +10,7 @@ export class AbiDecoder { constructor(abiArrays: Web3.AbiDefinition[][]) { _.map(abiArrays, this.addABI.bind(this)); } - public tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|Web3.LogEntry { + public tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|RawLog { const methodId = log.topics[0]; const event = this.methodIds[methodId]; if (_.isUndefined(event)) { -- cgit v1.2.3 From 0a12fa7f4e83562d48e143c30cb59645aa6b9b7a Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 15:53:23 +0300 Subject: Implement getLogsAsync on token contract --- src/contract_wrappers/contract_wrapper.ts | 2 +- src/contract_wrappers/token_wrapper.ts | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index bc65f692d..0c8864ee1 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -12,7 +12,7 @@ export class ContractWrapper { this._web3Wrapper = web3Wrapper; this._abiDecoder = abiDecoder; } - protected tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|RawLog { + protected _tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|RawLog { if (_.isUndefined(this._abiDecoder)) { throw new Error(ZeroExError.NoAbiDecoder); } diff --git a/src/contract_wrappers/token_wrapper.ts b/src/contract_wrappers/token_wrapper.ts index f7f0a0ce3..04c03edbd 100644 --- a/src/contract_wrappers/token_wrapper.ts +++ b/src/contract_wrappers/token_wrapper.ts @@ -7,6 +7,7 @@ import {utils} from '../utils/utils'; import {eventUtils} from '../utils/event_utils'; import {constants} from '../utils/constants'; import {ContractWrapper} from './contract_wrapper'; +import {AbiDecoder} from '../utils/abi_decoder'; import {artifacts} from '../artifacts'; import { TokenContract, @@ -18,6 +19,8 @@ import { ContractEventEmitter, ContractEventObj, MethodOpts, + LogWithDecodedArgs, + RawLog, } from '../types'; const ALLOWANCE_TO_ZERO_GAS_AMOUNT = 47155; @@ -32,8 +35,9 @@ export class TokenWrapper extends ContractWrapper { private _tokenContractsByAddress: {[address: string]: TokenContract}; private _tokenLogEventEmitters: ContractEventEmitter[]; private _tokenTransferProxyContractAddressFetcher: () => Promise; - constructor(web3Wrapper: Web3Wrapper, tokenTransferProxyContractAddressFetcher: () => Promise) { - super(web3Wrapper); + constructor(web3Wrapper: Web3Wrapper, abiDecoder: AbiDecoder, + tokenTransferProxyContractAddressFetcher: () => Promise) { + super(web3Wrapper, abiDecoder); this._tokenContractsByAddress = {}; this._tokenLogEventEmitters = []; this._tokenTransferProxyContractAddressFetcher = tokenTransferProxyContractAddressFetcher; @@ -276,6 +280,21 @@ export class TokenWrapper extends ContractWrapper { this._tokenLogEventEmitters.push(eventEmitter); return eventEmitter; } + public async getLogsAsync(tokenAddress: string, eventName: TokenEvents, + subscriptionOpts: SubscriptionOpts, + indexFilterValues: IndexedFilterValues): Promise> { + // TODO include indexFilterValues in topics + const eventSignature = this._getEventSignatureFromAbiByName(artifacts.TokenArtifact.abi, eventName); + const filter = { + fromBlock: subscriptionOpts.fromBlock, + toBlock: subscriptionOpts.toBlock, + address: tokenAddress, + topics: [this._web3Wrapper.keccak256(eventSignature)], + }; + const logs = await this._web3Wrapper.getLogsAsync(filter); + const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoOp.bind(this)); + return logsWithDecodedArguments; + } /** * Stops watching for all token events */ -- cgit v1.2.3 From e6c138be5ab56856a454f7f04b6e1e54f1d41f18 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 16:37:09 +0300 Subject: Add _getLogsAsync on contract_wrapper --- src/contract_wrappers/contract_wrapper.ts | 25 ++++++++++++++++++++++++- src/contract_wrappers/token_wrapper.ts | 18 +++++------------- 2 files changed, 29 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index 0c8864ee1..6b2517fc9 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -2,7 +2,15 @@ import * as _ from 'lodash'; import * as Web3 from 'web3'; import {Web3Wrapper} from '../web3_wrapper'; import {AbiDecoder} from '../utils/abi_decoder'; -import {ZeroExError, Artifact, LogWithDecodedArgs, RawLog, ContractEvents} from '../types'; +import { + ZeroExError, + Artifact, + LogWithDecodedArgs, + RawLog, + ContractEvents, + SubscriptionOpts, + IndexedFilterValues, +} from '../types'; import {utils} from '../utils/utils'; export class ContractWrapper { @@ -12,6 +20,21 @@ export class ContractWrapper { this._web3Wrapper = web3Wrapper; this._abiDecoder = abiDecoder; } + protected async _getLogsAsync(address: string, eventName: ContractEvents, subscriptionOpts: SubscriptionOpts, + indexFilterValues: IndexedFilterValues, + abi: Web3.ContractAbi): Promise> { + // TODO include indexFilterValues in topics + const eventSignature = this._getEventSignatureFromAbiByName(abi, eventName); + const filter = { + fromBlock: subscriptionOpts.fromBlock, + toBlock: subscriptionOpts.toBlock, + address, + topics: [this._web3Wrapper.keccak256(eventSignature)], + }; + const logs = await this._web3Wrapper.getLogsAsync(filter); + const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoOp.bind(this)); + return logsWithDecodedArguments; + } protected _tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|RawLog { if (_.isUndefined(this._abiDecoder)) { throw new Error(ZeroExError.NoAbiDecoder); diff --git a/src/contract_wrappers/token_wrapper.ts b/src/contract_wrappers/token_wrapper.ts index 04c03edbd..b932686d4 100644 --- a/src/contract_wrappers/token_wrapper.ts +++ b/src/contract_wrappers/token_wrapper.ts @@ -280,20 +280,12 @@ export class TokenWrapper extends ContractWrapper { this._tokenLogEventEmitters.push(eventEmitter); return eventEmitter; } - public async getLogsAsync(tokenAddress: string, eventName: TokenEvents, - subscriptionOpts: SubscriptionOpts, + public async getLogsAsync(tokenAddress: string, eventName: TokenEvents, subscriptionOpts: SubscriptionOpts, indexFilterValues: IndexedFilterValues): Promise> { - // TODO include indexFilterValues in topics - const eventSignature = this._getEventSignatureFromAbiByName(artifacts.TokenArtifact.abi, eventName); - const filter = { - fromBlock: subscriptionOpts.fromBlock, - toBlock: subscriptionOpts.toBlock, - address: tokenAddress, - topics: [this._web3Wrapper.keccak256(eventSignature)], - }; - const logs = await this._web3Wrapper.getLogsAsync(filter); - const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoOp.bind(this)); - return logsWithDecodedArguments; + const logs = await this._getLogsAsync( + tokenAddress, eventName, subscriptionOpts, indexFilterValues, artifacts.TokenArtifact.abi, + ); + return logs; } /** * Stops watching for all token events -- cgit v1.2.3 From 837618c7a016b9b66d70f3c0e9682c97a9d4cf8a Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 16:44:16 +0300 Subject: Implement zeroEx.exchange.getLogsAsync --- src/contract_wrappers/exchange_wrapper.ts | 17 +++++++++++++++++ src/contract_wrappers/token_wrapper.ts | 9 +++++++++ 2 files changed, 26 insertions(+) (limited to 'src') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index d02a6e642..78c2f4173 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -30,6 +30,7 @@ import { MethodOpts, ValidateOrderFillableOpts, OrderTransactionOpts, + RawLog, } from '../types'; import {assert} from '../utils/assert'; import {utils} from '../utils/utils'; @@ -655,6 +656,22 @@ export class ExchangeWrapper extends ContractWrapper { this._exchangeLogEventEmitters.push(eventEmitter); return eventEmitter; } + /** + * Gets historical logs without creating a subscription + * @param eventName The exchange contract event you would like to subscribe to. + * @param subscriptionOpts Subscriptions options that let you configure the subscription. + * @param indexFilterValues An object where the keys are indexed args returned by the event and + * the value is the value you are interested in. E.g `{_from: aUserAddressHex}` + * @return Array of logs that match the parameters + */ + public async getLogsAsync(eventName: ExchangeEvents, subscriptionOpts: SubscriptionOpts, + indexFilterValues: IndexedFilterValues): Promise> { + const exchangeContractAddress = await this.getContractAddressAsync(); + const logs = await this._getLogsAsync( + exchangeContractAddress, eventName, subscriptionOpts, indexFilterValues, artifacts.ExchangeArtifact.abi, + ); + return logs; + } /** * Stops watching for all exchange events */ diff --git a/src/contract_wrappers/token_wrapper.ts b/src/contract_wrappers/token_wrapper.ts index b932686d4..175671f74 100644 --- a/src/contract_wrappers/token_wrapper.ts +++ b/src/contract_wrappers/token_wrapper.ts @@ -280,6 +280,15 @@ export class TokenWrapper extends ContractWrapper { this._tokenLogEventEmitters.push(eventEmitter); return eventEmitter; } + /** + * Gets historical logs without creating a subscription + * @param tokenAddress An address of the token that emited the logs. + * @param eventName The token contract event you would like to subscribe to. + * @param subscriptionOpts Subscriptions options that let you configure the subscription. + * @param indexFilterValues An object where the keys are indexed args returned by the event and + * the value is the value you are interested in. E.g `{_from: aUserAddressHex}` + * @return Array of logs that match the parameters + */ public async getLogsAsync(tokenAddress: string, eventName: TokenEvents, subscriptionOpts: SubscriptionOpts, indexFilterValues: IndexedFilterValues): Promise> { const logs = await this._getLogsAsync( -- cgit v1.2.3 From 451ded4963aaaa40ff4d00bcb0d589b06b45ce24 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 19:05:44 +0300 Subject: Add tests for zeroEx.exchange.getLogsAsync --- src/0x.ts | 6 +++++- src/contract_wrappers/contract_wrapper.ts | 2 +- src/contract_wrappers/exchange_wrapper.ts | 8 +++++--- src/contract_wrappers/token_wrapper.ts | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/0x.ts b/src/0x.ts index c187fc5c2..c5e8e0066 100644 --- a/src/0x.ts +++ b/src/0x.ts @@ -206,7 +206,11 @@ export class ZeroEx { this._getTokenTransferProxyAddressAsync.bind(this), ); const exchageContractAddressIfExists = _.isUndefined(config) ? undefined : config.exchangeContractAddress; - this.exchange = new ExchangeWrapper(this._web3Wrapper, this.token, exchageContractAddressIfExists); + this.exchange = new ExchangeWrapper( + this._web3Wrapper, + this._abiDecoder, + this.token, + exchageContractAddressIfExists); this.proxy = new TokenTransferProxyWrapper( this._web3Wrapper, this._getTokenTransferProxyAddressAsync.bind(this), diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index 6b2517fc9..d6c7d915a 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -22,7 +22,7 @@ export class ContractWrapper { } protected async _getLogsAsync(address: string, eventName: ContractEvents, subscriptionOpts: SubscriptionOpts, indexFilterValues: IndexedFilterValues, - abi: Web3.ContractAbi): Promise> { + abi: Web3.ContractAbi): Promise { // TODO include indexFilterValues in topics const eventSignature = this._getEventSignatureFromAbiByName(abi, eventName); const filter = { diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 78c2f4173..b3a35d5bf 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -40,6 +40,7 @@ import {ContractWrapper} from './contract_wrapper'; import {constants} from '../utils/constants'; import {TokenWrapper} from './token_wrapper'; import {decorators} from '../utils/decorators'; +import {AbiDecoder} from '../utils/abi_decoder'; import {artifacts} from '../artifacts'; const SHOULD_VALIDATE_BY_DEFAULT = true; @@ -80,8 +81,9 @@ export class ExchangeWrapper extends ContractWrapper { ]; return [orderAddresses, orderValues]; } - constructor(web3Wrapper: Web3Wrapper, tokenWrapper: TokenWrapper, contractAddressIfExists?: string) { - super(web3Wrapper); + constructor(web3Wrapper: Web3Wrapper, abiDecoder: AbiDecoder, + tokenWrapper: TokenWrapper, contractAddressIfExists?: string) { + super(web3Wrapper, abiDecoder); this._tokenWrapper = tokenWrapper; this._orderValidationUtils = new OrderValidationUtils(tokenWrapper, this); this._exchangeLogEventEmitters = []; @@ -665,7 +667,7 @@ export class ExchangeWrapper extends ContractWrapper { * @return Array of logs that match the parameters */ public async getLogsAsync(eventName: ExchangeEvents, subscriptionOpts: SubscriptionOpts, - indexFilterValues: IndexedFilterValues): Promise> { + indexFilterValues: IndexedFilterValues): Promise { const exchangeContractAddress = await this.getContractAddressAsync(); const logs = await this._getLogsAsync( exchangeContractAddress, eventName, subscriptionOpts, indexFilterValues, artifacts.ExchangeArtifact.abi, diff --git a/src/contract_wrappers/token_wrapper.ts b/src/contract_wrappers/token_wrapper.ts index 175671f74..95f5491c9 100644 --- a/src/contract_wrappers/token_wrapper.ts +++ b/src/contract_wrappers/token_wrapper.ts @@ -290,7 +290,7 @@ export class TokenWrapper extends ContractWrapper { * @return Array of logs that match the parameters */ public async getLogsAsync(tokenAddress: string, eventName: TokenEvents, subscriptionOpts: SubscriptionOpts, - indexFilterValues: IndexedFilterValues): Promise> { + indexFilterValues: IndexedFilterValues): Promise { const logs = await this._getLogsAsync( tokenAddress, eventName, subscriptionOpts, indexFilterValues, artifacts.TokenArtifact.abi, ); -- cgit v1.2.3 From 7c49224c7b9ce41cf0eb0026f2b5d73e8726b089 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 3 Oct 2017 19:14:03 +0300 Subject: Don't export RawLog --- src/index.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/index.ts b/src/index.ts index 8e81d83a7..3359743e9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -36,5 +36,4 @@ export { MethodOpts, OrderTransactionOpts, FilterObject, - RawLog, } from './types'; -- cgit v1.2.3 From f26d49f077a9a8b606159f22c05aaf2601dc8f57 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 11:47:48 +0300 Subject: Use Noop instead of NoOp --- src/0x.ts | 6 ++++-- src/utils/abi_decoder.ts | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/0x.ts b/src/0x.ts index c5e8e0066..ba68a6e1e 100644 --- a/src/0x.ts +++ b/src/0x.ts @@ -307,8 +307,10 @@ export class ZeroEx { const transactionReceipt = await this._web3Wrapper.getTransactionReceiptAsync(txHash); if (!_.isNull(transactionReceipt)) { intervalUtils.clearAsyncExcludingInterval(intervalId); - const tryToDecodeLogOrNoOp = this._abiDecoder.tryToDecodeLogOrNoOp.bind(this._abiDecoder); - const logsWithDecodedArgs = _.map(transactionReceipt.logs, tryToDecodeLogOrNoOp); + const logsWithDecodedArgs = _.map( + transactionReceipt.logs, + this._abiDecoder.tryToDecodeLogOrNoop.bind(this._abiDecoder), + ); const transactionReceiptWithDecodedLogArgs: TransactionReceiptWithDecodedLogs = { ...transactionReceipt, logs: logsWithDecodedArgs, diff --git a/src/utils/abi_decoder.ts b/src/utils/abi_decoder.ts index 2b420bd1f..75d78629c 100644 --- a/src/utils/abi_decoder.ts +++ b/src/utils/abi_decoder.ts @@ -10,7 +10,7 @@ export class AbiDecoder { constructor(abiArrays: Web3.AbiDefinition[][]) { _.map(abiArrays, this.addABI.bind(this)); } - public tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|RawLog { + public tryToDecodeLogOrNoop(log: Web3.LogEntry): LogWithDecodedArgs|RawLog { const methodId = log.topics[0]; const event = this.methodIds[methodId]; if (_.isUndefined(event)) { -- cgit v1.2.3 From f65bfc1ab1425e4866b5b7b7ecf2a30e0eb018a7 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 11:51:36 +0300 Subject: Extract topics to its variable --- src/contract_wrappers/contract_wrapper.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index d6c7d915a..921b5a6c2 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -24,22 +24,25 @@ export class ContractWrapper { indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi): Promise { // TODO include indexFilterValues in topics - const eventSignature = this._getEventSignatureFromAbiByName(abi, eventName); + const eventAbi = _.filter(abi, {name: eventName})[0] as Web3.EventAbi; + const eventSignature = this._getEventSignatureFromAbiByName(eventAbi, eventName); + const topicForEventSignature = this._web3Wrapper.keccak256(eventSignature); + const topics = [topicForEventSignature]; const filter = { fromBlock: subscriptionOpts.fromBlock, toBlock: subscriptionOpts.toBlock, address, - topics: [this._web3Wrapper.keccak256(eventSignature)], + topics, }; const logs = await this._web3Wrapper.getLogsAsync(filter); - const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoOp.bind(this)); + const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoop.bind(this)); return logsWithDecodedArguments; } - protected _tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|RawLog { + protected _tryToDecodeLogOrNoop(log: Web3.LogEntry): LogWithDecodedArgs|RawLog { if (_.isUndefined(this._abiDecoder)) { throw new Error(ZeroExError.NoAbiDecoder); } - const logWithDecodedArgs = this._abiDecoder.tryToDecodeLogOrNoOp(log); + const logWithDecodedArgs = this._abiDecoder.tryToDecodeLogOrNoop(log); return logWithDecodedArgs; } protected async _instantiateContractIfExistsAsync(artifact: Artifact, @@ -49,8 +52,7 @@ export class ContractWrapper { await this._web3Wrapper.getContractInstanceFromArtifactAsync(artifact, addressIfExists); return contractInstance; } - protected _getEventSignatureFromAbiByName(abi: Web3.ContractAbi, eventName: ContractEvents): string { - const eventAbi = _.filter(abi, {name: eventName})[0] as Web3.EventAbi; + protected _getEventSignatureFromAbiByName(eventAbi: Web3.EventAbi, eventName: ContractEvents): string { const types = _.map(eventAbi.inputs, 'type'); const signature = `${eventAbi.name}(${types.join(',')})`; return signature; -- cgit v1.2.3 From d1e4f6efdd14dc3b7c73b1d95f360cedaf4df03b Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 11:53:02 +0300 Subject: Move NoAbiDecoder to InternalZeroExErrors --- src/contract_wrappers/contract_wrapper.ts | 4 ++-- src/types.ts | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index 921b5a6c2..cffd2f6f3 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -3,7 +3,7 @@ import * as Web3 from 'web3'; import {Web3Wrapper} from '../web3_wrapper'; import {AbiDecoder} from '../utils/abi_decoder'; import { - ZeroExError, + InternalZeroExError, Artifact, LogWithDecodedArgs, RawLog, @@ -40,7 +40,7 @@ export class ContractWrapper { } protected _tryToDecodeLogOrNoop(log: Web3.LogEntry): LogWithDecodedArgs|RawLog { if (_.isUndefined(this._abiDecoder)) { - throw new Error(ZeroExError.NoAbiDecoder); + throw new Error(InternalZeroExError.NoAbiDecoder); } const logWithDecodedArgs = this._abiDecoder.tryToDecodeLogOrNoop(log); return logWithDecodedArgs; diff --git a/src/types.ts b/src/types.ts index 0567b5e6a..a6a24ef8e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -15,6 +15,9 @@ export enum ZeroExError { InvalidJump = 'INVALID_JUMP', OutOfGas = 'OUT_OF_GAS', NoNetworkId = 'NO_NETWORK_ID', +} + +export enum InternalZeroExError { NoAbiDecoder = 'NO_ABI_DECODER', } -- cgit v1.2.3 From aa995ff9941c4f319985e23a14d0a87fc7b9ea1c Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 11:53:44 +0300 Subject: Use _.find instead of _.filter --- src/contract_wrappers/contract_wrapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index cffd2f6f3..6f074a976 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -24,7 +24,7 @@ export class ContractWrapper { indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi): Promise { // TODO include indexFilterValues in topics - const eventAbi = _.filter(abi, {name: eventName})[0] as Web3.EventAbi; + const eventAbi = _.find(abi, {name: eventName}) as Web3.EventAbi; const eventSignature = this._getEventSignatureFromAbiByName(eventAbi, eventName); const topicForEventSignature = this._web3Wrapper.keccak256(eventSignature); const topics = [topicForEventSignature]; -- cgit v1.2.3 From 2b9418b7009a54c5943dd42b34db8f82ddf50e99 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 11:54:34 +0300 Subject: Fix a typo --- src/contract_wrappers/token_wrapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/contract_wrappers/token_wrapper.ts b/src/contract_wrappers/token_wrapper.ts index 95f5491c9..91af223e4 100644 --- a/src/contract_wrappers/token_wrapper.ts +++ b/src/contract_wrappers/token_wrapper.ts @@ -282,7 +282,7 @@ export class TokenWrapper extends ContractWrapper { } /** * Gets historical logs without creating a subscription - * @param tokenAddress An address of the token that emited the logs. + * @param tokenAddress An address of the token that emmited the logs. * @param eventName The token contract event you would like to subscribe to. * @param subscriptionOpts Subscriptions options that let you configure the subscription. * @param indexFilterValues An object where the keys are indexed args returned by the event and -- cgit v1.2.3 From a6f4f83b5b0440a3f63112514c6abe6be74df3f9 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 11:55:29 +0300 Subject: Add a comment --- src/utils/abi_decoder.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/utils/abi_decoder.ts b/src/utils/abi_decoder.ts index 75d78629c..b601dd2f4 100644 --- a/src/utils/abi_decoder.ts +++ b/src/utils/abi_decoder.ts @@ -10,6 +10,7 @@ export class AbiDecoder { constructor(abiArrays: Web3.AbiDefinition[][]) { _.map(abiArrays, this.addABI.bind(this)); } + // This method can only decode logs from the 0x smart contracts public tryToDecodeLogOrNoop(log: Web3.LogEntry): LogWithDecodedArgs|RawLog { const methodId = log.topics[0]; const event = this.methodIds[methodId]; -- cgit v1.2.3 From 499e60c4a3719ce0699f75f1993a5336d0074bc7 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 12:48:45 +0300 Subject: Use 0x.length instead of 2 --- src/utils/abi_decoder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/utils/abi_decoder.ts b/src/utils/abi_decoder.ts index b601dd2f4..4646016f2 100644 --- a/src/utils/abi_decoder.ts +++ b/src/utils/abi_decoder.ts @@ -24,7 +24,7 @@ export class AbiDecoder { const nonIndexedInputs = _.filter(event.inputs, input => !input.indexed); const dataTypes = _.map(nonIndexedInputs, input => input.type); - const decodedData = SolidityCoder.decodeParams(dataTypes, logData.slice(2)); + const decodedData = SolidityCoder.decodeParams(dataTypes, logData.slice('0x'.length)); _.map(event.inputs, (param: Web3.EventParameter) => { let value; -- cgit v1.2.3 From 944f51d66c5afb92008ddd1bff9fe83ce51a5e10 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 12:55:16 +0300 Subject: Use SolidityTypes --- src/types.ts | 2 ++ src/utils/abi_decoder.ts | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/types.ts b/src/types.ts index a6a24ef8e..92b873886 100644 --- a/src/types.ts +++ b/src/types.ts @@ -202,6 +202,8 @@ export interface TokenTransferProxyContract extends Web3.ContractInstance { export enum SolidityTypes { Address = 'address', Uint256 = 'uint256', + Uint8 = 'uint8', + Uint = 'uint', } export enum ExchangeContractErrCodes { diff --git a/src/utils/abi_decoder.ts b/src/utils/abi_decoder.ts index 4646016f2..e9ba3bc5a 100644 --- a/src/utils/abi_decoder.ts +++ b/src/utils/abi_decoder.ts @@ -1,7 +1,7 @@ import * as Web3 from 'web3'; import * as _ from 'lodash'; import * as BigNumber from 'bignumber.js'; -import {AbiType, DecodedLogArgs, DecodedArgs, LogWithDecodedArgs, RawLog} from '../types'; +import {AbiType, DecodedLogArgs, DecodedArgs, LogWithDecodedArgs, RawLog, SolidityTypes} from '../types'; import * as SolidityCoder from 'web3/lib/solidity/coder'; export class AbiDecoder { @@ -35,9 +35,11 @@ export class AbiDecoder { value = decodedData[dataIndex]; dataIndex++; } - if (param.type === 'address') { + if (param.type === SolidityTypes.Address) { value = this.padZeros(new BigNumber(value).toString(16)); - } else if (param.type === 'uint256' || param.type === 'uint8' || param.type === 'int' ) { + } else if (param.type === SolidityTypes.Uint256 || + param.type === SolidityTypes.Uint8 || + param.type === SolidityTypes.Uint ) { value = new BigNumber(value); } decodedParams[param.name] = value; -- cgit v1.2.3 From 9af47eb063406753456f16bf3efb916666c76d7f Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 12:59:46 +0300 Subject: Use a ternary and add a comment --- src/utils/abi_decoder.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/utils/abi_decoder.ts b/src/utils/abi_decoder.ts index e9ba3bc5a..542591251 100644 --- a/src/utils/abi_decoder.ts +++ b/src/utils/abi_decoder.ts @@ -27,14 +27,8 @@ export class AbiDecoder { const decodedData = SolidityCoder.decodeParams(dataTypes, logData.slice('0x'.length)); _.map(event.inputs, (param: Web3.EventParameter) => { - let value; - if (param.indexed) { - value = log.topics[topicsIndex]; - topicsIndex++; - } else { - value = decodedData[dataIndex]; - dataIndex++; - } + // Indexed parameters are stored in topics. Non-indexed ones in decodedData + let value = param.indexed ? log.topics[topicsIndex++] : decodedData[dataIndex++]; if (param.type === SolidityTypes.Address) { value = this.padZeros(new BigNumber(value).toString(16)); } else if (param.type === SolidityTypes.Uint256 || -- cgit v1.2.3 From 504beeb2f321c6c35cfcc3edfff1669bdebc939b Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 13:30:00 +0300 Subject: Add filtering by topic --- src/contract_wrappers/contract_wrapper.ts | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index 6f074a976..7732f2f50 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -1,5 +1,6 @@ import * as _ from 'lodash'; import * as Web3 from 'web3'; +import * as ethUtil from 'ethereumjs-util'; import {Web3Wrapper} from '../web3_wrapper'; import {AbiDecoder} from '../utils/abi_decoder'; import { @@ -13,6 +14,8 @@ import { } from '../types'; import {utils} from '../utils/utils'; +const TOPIC_LENGTH = 32; + export class ContractWrapper { protected _web3Wrapper: Web3Wrapper; private _abiDecoder?: AbiDecoder; @@ -23,11 +26,11 @@ export class ContractWrapper { protected async _getLogsAsync(address: string, eventName: ContractEvents, subscriptionOpts: SubscriptionOpts, indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi): Promise { - // TODO include indexFilterValues in topics - const eventAbi = _.find(abi, {name: eventName}) as Web3.EventAbi; + const eventAbi = _.filter(abi, {name: eventName})[0] as Web3.EventAbi; const eventSignature = this._getEventSignatureFromAbiByName(eventAbi, eventName); const topicForEventSignature = this._web3Wrapper.keccak256(eventSignature); - const topics = [topicForEventSignature]; + const topicsForIndexedArgs = this._getTopicsForIndexedArgs(eventAbi, indexFilterValues); + const topics = [topicForEventSignature, ...topicsForIndexedArgs]; const filter = { fromBlock: subscriptionOpts.fromBlock, toBlock: subscriptionOpts.toBlock, @@ -57,4 +60,21 @@ export class ContractWrapper { const signature = `${eventAbi.name}(${types.join(',')})`; return signature; } + private _getTopicsForIndexedArgs(abi: Web3.EventAbi, indexFilterValues: IndexedFilterValues): Array { + const topics: Array = []; + for (const eventInput of abi.inputs) { + if (eventInput.indexed) { + if (_.isUndefined(indexFilterValues[eventInput.name])) { + topics.push(null); + } else { + const value = indexFilterValues[eventInput.name] as string; + const buffer = ethUtil.toBuffer(value); + const paddedBuffer = ethUtil.setLengthLeft(buffer, TOPIC_LENGTH); + const topic = ethUtil.bufferToHex(paddedBuffer); + topics.push(topic); + } + } + } + return topics; + } } -- cgit v1.2.3 From 8fb5e8724310d034659be6d00d287bb73ced1eae Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 14:22:17 +0300 Subject: Allign brackets --- src/0x.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/0x.ts b/src/0x.ts index ba68a6e1e..3180c52f6 100644 --- a/src/0x.ts +++ b/src/0x.ts @@ -210,7 +210,8 @@ export class ZeroEx { this._web3Wrapper, this._abiDecoder, this.token, - exchageContractAddressIfExists); + exchageContractAddressIfExists, + ); this.proxy = new TokenTransferProxyWrapper( this._web3Wrapper, this._getTokenTransferProxyAddressAsync.bind(this), -- cgit v1.2.3 From cc3871aca54a9c4dc0906e2b726c2c079787f142 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 14:22:47 +0300 Subject: Use find --- src/contract_wrappers/contract_wrapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index 7732f2f50..4d08f04e6 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -26,7 +26,7 @@ export class ContractWrapper { protected async _getLogsAsync(address: string, eventName: ContractEvents, subscriptionOpts: SubscriptionOpts, indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi): Promise { - const eventAbi = _.filter(abi, {name: eventName})[0] as Web3.EventAbi; + const eventAbi = _.find(abi, {name: eventName}) as Web3.EventAbi; const eventSignature = this._getEventSignatureFromAbiByName(eventAbi, eventName); const topicForEventSignature = this._web3Wrapper.keccak256(eventSignature); const topicsForIndexedArgs = this._getTopicsForIndexedArgs(eventAbi, indexFilterValues); -- cgit v1.2.3 From 11c48ced00ef4c25aeffd47504685f0a3bf3e7e3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 14:23:42 +0300 Subject: Reduce nesting --- src/contract_wrappers/contract_wrapper.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts index 4d08f04e6..743dfc9b2 100644 --- a/src/contract_wrappers/contract_wrapper.ts +++ b/src/contract_wrappers/contract_wrapper.ts @@ -63,16 +63,17 @@ export class ContractWrapper { private _getTopicsForIndexedArgs(abi: Web3.EventAbi, indexFilterValues: IndexedFilterValues): Array { const topics: Array = []; for (const eventInput of abi.inputs) { - if (eventInput.indexed) { - if (_.isUndefined(indexFilterValues[eventInput.name])) { - topics.push(null); - } else { - const value = indexFilterValues[eventInput.name] as string; - const buffer = ethUtil.toBuffer(value); - const paddedBuffer = ethUtil.setLengthLeft(buffer, TOPIC_LENGTH); - const topic = ethUtil.bufferToHex(paddedBuffer); - topics.push(topic); - } + if (!eventInput.indexed) { + continue; + } + if (_.isUndefined(indexFilterValues[eventInput.name])) { + topics.push(null); + } else { + const value = indexFilterValues[eventInput.name] as string; + const buffer = ethUtil.toBuffer(value); + const paddedBuffer = ethUtil.setLengthLeft(buffer, TOPIC_LENGTH); + const topic = ethUtil.bufferToHex(paddedBuffer); + topics.push(topic); } } return topics; -- cgit v1.2.3 From e5bdf60460330a24597e018f3611e7bc939c1362 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 4 Oct 2017 14:25:15 +0300 Subject: Move ZRX_NOT_IN_TOKEN_REGISTRY to InternalZeroExError --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/types.ts b/src/types.ts index 92b873886..35bb6af78 100644 --- a/src/types.ts +++ b/src/types.ts @@ -7,7 +7,6 @@ export enum ZeroExError { UserHasNoAssociatedAddress = 'USER_HAS_NO_ASSOCIATED_ADDRESSES', InvalidSignature = 'INVALID_SIGNATURE', ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK', - ZrxNotInTokenRegistry = 'ZRX_NOT_IN_TOKEN_REGISTRY', InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER', InsufficientBalanceForTransfer = 'INSUFFICIENT_BALANCE_FOR_TRANSFER', InsufficientEthBalanceForDeposit = 'INSUFFICIENT_ETH_BALANCE_FOR_DEPOSIT', @@ -19,6 +18,7 @@ export enum ZeroExError { export enum InternalZeroExError { NoAbiDecoder = 'NO_ABI_DECODER', + ZrxNotInTokenRegistry = 'ZRX_NOT_IN_TOKEN_REGISTRY', } /** -- cgit v1.2.3