Add initial implementation and tests for zeroEx.token.subscribeAsync
This commit is contained in:
		@@ -164,8 +164,8 @@ export class ZeroEx {
 | 
			
		||||
        this._web3Wrapper.setProvider(provider);
 | 
			
		||||
        await this.exchange.invalidateContractInstancesAsync();
 | 
			
		||||
        this.tokenRegistry.invalidateContractInstance();
 | 
			
		||||
        this.token.invalidateContractInstances();
 | 
			
		||||
        this._proxyWrapper.invalidateContractInstance();
 | 
			
		||||
        await this.token.invalidateContractInstancesAsync();
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Get user Ethereum addresses available through the supplied web3 instance available for sending transactions.
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@ import {
 | 
			
		||||
} from '../types';
 | 
			
		||||
import {assert} from '../utils/assert';
 | 
			
		||||
import {utils} from '../utils/utils';
 | 
			
		||||
import {eventUtils} from '../utils/event_utils';
 | 
			
		||||
import {ContractWrapper} from './contract_wrapper';
 | 
			
		||||
import {ProxyWrapper} from './proxy_wrapper';
 | 
			
		||||
import {ExchangeArtifactsByName} from '../exchange_artifacts_by_name';
 | 
			
		||||
@@ -601,7 +602,7 @@ export class ExchangeWrapper extends ContractWrapper {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const logEventObj: ContractEventObj = createLogEvent(indexFilterValues, subscriptionOpts);
 | 
			
		||||
        const eventEmitter = this._wrapEventEmitter(logEventObj);
 | 
			
		||||
        const eventEmitter = eventUtils.wrapEventEmitter(logEventObj);
 | 
			
		||||
        this._exchangeLogEventEmitters.push(eventEmitter);
 | 
			
		||||
        return eventEmitter;
 | 
			
		||||
    }
 | 
			
		||||
@@ -655,37 +656,6 @@ export class ExchangeWrapper extends ContractWrapper {
 | 
			
		||||
        const isAuthorized = await this._proxyWrapper.isAuthorizedAsync(exchangeContractAddress);
 | 
			
		||||
        return isAuthorized;
 | 
			
		||||
    }
 | 
			
		||||
    private _wrapEventEmitter(event: ContractEventObj): ContractEventEmitter {
 | 
			
		||||
        const watch = (eventCallback: EventCallback) => {
 | 
			
		||||
            const bignumberWrappingEventCallback = this._getBigNumberWrappingEventCallback(eventCallback);
 | 
			
		||||
            event.watch(bignumberWrappingEventCallback);
 | 
			
		||||
        };
 | 
			
		||||
        const zeroExEvent = {
 | 
			
		||||
            watch,
 | 
			
		||||
            stopWatchingAsync: async () => {
 | 
			
		||||
                await promisify(event.stopWatching, event)();
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
        return zeroExEvent;
 | 
			
		||||
    }
 | 
			
		||||
    private _getBigNumberWrappingEventCallback(eventCallback: EventCallback): EventCallback {
 | 
			
		||||
        const bignumberWrappingEventCallback = (err: Error, event: ContractEvent) => {
 | 
			
		||||
            if (_.isNull(err)) {
 | 
			
		||||
                const wrapIfBigNumber = (value: ContractEventArg): ContractEventArg => {
 | 
			
		||||
                    // HACK: The old version of BigNumber used by Web3@0.19.0 does not support the `isBigNumber`
 | 
			
		||||
                    // and checking for a BigNumber instance using `instanceof` does not work either. We therefore
 | 
			
		||||
                    // compare the constructor functions of the possible BigNumber instance and the BigNumber used by
 | 
			
		||||
                    // Web3.
 | 
			
		||||
                    const web3BigNumber = (Web3.prototype as any).BigNumber;
 | 
			
		||||
                    const isWeb3BigNumber = web3BigNumber.toString() === value.constructor.toString();
 | 
			
		||||
                    return isWeb3BigNumber ?  new BigNumber(value) : value;
 | 
			
		||||
                };
 | 
			
		||||
                event.args = _.mapValues(event.args, wrapIfBigNumber);
 | 
			
		||||
            }
 | 
			
		||||
            eventCallback(err, event);
 | 
			
		||||
        };
 | 
			
		||||
        return bignumberWrappingEventCallback;
 | 
			
		||||
    }
 | 
			
		||||
    private async _isValidSignatureUsingContractCallAsync(dataHex: string, ecSignature: ECSignature,
 | 
			
		||||
                                                          signerAddressHex: string,
 | 
			
		||||
                                                          exchangeContractAddress: string): Promise<boolean> {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,22 @@ import * as _ from 'lodash';
 | 
			
		||||
import * as BigNumber from 'bignumber.js';
 | 
			
		||||
import {Web3Wrapper} from '../web3_wrapper';
 | 
			
		||||
import {assert} from '../utils/assert';
 | 
			
		||||
import {utils} from '../utils/utils';
 | 
			
		||||
import {eventUtils} from '../utils/event_utils';
 | 
			
		||||
import {constants} from '../utils/constants';
 | 
			
		||||
import {ContractWrapper} from './contract_wrapper';
 | 
			
		||||
import * as TokenArtifacts from '../artifacts/Token.json';
 | 
			
		||||
import * as ProxyArtifacts from '../artifacts/Proxy.json';
 | 
			
		||||
import {TokenContract, ZeroExError} from '../types';
 | 
			
		||||
import {
 | 
			
		||||
    TokenContract,
 | 
			
		||||
    ZeroExError,
 | 
			
		||||
    TokenEvents,
 | 
			
		||||
    IndexedFilterValues,
 | 
			
		||||
    SubscriptionOpts,
 | 
			
		||||
    CreateContractEvent,
 | 
			
		||||
    ContractEventEmitter,
 | 
			
		||||
    ContractEventObj,
 | 
			
		||||
} from '../types';
 | 
			
		||||
 | 
			
		||||
const ALLOWANCE_TO_ZERO_GAS_AMOUNT = 45730;
 | 
			
		||||
 | 
			
		||||
@@ -17,11 +28,14 @@ const ALLOWANCE_TO_ZERO_GAS_AMOUNT = 45730;
 | 
			
		||||
 */
 | 
			
		||||
export class TokenWrapper extends ContractWrapper {
 | 
			
		||||
    private _tokenContractsByAddress: {[address: string]: TokenContract};
 | 
			
		||||
    private _tokenLogEventEmitters: ContractEventEmitter[];
 | 
			
		||||
    constructor(web3Wrapper: Web3Wrapper) {
 | 
			
		||||
        super(web3Wrapper);
 | 
			
		||||
        this._tokenContractsByAddress = {};
 | 
			
		||||
        this._tokenLogEventEmitters = [];
 | 
			
		||||
    }
 | 
			
		||||
    public invalidateContractInstances() {
 | 
			
		||||
    public async invalidateContractInstancesAsync(): Promise<void> {
 | 
			
		||||
        await this.stopWatchingAllEventsAsync();
 | 
			
		||||
        this._tokenContractsByAddress = {};
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
@@ -178,6 +192,45 @@ export class TokenWrapper extends ContractWrapper {
 | 
			
		||||
            from: senderAddress,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Subscribe to an event type emitted by the Token smart contract
 | 
			
		||||
     * @param   tokenAddress        The hex encoded contract Ethereum address where the ERC20 token is deployed.
 | 
			
		||||
     * @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 `{maker: aUserAddressHex}`
 | 
			
		||||
     * @return                      ContractEventEmitter object
 | 
			
		||||
     */
 | 
			
		||||
    public async subscribeAsync(tokenAddress: string, eventName: TokenEvents, subscriptionOpts: SubscriptionOpts,
 | 
			
		||||
                                indexFilterValues: IndexedFilterValues):
 | 
			
		||||
                                Promise<ContractEventEmitter> {
 | 
			
		||||
        const tokenContract = await this._getTokenContractAsync(tokenAddress);
 | 
			
		||||
        let createLogEvent: CreateContractEvent;
 | 
			
		||||
        switch (eventName) {
 | 
			
		||||
            case TokenEvents.Approval:
 | 
			
		||||
                createLogEvent = tokenContract.Approval;
 | 
			
		||||
                break;
 | 
			
		||||
            case TokenEvents.Transfer:
 | 
			
		||||
                createLogEvent = tokenContract.Transfer;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                throw utils.spawnSwitchErr('TokenEvents', eventName);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const logEventObj: ContractEventObj = createLogEvent(indexFilterValues, subscriptionOpts);
 | 
			
		||||
        const eventEmitter = eventUtils.wrapEventEmitter(logEventObj);
 | 
			
		||||
        this._tokenLogEventEmitters.push(eventEmitter);
 | 
			
		||||
        return eventEmitter;
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Stops watching for all token events
 | 
			
		||||
     */
 | 
			
		||||
    public async stopWatchingAllEventsAsync(): Promise<void> {
 | 
			
		||||
        const stopWatchingPromises = _.map(this._tokenLogEventEmitters,
 | 
			
		||||
                                           logEventObj => logEventObj.stopWatchingAsync());
 | 
			
		||||
        await Promise.all(stopWatchingPromises);
 | 
			
		||||
        this._tokenLogEventEmitters = [];
 | 
			
		||||
    }
 | 
			
		||||
    private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> {
 | 
			
		||||
        let tokenContract = this._tokenContractsByAddress[tokenAddress];
 | 
			
		||||
        if (!_.isUndefined(tokenContract)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ export {
 | 
			
		||||
    ContractEvent,
 | 
			
		||||
    Token,
 | 
			
		||||
    ExchangeEvents,
 | 
			
		||||
    TokenEvents,
 | 
			
		||||
    IndexedFilterValues,
 | 
			
		||||
    SubscriptionOpts,
 | 
			
		||||
    BlockParam,
 | 
			
		||||
@@ -22,6 +23,10 @@ export {
 | 
			
		||||
    LogErrorContractEventArgs,
 | 
			
		||||
    LogCancelContractEventArgs,
 | 
			
		||||
    LogFillContractEventArgs,
 | 
			
		||||
    ExchangeContractEventArgs,
 | 
			
		||||
    TransferContractEventArgs,
 | 
			
		||||
    ApprovalContractEventArgs,
 | 
			
		||||
    TokenContractEventArgs,
 | 
			
		||||
    ContractEventArgs,
 | 
			
		||||
    Web3Provider,
 | 
			
		||||
} from './types';
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								src/types.ts
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/types.ts
									
									
									
									
									
								
							@@ -122,6 +122,8 @@ export interface ExchangeContract extends ContractInstance {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface TokenContract extends ContractInstance {
 | 
			
		||||
    Transfer: CreateContractEvent;
 | 
			
		||||
    Approval: CreateContractEvent;
 | 
			
		||||
    balanceOf: {
 | 
			
		||||
        call: (address: string) => Promise<BigNumber.BigNumber>;
 | 
			
		||||
    };
 | 
			
		||||
@@ -236,7 +238,19 @@ export interface LogErrorContractEventArgs {
 | 
			
		||||
    errorId: BigNumber.BigNumber;
 | 
			
		||||
    orderHash: string;
 | 
			
		||||
}
 | 
			
		||||
export type ContractEventArgs = LogFillContractEventArgs|LogCancelContractEventArgs|LogErrorContractEventArgs;
 | 
			
		||||
export type ExchangeContractEventArgs = LogFillContractEventArgs|LogCancelContractEventArgs|LogErrorContractEventArgs;
 | 
			
		||||
export interface TransferContractEventArgs {
 | 
			
		||||
    _from: string;
 | 
			
		||||
    _to: string;
 | 
			
		||||
    _value: BigNumber.BigNumber;
 | 
			
		||||
}
 | 
			
		||||
export interface ApprovalContractEventArgs {
 | 
			
		||||
    _owner: string;
 | 
			
		||||
    _spender: string;
 | 
			
		||||
    _value: BigNumber.BigNumber;
 | 
			
		||||
}
 | 
			
		||||
export type TokenContractEventArgs = TransferContractEventArgs|ApprovalContractEventArgs;
 | 
			
		||||
export type ContractEventArgs = ExchangeContractEventArgs|TokenContractEventArgs;
 | 
			
		||||
export type ContractEventArg = string|BigNumber.BigNumber;
 | 
			
		||||
 | 
			
		||||
export interface Order {
 | 
			
		||||
@@ -286,6 +300,12 @@ export const ExchangeEvents = strEnum([
 | 
			
		||||
]);
 | 
			
		||||
export type ExchangeEvents = keyof typeof ExchangeEvents;
 | 
			
		||||
 | 
			
		||||
export const TokenEvents = strEnum([
 | 
			
		||||
    'Transfer',
 | 
			
		||||
    'Approval',
 | 
			
		||||
]);
 | 
			
		||||
export type TokenEvents = keyof typeof TokenEvents;
 | 
			
		||||
 | 
			
		||||
export interface IndexedFilterValues {
 | 
			
		||||
    [index: string]: any;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								src/utils/event_utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/utils/event_utils.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import * as Web3 from 'web3';
 | 
			
		||||
import {EventCallback, ContractEventArg, ContractEvent, ContractEventObj, ContractEventEmitter} from '../types';
 | 
			
		||||
import * as BigNumber from 'bignumber.js';
 | 
			
		||||
import promisify = require('es6-promisify');
 | 
			
		||||
 | 
			
		||||
export const eventUtils = {
 | 
			
		||||
    /**
 | 
			
		||||
     * Wrappes eventCallback function so that all the BigNumber arguments are wrapped in nwwer version of BigNumber
 | 
			
		||||
     * @param eventCallback     event callback function to be wrapped
 | 
			
		||||
     * @return Wrapped event callback function
 | 
			
		||||
     */
 | 
			
		||||
    getBigNumberWrappingEventCallback(eventCallback: EventCallback): EventCallback {
 | 
			
		||||
        const bignumberWrappingEventCallback = (err: Error, event: ContractEvent) => {
 | 
			
		||||
            if (_.isNull(err)) {
 | 
			
		||||
                const wrapIfBigNumber = (value: ContractEventArg): ContractEventArg => {
 | 
			
		||||
                    // HACK: The old version of BigNumber used by Web3@0.19.0 does not support the `isBigNumber`
 | 
			
		||||
                    // and checking for a BigNumber instance using `instanceof` does not work either. We therefore
 | 
			
		||||
                    // compare the constructor functions of the possible BigNumber instance and the BigNumber used by
 | 
			
		||||
                    // Web3.
 | 
			
		||||
                    const web3BigNumber = (Web3.prototype as any).BigNumber;
 | 
			
		||||
                    const isWeb3BigNumber = web3BigNumber.toString() === value.constructor.toString();
 | 
			
		||||
                    return isWeb3BigNumber ?  new BigNumber(value) : value;
 | 
			
		||||
                };
 | 
			
		||||
                event.args = _.mapValues(event.args, wrapIfBigNumber);
 | 
			
		||||
            }
 | 
			
		||||
            eventCallback(err, event);
 | 
			
		||||
        };
 | 
			
		||||
        return bignumberWrappingEventCallback;
 | 
			
		||||
    },
 | 
			
		||||
    wrapEventEmitter(event: ContractEventObj): ContractEventEmitter {
 | 
			
		||||
        const watch = (eventCallback: EventCallback) => {
 | 
			
		||||
            const bignumberWrappingEventCallback = eventUtils.getBigNumberWrappingEventCallback(eventCallback);
 | 
			
		||||
            event.watch(bignumberWrappingEventCallback);
 | 
			
		||||
        };
 | 
			
		||||
        const zeroExEvent = {
 | 
			
		||||
            watch,
 | 
			
		||||
            stopWatchingAsync: async () => {
 | 
			
		||||
                await promisify(event.stopWatching, event)();
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
        return zeroExEvent;
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
@@ -5,8 +5,17 @@ import * as Web3 from 'web3';
 | 
			
		||||
import * as BigNumber from 'bignumber.js';
 | 
			
		||||
import promisify = require('es6-promisify');
 | 
			
		||||
import {web3Factory} from './utils/web3_factory';
 | 
			
		||||
import {ZeroEx, ZeroExError, Token} from '../src';
 | 
			
		||||
import {
 | 
			
		||||
    ZeroEx,
 | 
			
		||||
    ZeroExError,
 | 
			
		||||
    Token,
 | 
			
		||||
    SubscriptionOpts,
 | 
			
		||||
    TokenEvents,
 | 
			
		||||
    ContractEvent,
 | 
			
		||||
    TransferContractEventArgs,
 | 
			
		||||
} from '../src';
 | 
			
		||||
import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
 | 
			
		||||
import {DoneCallback} from '../src/types';
 | 
			
		||||
 | 
			
		||||
chaiSetup.configure();
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -231,4 +240,106 @@ describe('TokenWrapper', () => {
 | 
			
		||||
            return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    describe('#subscribeAsync', () => {
 | 
			
		||||
        const indexFilterValues = {};
 | 
			
		||||
        const shouldCheckTransfer = false;
 | 
			
		||||
        let tokenAddress: string;
 | 
			
		||||
        const subscriptionOpts: SubscriptionOpts = {
 | 
			
		||||
            fromBlock: 0,
 | 
			
		||||
            toBlock: 'latest',
 | 
			
		||||
        };
 | 
			
		||||
        const transferAmount = new BigNumber(42);
 | 
			
		||||
        const allowanceAmount = new BigNumber(42);
 | 
			
		||||
        before(() => {
 | 
			
		||||
            const token = tokens[0];
 | 
			
		||||
            tokenAddress = token.address;
 | 
			
		||||
        });
 | 
			
		||||
        afterEach(async () => {
 | 
			
		||||
            await zeroEx.token.stopWatchingAllEventsAsync();
 | 
			
		||||
        });
 | 
			
		||||
        // Hack: Mocha does not allow a test to be both async and have a `done` callback
 | 
			
		||||
        // Since we need to await the receipt of the event in the `subscribeAsync` callback,
 | 
			
		||||
        // we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
 | 
			
		||||
        // wrap the rest of the test in an async block
 | 
			
		||||
        // Source: https://github.com/mochajs/mocha/issues/2407
 | 
			
		||||
        it('Should receive the Transfer event when an order is filled', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                const zeroExEvent = await zeroEx.token.subscribeAsync(
 | 
			
		||||
                    tokenAddress, TokenEvents.Transfer, subscriptionOpts, indexFilterValues);
 | 
			
		||||
                zeroExEvent.watch((err: Error, event: ContractEvent) => {
 | 
			
		||||
                    expect(err).to.be.null();
 | 
			
		||||
                    expect(event).to.not.be.undefined();
 | 
			
		||||
                    expect(event.args as TransferContractEventArgs).to.be.deep.equal({
 | 
			
		||||
                        _from: coinbase,
 | 
			
		||||
                        _to: addressWithoutFunds,
 | 
			
		||||
                        _value: transferAmount,
 | 
			
		||||
                    });
 | 
			
		||||
                    done();
 | 
			
		||||
                });
 | 
			
		||||
                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
 | 
			
		||||
            })();
 | 
			
		||||
        });
 | 
			
		||||
        it('Should receive the Approval event when an order is cancelled', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                const zeroExEvent = await zeroEx.token.subscribeAsync(
 | 
			
		||||
                    tokenAddress, TokenEvents.Approval, subscriptionOpts, indexFilterValues);
 | 
			
		||||
                zeroExEvent.watch((err: Error, event: ContractEvent) => {
 | 
			
		||||
                        expect(err).to.be.null();
 | 
			
		||||
                        expect(event).to.not.be.undefined();
 | 
			
		||||
                        expect(event.args as TransferContractEventArgs).to.be.deep.equal({
 | 
			
		||||
                            _owner: coinbase,
 | 
			
		||||
                            _spender: addressWithoutFunds,
 | 
			
		||||
                            _value: allowanceAmount,
 | 
			
		||||
                        });
 | 
			
		||||
                        done();
 | 
			
		||||
                });
 | 
			
		||||
                await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
 | 
			
		||||
            })();
 | 
			
		||||
        });
 | 
			
		||||
        it('Outstanding subscriptions are cancelled when zeroEx.setProviderAsync called', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                const eventSubscriptionToBeCancelled = await zeroEx.token.subscribeAsync(
 | 
			
		||||
                    tokenAddress, TokenEvents.Transfer, subscriptionOpts, indexFilterValues);
 | 
			
		||||
                eventSubscriptionToBeCancelled.watch((err: Error, event: ContractEvent) => {
 | 
			
		||||
                    done(new Error('Expected this subscription to have been cancelled'));
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                const newProvider = web3Factory.getRpcProvider();
 | 
			
		||||
                await zeroEx.setProviderAsync(newProvider);
 | 
			
		||||
 | 
			
		||||
                const eventSubscriptionToStay = await zeroEx.token.subscribeAsync(
 | 
			
		||||
                    tokenAddress, TokenEvents.Transfer, subscriptionOpts, indexFilterValues);
 | 
			
		||||
                eventSubscriptionToStay.watch((err: Error, event: ContractEvent) => {
 | 
			
		||||
                    expect(err).to.be.null();
 | 
			
		||||
                    expect(event).to.not.be.undefined();
 | 
			
		||||
                    done();
 | 
			
		||||
                });
 | 
			
		||||
                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
 | 
			
		||||
            })();
 | 
			
		||||
        });
 | 
			
		||||
        it('Should stop watch for events when stopWatchingAsync called on the eventEmitter', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                const eventSubscriptionToBeStopped = await zeroEx.token.subscribeAsync(
 | 
			
		||||
                    tokenAddress, TokenEvents.Transfer, subscriptionOpts, indexFilterValues);
 | 
			
		||||
                eventSubscriptionToBeStopped.watch((err: Error, event: ContractEvent) => {
 | 
			
		||||
                    done(new Error('Expected this subscription to have been stopped'));
 | 
			
		||||
                });
 | 
			
		||||
                await eventSubscriptionToBeStopped.stopWatchingAsync();
 | 
			
		||||
                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
 | 
			
		||||
                done();
 | 
			
		||||
            })();
 | 
			
		||||
        });
 | 
			
		||||
        it('Should wrap all event args BigNumber instances in a newer version of BigNumber', (done: DoneCallback) => {
 | 
			
		||||
            (async () => {
 | 
			
		||||
                const zeroExEvent = await zeroEx.token.subscribeAsync(
 | 
			
		||||
                    tokenAddress, TokenEvents.Transfer, subscriptionOpts, indexFilterValues);
 | 
			
		||||
                zeroExEvent.watch((err: Error, event: ContractEvent) => {
 | 
			
		||||
                    const args = event.args as TransferContractEventArgs;
 | 
			
		||||
                    expect(args._value.isBigNumber).to.be.true();
 | 
			
		||||
                    done();
 | 
			
		||||
                });
 | 
			
		||||
                await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
 | 
			
		||||
            })();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user