diff options
Diffstat (limited to 'packages')
-rw-r--r-- | packages/0x.js/CHANGELOG.md | 2 | ||||
-rw-r--r-- | packages/0x.js/src/order_watcher/order_state_watcher.ts | 25 | ||||
-rw-r--r-- | packages/0x.js/test/order_state_watcher_test.ts | 46 |
3 files changed, 50 insertions, 23 deletions
diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md index 69fd7661b..6245308c3 100644 --- a/packages/0x.js/CHANGELOG.md +++ b/packages/0x.js/CHANGELOG.md @@ -3,6 +3,8 @@ vx.x.x ------------------------ * Remove support for Async callback types when used in Subscribe functions + * In OrderWatcher subscribe to ZRX Token Transfer and Approval events when maker token is different (#225) + v0.25.1 - _November 13, 2017_ ------------------------ * Standardise on Cancelled over Canceled diff --git a/packages/0x.js/src/order_watcher/order_state_watcher.ts b/packages/0x.js/src/order_watcher/order_state_watcher.ts index 1b410dad1..33fa69b1c 100644 --- a/packages/0x.js/src/order_watcher/order_state_watcher.ts +++ b/packages/0x.js/src/order_watcher/order_state_watcher.ts @@ -78,24 +78,27 @@ export class OrderStateWatcher { * signature is verified. * @param signedOrder The order you wish to start watching. */ - public addOrder(signedOrder: SignedOrder): void { + public async addOrderAsync(signedOrder: SignedOrder): Promise<void> { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); const orderHash = ZeroEx.getOrderHashHex(signedOrder); assert.isValidSignature(orderHash, signedOrder.ecSignature, signedOrder.maker); this._orderByOrderHash[orderHash] = signedOrder; - this.addToDependentOrderHashes(signedOrder, orderHash); + await this.addToDependentOrderHashesAsync(signedOrder, orderHash); } /** * Removes an order from the orderStateWatcher * @param orderHash The orderHash of the order you wish to stop watching. */ - public removeOrder(orderHash: string): void { + public async removeOrderAsync(orderHash: string): Promise<void> { assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema); const signedOrder = this._orderByOrderHash[orderHash]; if (_.isUndefined(signedOrder)) { return; // noop } delete this._orderByOrderHash[orderHash]; + const exchange = (this._orderFilledCancelledLazyStore as any).exchange as ExchangeWrapper; + const zrxTokenAddress = await exchange.getZRXTokenAddressAsync(); + this.removeFromDependentOrderHashes(signedOrder.maker, zrxTokenAddress, orderHash); this.removeFromDependentOrderHashes(signedOrder.maker, signedOrder.makerTokenAddress, orderHash); } /** @@ -210,7 +213,7 @@ export class OrderStateWatcher { this._callbackIfExists(orderState); } } - private addToDependentOrderHashes(signedOrder: SignedOrder, orderHash: string) { + private async addToDependentOrderHashesAsync(signedOrder: SignedOrder, orderHash: string): Promise<void> { if (_.isUndefined(this._dependentOrderHashes[signedOrder.maker])) { this._dependentOrderHashes[signedOrder.maker] = {}; } @@ -218,11 +221,17 @@ export class OrderStateWatcher { this._dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress] = new Set(); } this._dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress].add(orderHash); + const exchange = (this._orderFilledCancelledLazyStore as any).exchange as ExchangeWrapper; + const zrxTokenAddress = await exchange.getZRXTokenAddressAsync(); + if (_.isUndefined(this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress])) { + this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress] = new Set(); + } + this._dependentOrderHashes[signedOrder.maker][zrxTokenAddress].add(orderHash); } - private removeFromDependentOrderHashes(makerAddress: string, makerTokenAddress: string, orderHash: string) { - this._dependentOrderHashes[makerAddress][makerTokenAddress].delete(orderHash); - if (this._dependentOrderHashes[makerAddress][makerTokenAddress].size === 0) { - delete this._dependentOrderHashes[makerAddress][makerTokenAddress]; + private removeFromDependentOrderHashes(makerAddress: string, tokenAddress: string, orderHash: string) { + this._dependentOrderHashes[makerAddress][tokenAddress].delete(orderHash); + if (this._dependentOrderHashes[makerAddress][tokenAddress].size === 0) { + delete this._dependentOrderHashes[makerAddress][tokenAddress]; } if (_.isEmpty(this._dependentOrderHashes[makerAddress])) { delete this._dependentOrderHashes[makerAddress]; diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index a112bac1d..00b290252 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -73,13 +73,13 @@ describe('OrderStateWatcher', () => { makerToken.address, takerToken.address, maker, taker, fillableAmount, ); const orderHash = ZeroEx.getOrderHashHex(signedOrder); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); expect((zeroEx.orderStateWatcher as any)._orderByOrderHash).to.include({ [orderHash]: signedOrder, }); let dependentOrderHashes = (zeroEx.orderStateWatcher as any)._dependentOrderHashes; expect(dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress]).to.have.keys(orderHash); - zeroEx.orderStateWatcher.removeOrder(orderHash); + await zeroEx.orderStateWatcher.removeOrderAsync(orderHash); expect((zeroEx.orderStateWatcher as any)._orderByOrderHash).to.not.include({ [orderHash]: signedOrder, }); @@ -92,7 +92,7 @@ describe('OrderStateWatcher', () => { ); const orderHash = ZeroEx.getOrderHashHex(signedOrder); const nonExistentOrderHash = `0x${orderHash.substr(2).split('').reverse().join('')}`; - zeroEx.orderStateWatcher.removeOrder(nonExistentOrderHash); + await zeroEx.orderStateWatcher.removeOrderAsync(nonExistentOrderHash); }); }); describe('#subscribe', async () => { @@ -109,7 +109,7 @@ describe('OrderStateWatcher', () => { afterEach(async () => { zeroEx.orderStateWatcher.unsubscribe(); const orderHash = ZeroEx.getOrderHashHex(signedOrder); - zeroEx.orderStateWatcher.removeOrder(orderHash); + await zeroEx.orderStateWatcher.removeOrderAsync(orderHash); }); it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => { (async () => { @@ -117,7 +117,7 @@ describe('OrderStateWatcher', () => { makerToken.address, takerToken.address, maker, taker, fillableAmount, ); const orderHash = ZeroEx.getOrderHashHex(signedOrder); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); const invalidOrderState = orderState as OrderStateInvalid; @@ -135,7 +135,7 @@ describe('OrderStateWatcher', () => { makerToken.address, takerToken.address, maker, taker, fillableAmount, ); const orderHash = ZeroEx.getOrderHashHex(signedOrder); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { throw new Error('OrderState callback fired for irrelevant order'); }); @@ -156,7 +156,7 @@ describe('OrderStateWatcher', () => { makerToken.address, takerToken.address, maker, taker, fillableAmount, ); const orderHash = ZeroEx.getOrderHashHex(signedOrder); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); const invalidOrderState = orderState as OrderStateInvalid; @@ -176,7 +176,7 @@ describe('OrderStateWatcher', () => { makerToken.address, takerToken.address, maker, taker, fillableAmount, ); const orderHash = ZeroEx.getOrderHashHex(signedOrder); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); let eventCount = 0; const callback = reportCallbackErrors(done)((orderState: OrderState) => { @@ -208,7 +208,7 @@ describe('OrderStateWatcher', () => { const fillAmountInBaseUnits = new BigNumber(2); const orderHash = ZeroEx.getOrderHashHex(signedOrder); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); let eventCount = 0; const callback = reportCallbackErrors(done)((orderState: OrderState) => { @@ -235,6 +235,22 @@ describe('OrderStateWatcher', () => { ); })().catch(done); }); + it('should trigger the callback when orders backing ZRX allowance changes', (done: DoneCallback) => { + (async () => { + const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18); + const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18); + signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync( + makerToken.address, takerToken.address, makerFee, takerFee, maker, taker, fillableAmount, + taker); + const orderHash = ZeroEx.getOrderHashHex(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); + const callback = reportCallbackErrors(done)((orderState: OrderState) => { + done(); + }); + zeroEx.orderStateWatcher.subscribe(callback); + await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, new BigNumber(0)); + })().catch(done); + }); describe('remainingFillable(M|T)akerTokenAmount', () => { it('should calculate correct remaining fillable', (done: DoneCallback) => { (async () => { @@ -248,7 +264,7 @@ describe('OrderStateWatcher', () => { const takerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, taker); const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18); const orderHash = ZeroEx.getOrderHashHex(signedOrder); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); let eventCount = 0; const callback = reportCallbackErrors(done)((orderState: OrderState) => { eventCount++; @@ -280,7 +296,7 @@ describe('OrderStateWatcher', () => { const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker); const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), 18); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { const validOrderState = orderState as OrderStateValid; @@ -305,7 +321,7 @@ describe('OrderStateWatcher', () => { const remainingAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18); const transferAmount = makerBalance.sub(remainingAmount); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { const validOrderState = orderState as OrderStateValid; @@ -328,7 +344,7 @@ describe('OrderStateWatcher', () => { makerToken.address, takerToken.address, maker, taker, fillableAmount, ); const orderHash = ZeroEx.getOrderHashHex(signedOrder); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); @@ -350,7 +366,7 @@ describe('OrderStateWatcher', () => { makerToken.address, takerToken.address, maker, taker, fillableAmount, ); const orderHash = ZeroEx.getOrderHashHex(signedOrder); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); @@ -376,7 +392,7 @@ describe('OrderStateWatcher', () => { const cancelAmountInBaseUnits = new BigNumber(2); const orderHash = ZeroEx.getOrderHashHex(signedOrder); - zeroEx.orderStateWatcher.addOrder(signedOrder); + await zeroEx.orderStateWatcher.addOrderAsync(signedOrder); const callback = reportCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.true(); |