Compare commits

..

22 Commits

Author SHA1 Message Date
Leonid Logvinov
225ec50645 0.5.0 2017-06-14 11:41:42 +02:00
Leonid Logvinov
ba289c2843 Remove types that are not used in public interface from export and rename EventEmitter to ContractEventEmitter and IndexFilterValues to IndexedFilterValues 2017-06-14 11:27:33 +02:00
Leonid Logvinov
aea8c7f7df Merge branch 'master' of github.com:0xProject/0x.js 2017-06-14 11:18:05 +02:00
Fabio Berger
b24afe2653 Update doc:json command to exclude privates and externals 2017-06-14 11:05:23 +02:00
Leonid Logvinov
53fcdf13be 0.4.0 2017-06-13 18:08:48 +02:00
Leonid
2a56ab0846 Merge pull request #64 from 0xProject/events
Refactor events API
2017-06-13 18:08:30 +02:00
Leonid Logvinov
ac8116bbe4 Address feedback 2017-06-13 18:08:18 +02:00
Leonid Logvinov
5ebc3a4660 Rename ZeroExEvent to EventEmitter 2017-06-13 17:52:06 +02:00
Leonid Logvinov
55f4c45af1 Revert "0.4.0"
This reverts commit 870f9838d6.
2017-06-13 17:49:55 +02:00
Leonid Logvinov
96a93c4b35 Add tests for stopWatchingAsync 2017-06-13 17:39:43 +02:00
Leonid Logvinov
870f9838d6 0.4.0 2017-06-13 17:33:57 +02:00
Leonid Logvinov
048302625f Bind watch function on an event 2017-06-13 17:26:08 +02:00
Leonid Logvinov
6ad1900ada Refactor subscription to return zeroExSignature object 2017-06-13 15:52:50 +02:00
Leonid Logvinov
a045eb7bbb 0.3.0 2017-06-13 13:29:36 +02:00
Leonid Logvinov
52dc6b7710 Add getContractAddressAsync and tests 2017-06-13 13:29:02 +02:00
Leonid Logvinov
72318314c6 0.2.3 2017-06-12 19:08:15 +02:00
Leonid
2cac659f8b Merge pull request #63 from 0xProject/api-refactor
Api refactor
2017-06-12 19:07:40 +02:00
Leonid Logvinov
6cdd90e18b Fix test 2017-06-12 19:03:16 +02:00
Leonid Logvinov
7cf31db20e Fix test 2017-06-12 18:57:54 +02:00
Leonid Logvinov
2248514584 Change UMD bundle name 2017-06-12 18:49:57 +02:00
Leonid Logvinov
a4b431349d Export DoneCallback 2017-06-12 18:27:35 +02:00
Leonid Logvinov
365548e126 Introduce index.ts file which defines public interface 2017-06-12 18:20:43 +02:00
14 changed files with 129 additions and 55 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/0x.js",
"version": "0.2.2",
"version": "0.5.0",
"description": "A javascript library for interacting with the 0x protocol",
"keywords": [
"0x.js",
@@ -9,8 +9,8 @@
"tokens",
"exchange"
],
"main": "lib/src/0x.js",
"types": "lib/src/0x.d.ts",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"scripts": {
"prebuild": "npm run clean",
"build": "run-p build:*:prod",
@@ -21,7 +21,7 @@
"test:coverage": "nyc npm run test --all",
"update_contracts": "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../0x.js/src/artifacts; done;",
"testrpc": "testrpc -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
"docs:json": "typedoc --json docs/index.json .",
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json docs/index.json .",
"docs:generate": "typedoc --out docs .",
"docs:open": "opn docs/index.html",
"clean": "shx rm -rf _bundles lib test_temp",

View File

@@ -14,11 +14,11 @@ import {
SignedOrder,
ContractEvent,
ExchangeEvents,
ContractEventEmitter,
SubscriptionOpts,
IndexFilterValues,
IndexedFilterValues,
CreateContractEvent,
ContractEventObj,
EventCallback,
ContractResponse,
OrderCancellationRequest,
OrderFillRequest,
@@ -47,7 +47,7 @@ export class ExchangeWrapper extends ContractWrapper {
[ExchangeContractErrCodes.ERROR_FILL_BALANCE_ALLOWANCE]: ExchangeContractErrs.FILL_BALANCE_ALLOWANCE_ERROR,
};
private _exchangeContractIfExists?: ExchangeContract;
private _exchangeLogEventObjs: ContractEventObj[];
private _exchangeLogEventEmitters: ContractEventEmitter[];
private _tokenWrapper: TokenWrapper;
private static _getOrderAddressesAndValues(order: Order): [OrderAddresses, OrderValues] {
const orderAddresses: OrderAddresses = [
@@ -70,10 +70,10 @@ export class ExchangeWrapper extends ContractWrapper {
constructor(web3Wrapper: Web3Wrapper, tokenWrapper: TokenWrapper) {
super(web3Wrapper);
this._tokenWrapper = tokenWrapper;
this._exchangeLogEventObjs = [];
this._exchangeLogEventEmitters = [];
}
public async invalidateContractInstanceAsync(): Promise<void> {
await this._stopWatchingExchangeLogEventsAsync();
await this.stopWatchingAllEventsAsync();
delete this._exchangeContractIfExists;
}
/**
@@ -517,11 +517,11 @@ export class ExchangeWrapper extends ContractWrapper {
* @param subscriptionOpts Subscriptions options that let you configure the subscription.
* @param indexFilterValues A JS 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}`
* @param callback The callback that will be called everytime a matching event is found.
* @return ContractEventEmitter object
*/
public async subscribeAsync(eventName: ExchangeEvents, subscriptionOpts: SubscriptionOpts,
indexFilterValues: IndexFilterValues, callback: EventCallback):
Promise<void> {
indexFilterValues: IndexedFilterValues):
Promise<ContractEventEmitter> {
const exchangeContract = await this._getExchangeContractAsync();
let createLogEvent: CreateContractEvent;
switch (eventName) {
@@ -535,13 +535,40 @@ export class ExchangeWrapper extends ContractWrapper {
createLogEvent = exchangeContract.LogCancel;
break;
default:
utils.spawnSwitchErr('ExchangeEvents', eventName);
return;
throw utils.spawnSwitchErr('ExchangeEvents', eventName);
}
const logEventObj: ContractEventObj = createLogEvent(indexFilterValues, subscriptionOpts);
logEventObj.watch(callback);
this._exchangeLogEventObjs.push(logEventObj);
const eventEmitter = this._wrapEventEmitter(logEventObj);
this._exchangeLogEventEmitters.push(eventEmitter);
return eventEmitter;
}
/**
* Returns the ethereum address of the current exchange contract
* on the network that the provided web3 instance is connected to
* @return The ethereum address of the current exchange contract.
*/
public async getContractAddressAsync(): Promise<string> {
const exchangeContract = await this._getExchangeContractAsync();
return exchangeContract.address;
}
/**
* Stops watching for all exchange events
*/
public async stopWatchingAllEventsAsync(): Promise<void> {
const stopWatchingPromises = _.map(this._exchangeLogEventEmitters,
logEventObj => logEventObj.stopWatchingAsync());
await Promise.all(stopWatchingPromises);
this._exchangeLogEventEmitters = [];
}
private _wrapEventEmitter(event: ContractEventObj): ContractEventEmitter {
const zeroExEvent = {
watch: event.watch.bind(event),
stopWatchingAsync: async () => {
await promisify(event.stopWatching, event)();
},
};
return zeroExEvent;
}
private async _isValidSignatureUsingContractCallAsync(dataHex: string, ecSignature: ECSignature,
signerAddressHex: string): Promise<boolean> {
@@ -571,13 +598,6 @@ export class ExchangeWrapper extends ContractWrapper {
const orderHashHex = await exchangeInstance.getOrderHash.call(orderAddresses, orderValues);
return orderHashHex;
}
private async _stopWatchingExchangeLogEventsAsync() {
const stopWatchingPromises = _.map(this._exchangeLogEventObjs, logEventObj => {
return promisify(logEventObj.stopWatching, logEventObj)();
});
await Promise.all(stopWatchingPromises);
this._exchangeLogEventObjs = [];
}
private async _validateFillOrderAndThrowIfInvalidAsync(signedOrder: SignedOrder,
fillTakerAmount: BigNumber.BigNumber,
senderAddress: string): Promise<void> {

22
src/index.ts Normal file
View File

@@ -0,0 +1,22 @@
export {ZeroEx} from './0x';
export {
Order,
SignedOrder,
ECSignature,
ZeroExError,
EventCallback,
EventCallbackAsync,
EventCallbackSync,
ExchangeContractErrs,
ContractEvent,
Token,
ExchangeEvents,
IndexedFilterValues,
SubscriptionOpts,
BlockParam,
OrderFillOrKillRequest,
OrderCancellationRequest,
OrderFillRequest,
ContractEventEmitter,
} from './types';

View File

@@ -44,7 +44,7 @@ export interface ContractEventObj {
watch: (eventWatch: EventCallback) => void;
stopWatching: () => void;
}
export type CreateContractEvent = (indexFilterValues: IndexFilterValues,
export type CreateContractEvent = (indexFilterValues: IndexedFilterValues,
subscriptionOpts: SubscriptionOpts) => ContractEventObj;
export interface ExchangeContract extends ContractInstance {
isValidSignature: {
@@ -238,7 +238,7 @@ export const ExchangeEvents = strEnum([
]);
export type ExchangeEvents = keyof typeof ExchangeEvents;
export interface IndexFilterValues {
export interface IndexedFilterValues {
[index: string]: any;
}
@@ -275,3 +275,8 @@ export interface ContractInstance {
export interface Artifact {
networks: {[networkId: number]: any};
}
export interface ContractEventEmitter {
watch: (eventCallback: EventCallback) => void;
stopWatchingAsync: () => Promise<void>;
}

View File

@@ -22,11 +22,11 @@ export const utils = {
isParityNode(nodeVersion: string): boolean {
return _.includes(nodeVersion, 'Parity');
},
isValidOrderHash(orderHashHex: string) {
isValidOrderHash(orderHashHex: string): boolean {
const isValid = /^0x[0-9A-F]{64}$/i.test(orderHashHex);
return isValid;
},
spawnSwitchErr(name: string, value: any) {
spawnSwitchErr(name: string, value: any): Error {
return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
},
getOrderHashHex(order: Order|SignedOrder, exchangeContractAddr: string): string {

View File

@@ -4,10 +4,8 @@ import {chaiSetup} from './utils/chai_setup';
import 'mocha';
import * as BigNumber from 'bignumber.js';
import * as Sinon from 'sinon';
import {ZeroEx} from '../src/0x';
import {ZeroEx, Order} from '../src';
import {constants} from './utils/constants';
import {Order} from '../src/types';
import {ECSignature} from '../src/types';
import {web3Factory} from './utils/web3_factory';
chaiSetup.configure();

View File

@@ -1,6 +1,6 @@
import * as chai from 'chai';
import 'mocha';
import {ZeroEx} from '../src/0x';
import {ZeroEx} from '../src';
import {assert} from '../src/utils/assert';
import {web3Factory} from './utils/web3_factory';

View File

@@ -6,22 +6,22 @@ import {chaiSetup} from './utils/chai_setup';
import ChaiBigNumber = require('chai-bignumber');
import promisify = require('es6-promisify');
import {web3Factory} from './utils/web3_factory';
import {ZeroEx} from '../src/0x';
import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
import {
ZeroEx,
Token,
Order,
SignedOrder,
SubscriptionOpts,
ExchangeEvents,
ContractEvent,
DoneCallback,
ExchangeContractErrs,
OrderCancellationRequest,
OrderFillRequest,
} from '../src/types';
} from '../src';
import {DoneCallback} from '../src/types';
import {FillScenarios} from './utils/fill_scenarios';
import {TokenUtils} from './utils/token_utils';
import {assert} from '../src/utils/assert';
chaiSetup.configure();
const expect = chai.expect;
@@ -618,7 +618,7 @@ describe('ExchangeWrapper', () => {
);
});
afterEach(async () => {
await (zeroEx.exchange as any)._stopWatchingExchangeLogEventsAsync();
await zeroEx.exchange.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,
@@ -631,8 +631,9 @@ describe('ExchangeWrapper', () => {
fromBlock: 0,
toBlock: 'latest',
};
await zeroEx.exchange.subscribeAsync(ExchangeEvents.LogFill, subscriptionOpts,
indexFilterValues, (err: Error, event: ContractEvent) => {
const zeroExEvent = await zeroEx.exchange.subscribeAsync(ExchangeEvents.LogFill, subscriptionOpts,
indexFilterValues);
zeroExEvent.watch((err: Error, event: ContractEvent) => {
expect(err).to.be.null();
expect(event).to.not.be.undefined();
done();
@@ -649,12 +650,13 @@ describe('ExchangeWrapper', () => {
fromBlock: 0,
toBlock: 'latest',
};
await zeroEx.exchange.subscribeAsync(ExchangeEvents.LogCancel, subscriptionOpts,
indexFilterValues, (err: Error, event: ContractEvent) => {
const zeroExEvent = await zeroEx.exchange.subscribeAsync(ExchangeEvents.LogCancel, subscriptionOpts,
indexFilterValues);
zeroExEvent.watch((err: Error, event: ContractEvent) => {
expect(err).to.be.null();
expect(event).to.not.be.undefined();
done();
});
});
const cancelTakerAmountInBaseUnits = new BigNumber(1);
await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
})();
@@ -665,16 +667,20 @@ describe('ExchangeWrapper', () => {
fromBlock: 0,
toBlock: 'latest',
};
await zeroEx.exchange.subscribeAsync(ExchangeEvents.LogFill, subscriptionOpts,
indexFilterValues, (err: Error, event: ContractEvent) => {
const eventSubscriptionToBeCancelled = await zeroEx.exchange.subscribeAsync(
ExchangeEvents.LogFill, 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);
await zeroEx.exchange.subscribeAsync(ExchangeEvents.LogFill, subscriptionOpts,
indexFilterValues, (err: Error, event: ContractEvent) => {
const eventSubscriptionToStay = await zeroEx.exchange.subscribeAsync(
ExchangeEvents.LogFill, subscriptionOpts, indexFilterValues,
);
eventSubscriptionToStay.watch((err: Error, event: ContractEvent) => {
expect(err).to.be.null();
expect(event).to.not.be.undefined();
done();
@@ -686,6 +692,26 @@ describe('ExchangeWrapper', () => {
);
})();
});
it('Should stop watch for events when stopWatchingAsync called on the eventEmitter', (done: DoneCallback) => {
(async () => {
const subscriptionOpts: SubscriptionOpts = {
fromBlock: 0,
toBlock: 'latest',
};
const eventSubscriptionToBeStopped = await zeroEx.exchange.subscribeAsync(
ExchangeEvents.LogFill, subscriptionOpts, indexFilterValues,
);
eventSubscriptionToBeStopped.watch((err: Error, event: ContractEvent) => {
done(new Error('Expected this subscription to have been stopped'));
});
await eventSubscriptionToBeStopped.stopWatchingAsync();
const fillTakerAmountInBaseUnits = new BigNumber(1);
await zeroEx.exchange.fillOrderAsync(
signedOrder, fillTakerAmountInBaseUnits, shouldCheckTransfer, takerAddress,
);
done();
})();
});
});
describe('#getOrderHashHexUsingContractCallAsync', () => {
let makerTokenAddress: string;
@@ -709,4 +735,10 @@ describe('ExchangeWrapper', () => {
expect(orderHash).to.equal(orderHashFromContract);
});
});
describe('#getContractAddressAsync', () => {
it('returns the exchange contract address', async () => {
const exchangeAddress = await zeroEx.exchange.getContractAddressAsync();
assert.isETHAddressHex('exchangeAddress', exchangeAddress);
});
});
});

View File

@@ -3,7 +3,7 @@ import 'mocha';
import * as chai from 'chai';
import {chaiSetup} from './utils/chai_setup';
import {web3Factory} from './utils/web3_factory';
import {ZeroEx} from '../src/0x';
import {ZeroEx} from '../src';
import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
import {SchemaValidator} from '../src/utils/schema_validator';
import {tokenSchema} from '../src/schemas/token_schema';

View File

@@ -5,8 +5,7 @@ import * as Web3 from 'web3';
import * as BigNumber from 'bignumber.js';
import promisify = require('es6-promisify');
import {web3Factory} from './utils/web3_factory';
import {ZeroEx} from '../src/0x';
import {ZeroExError, Token} from '../src/types';
import {ZeroEx, ZeroExError, Token} from '../src';
import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
chaiSetup.configure();

View File

@@ -1,6 +1,5 @@
import * as BigNumber from 'bignumber.js';
import {ZeroEx} from '../../src/0x';
import {Token, SignedOrder} from '../../src/types';
import {ZeroEx, Token, SignedOrder} from '../../src';
import {orderFactory} from '../utils/order_factory';
import {constants} from './constants';

View File

@@ -1,7 +1,6 @@
import * as _ from 'lodash';
import * as BigNumber from 'bignumber.js';
import {SignedOrder} from '../../src/types';
import {ZeroEx} from '../../src/0x';
import {ZeroEx, SignedOrder} from '../../src';
export const orderFactory = {
async createSignedOrderAsync(

View File

@@ -1,5 +1,5 @@
import * as _ from 'lodash';
import {Token, ZeroExError} from '../../src/types';
import {Token, ZeroExError} from '../../src';
const PROTOCOL_TOKEN_SYMBOL = 'ZRX';

View File

@@ -7,10 +7,10 @@ const path = require('path');
const production = process.env.NODE_ENV === 'production';
let entry = {
'0x': './src/0x.ts',
'index': './src/index.ts',
};
if (production) {
entry = _.assign({}, entry, {'0x.min': './src/0x.ts'});
entry = _.assign({}, entry, {'index.min': './src/index.ts'});
}
module.exports = {