diff options
author | fragosti <francesco.agosti93@gmail.com> | 2018-08-21 02:42:29 +0800 |
---|---|---|
committer | fragosti <francesco.agosti93@gmail.com> | 2018-08-21 02:42:29 +0800 |
commit | 075e3a41c876797907e3ad98f20940e32e8d0762 (patch) | |
tree | d1f9db70ee1a56b500a3293a9ee962fd08f7abec | |
parent | f2d1d953553adfa59f0a39bf2cf98817fae0a4ff (diff) | |
download | dexon-sol-tools-075e3a41c876797907e3ad98f20940e32e8d0762.tar dexon-sol-tools-075e3a41c876797907e3ad98f20940e32e8d0762.tar.gz dexon-sol-tools-075e3a41c876797907e3ad98f20940e32e8d0762.tar.bz2 dexon-sol-tools-075e3a41c876797907e3ad98f20940e32e8d0762.tar.lz dexon-sol-tools-075e3a41c876797907e3ad98f20940e32e8d0762.tar.xz dexon-sol-tools-075e3a41c876797907e3ad98f20940e32e8d0762.tar.zst dexon-sol-tools-075e3a41c876797907e3ad98f20940e32e8d0762.zip |
Update websocket for SRA v2
12 files changed, 71 insertions, 74 deletions
diff --git a/packages/connect/CHANGELOG.json b/packages/connect/CHANGELOG.json index 8d6feaa2e..1f17392a9 100644 --- a/packages/connect/CHANGELOG.json +++ b/packages/connect/CHANGELOG.json @@ -1,5 +1,13 @@ [ { + "version": "2.0.0", + "changes": [ + { + "note": "Updated for SRA v2" + } + ] + }, + { "timestamp": 1534210131, "version": "1.0.5", "changes": [ diff --git a/packages/connect/src/types.ts b/packages/connect/src/types.ts index f90f0808d..dbed8899f 100644 --- a/packages/connect/src/types.ts +++ b/packages/connect/src/types.ts @@ -31,7 +31,7 @@ export interface OrdersChannelHandler { onUpdate: ( channel: OrdersChannel, subscriptionOpts: OrdersChannelSubscriptionOpts, - order: APIOrder, + orders: APIOrder[], ) => void; onError: (channel: OrdersChannel, err: Error, subscriptionOpts?: OrdersChannelSubscriptionOpts) => void; onClose: (channel: OrdersChannel) => void; @@ -48,13 +48,13 @@ export enum OrdersChannelMessageTypes { export interface UpdateOrdersChannelMessage { type: OrdersChannelMessageTypes.Update; - requestId: number; - payload: APIOrder; + requestId: string; + payload: APIOrder[]; } export interface UnknownOrdersChannelMessage { type: OrdersChannelMessageTypes.Unknown; - requestId: number; + requestId: string; payload: undefined; } diff --git a/packages/connect/src/utils/orderbook_channel_message_parser.ts b/packages/connect/src/utils/orders_channel_message_parser.ts index 97d8f2d6a..1b6cda17b 100644 --- a/packages/connect/src/utils/orderbook_channel_message_parser.ts +++ b/packages/connect/src/utils/orders_channel_message_parser.ts @@ -15,15 +15,15 @@ export const ordersChannelMessageParser = { assert.assert(!_.isUndefined(type), `Message is missing a type parameter: ${utf8Data}`); assert.isString('type', type); // ensure we have a request id for the resulting message - const requestId: number = _.get(messageObj, 'requestId'); + const requestId: string = _.get(messageObj, 'requestId'); assert.assert(!_.isUndefined(requestId), `Message is missing a requestId parameter: ${utf8Data}`); - assert.isNumber('requestId', requestId); + assert.isString('requestId', requestId); switch (type) { case OrdersChannelMessageTypes.Update: { assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrdersChannelUpdateSchema); - const orderJson = messageObj.payload; - const order = relayerResponseJsonParsers.parseAPIOrderJson(orderJson); - return _.assign(messageObj, { payload: order }); + const ordersJson = messageObj.payload; + const orders = relayerResponseJsonParsers.parseAPIOrdersJson(ordersJson); + return _.assign(messageObj, { payload: orders }); } default: { return { diff --git a/packages/connect/src/utils/relayer_response_json_parsers.ts b/packages/connect/src/utils/relayer_response_json_parsers.ts index 2b2e1efe7..dff854dfb 100644 --- a/packages/connect/src/utils/relayer_response_json_parsers.ts +++ b/packages/connect/src/utils/relayer_response_json_parsers.ts @@ -22,7 +22,10 @@ export const relayerResponseJsonParsers = { }, parseOrdersJson(json: any): OrdersResponse { assert.doesConformToSchema('relayerApiOrdersResponse', json, schemas.relayerApiOrdersResponseSchema); - return { ...json, records: json.records.map(relayerResponseJsonParsers.parseAPIOrderJson.bind(relayerResponseJsonParsers)) }; + return { ...json, records: relayerResponseJsonParsers.parseAPIOrdersJson(json.records) }; + }, + parseAPIOrdersJson(json: any): APIOrder[] { + return json.map(relayerResponseJsonParsers.parseAPIOrderJson.bind(relayerResponseJsonParsers)); }, parseAPIOrderJson(json: any): APIOrder { assert.doesConformToSchema('relayerApiOrder', json, schemas.relayerApiOrderSchema); diff --git a/packages/connect/src/ws_orders_channel.ts b/packages/connect/src/ws_orders_channel.ts index 9d45b6570..62960d23a 100644 --- a/packages/connect/src/ws_orders_channel.ts +++ b/packages/connect/src/ws_orders_channel.ts @@ -9,7 +9,11 @@ import { OrdersChannelSubscriptionOpts, } from './types'; import { assert } from './utils/assert'; -import { ordersChannelMessageParser } from './utils/orderbook_channel_message_parser'; +import { ordersChannelMessageParser } from './utils/orders_channel_message_parser'; + +export interface OrdersChannelSubscriptionOptsMap { + [key: string]: OrdersChannelSubscriptionOpts; +} /** * This class includes all the functionality related to interacting with a websocket endpoint @@ -18,7 +22,7 @@ import { ordersChannelMessageParser } from './utils/orderbook_channel_message_pa export class WebSocketOrdersChannel implements OrdersChannel { private readonly _client: WebSocket.w3cwebsocket; private readonly _handler: OrdersChannelHandler; - private readonly _subscriptionOptsList: OrdersChannelSubscriptionOpts[] = []; + private readonly _subscriptionOptsMap: OrdersChannelSubscriptionOptsMap = {}; /** * Instantiates a new WebSocketOrdersChannel instance * @param client A WebSocket client @@ -50,11 +54,12 @@ export class WebSocketOrdersChannel implements OrdersChannel { public subscribe(subscriptionOpts: OrdersChannelSubscriptionOpts): void { assert.isOrdersChannelSubscriptionOpts('subscriptionOpts', subscriptionOpts); assert.assert(this._client.readyState === WebSocket.w3cwebsocket.OPEN, 'WebSocket connection is closed'); - this._subscriptionOptsList.push(subscriptionOpts); + const requestId = uuid(); + this._subscriptionOptsMap[requestId] = subscriptionOpts; const subscribeMessage = { type: 'subscribe', channel: 'orders', - requestId: uuid(), + requestId, payload: subscriptionOpts, }; this._client.send(JSON.stringify(subscribeMessage)); @@ -73,7 +78,7 @@ export class WebSocketOrdersChannel implements OrdersChannel { try { const data = message.data; const parserResult = ordersChannelMessageParser.parse(data); - const subscriptionOpts = this._subscriptionOptsList[parserResult.requestId]; + const subscriptionOpts = this._subscriptionOptsMap[parserResult.requestId]; if (_.isUndefined(subscriptionOpts)) { this._handler.onError( this, diff --git a/packages/connect/test/fixtures/standard_relayer_api/unknown_orderbook_channel_message.ts b/packages/connect/test/fixtures/standard_relayer_api/unknown_orders_channel_message.ts index c0e924a4b..b6c0cd50c 100644 --- a/packages/connect/test/fixtures/standard_relayer_api/unknown_orderbook_channel_message.ts +++ b/packages/connect/test/fixtures/standard_relayer_api/unknown_orders_channel_message.ts @@ -5,6 +5,6 @@ const orderJSONString = JSON.stringify(orderResponseJSON); export const unknownOrdersChannelMessage = `{ "type": "superGoodUpdate", "channel": "orderbook", - "requestId": 1, - "payload": ${orderJSONString} + "requestId": "6ce8c5a6-5c46-4027-a44a-51831c77b8a1", + "payload": [${orderJSONString}] }`; diff --git a/packages/connect/test/fixtures/standard_relayer_api/update_orderbook_channel_message.ts b/packages/connect/test/fixtures/standard_relayer_api/update_orderbook_channel_message.ts deleted file mode 100644 index daab20368..000000000 --- a/packages/connect/test/fixtures/standard_relayer_api/update_orderbook_channel_message.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as orderResponseJSON from './order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json'; - -const orderJSONString = JSON.stringify(orderResponseJSON); - -export const updateOrdersChannelMessage = `{ - "type": "update", - "channel": "orderbook", - "requestId": 1, - "payload": ${orderJSONString} -}`; - -export const malformedUpdateOrdersChannelMessage = `{ - "type": "update", - "channel": "orderbook", - "requestId": 1, - "payload": {} -}`; diff --git a/packages/connect/test/fixtures/standard_relayer_api/update_orders_channel_message.ts b/packages/connect/test/fixtures/standard_relayer_api/update_orders_channel_message.ts new file mode 100644 index 000000000..c18a2c789 --- /dev/null +++ b/packages/connect/test/fixtures/standard_relayer_api/update_orders_channel_message.ts @@ -0,0 +1,17 @@ +import * as apiOrderJSON from './order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json'; + +const apiOrderJSONString = JSON.stringify(apiOrderJSON); + +export const updateOrdersChannelMessage = `{ + "type": "update", + "channel": "orders", + "requestId": "5a1ce3a2-22b9-41e6-a615-68077512e9e2", + "payload": [${apiOrderJSONString}] +}`; + +export const malformedUpdateOrdersChannelMessage = `{ + "type": "update", + "channel": "orders", + "requestId": "4d8efcee-adde-4475-9601-f0b30962ca2b", + "payload": {} +}`; diff --git a/packages/connect/test/http_client_test.ts b/packages/connect/test/http_client_test.ts index 1c40cb10f..9ead010d3 100644 --- a/packages/connect/test/http_client_test.ts +++ b/packages/connect/test/http_client_test.ts @@ -191,6 +191,3 @@ describe('HttpClient', () => { }); }); }); - -// https://example.com/fee_recipients?networkId=42&page=3&perPage=50 -// https://example.com/fee_recipients?networkId=42&page=3&perPage=50
\ No newline at end of file diff --git a/packages/connect/test/orderbook_channel_factory_test.ts b/packages/connect/test/orders_channel_factory_test.ts index 66394cdc9..fcd07dd35 100644 --- a/packages/connect/test/orderbook_channel_factory_test.ts +++ b/packages/connect/test/orders_channel_factory_test.ts @@ -9,15 +9,9 @@ chai.config.includeStack = true; chai.use(dirtyChai); const expect = chai.expect; const emptyOrdersChannelHandler = { - onUpdate: () => { - _.noop(); - }, - onError: () => { - _.noop(); - }, - onClose: () => { - _.noop(); - }, + onUpdate: _.noop, + onError: _.noop, + onClose: _.noop, }; describe('ordersChannelFactory', () => { diff --git a/packages/connect/test/orderbook_channel_message_parsers_test.ts b/packages/connect/test/orders_channel_message_parsers_test.ts index b5a91330d..4d4a2d23f 100644 --- a/packages/connect/test/orderbook_channel_message_parsers_test.ts +++ b/packages/connect/test/orders_channel_message_parsers_test.ts @@ -2,14 +2,14 @@ import * as chai from 'chai'; import * as dirtyChai from 'dirty-chai'; import 'mocha'; -import { ordersChannelMessageParser } from '../src/utils/orderbook_channel_message_parser'; +import { ordersChannelMessageParser } from '../src/utils/orders_channel_message_parser'; import { orderResponse } from './fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f'; -import { unknownOrdersChannelMessage } from './fixtures/standard_relayer_api/unknown_orderbook_channel_message'; +import { unknownOrdersChannelMessage } from './fixtures/standard_relayer_api/unknown_orders_channel_message'; import { malformedUpdateOrdersChannelMessage, updateOrdersChannelMessage, -} from './fixtures/standard_relayer_api/update_orderbook_channel_message'; +} from './fixtures/standard_relayer_api/update_orders_channel_message'; chai.config.includeStack = true; chai.use(dirtyChai); @@ -20,7 +20,7 @@ describe('ordersChannelMessageParser', () => { it('parses update messages', () => { const updateMessage = ordersChannelMessageParser.parse(updateOrdersChannelMessage); expect(updateMessage.type).to.be.equal('update'); - expect(updateMessage.payload).to.be.deep.equal(orderResponse); + expect(updateMessage.payload).to.be.deep.equal([orderResponse]); }); it('returns unknown message for messages with unsupported types', () => { const unknownMessage = ordersChannelMessageParser.parse(unknownOrdersChannelMessage); @@ -29,9 +29,9 @@ describe('ordersChannelMessageParser', () => { }); it('throws when message does not include a type', () => { const typelessMessage = `{ - "channel": "orderbook", - "requestId": 1, - "payload": {} + "channel": "orders", + "requestId": "4d8efcee-adde-4475-9601-f0b30962ca2b", + "payload": [] }`; const badCall = () => ordersChannelMessageParser.parse(typelessMessage); expect(badCall).throws(`Message is missing a type parameter: ${typelessMessage}`); @@ -39,9 +39,9 @@ describe('ordersChannelMessageParser', () => { it('throws when type is not a string', () => { const messageWithBadType = `{ "type": 1, - "channel": "orderbook", - "requestId": 1, - "payload": {} + "channel": "orders", + "requestId": "4d8efcee-adde-4475-9601-f0b30962ca2b", + "payload": [] }`; const badCall = () => ordersChannelMessageParser.parse(messageWithBadType); expect(badCall).throws('Expected type to be of type string, encountered: 1'); @@ -53,7 +53,7 @@ describe('ordersChannelMessageParser', () => { it('throws when input message is not valid JSON', () => { const nonJsonString = 'h93b{sdfs9fsd f'; const badCall = () => ordersChannelMessageParser.parse(nonJsonString); - expect(badCall).throws('Unexpected assetData h in JSON at position 0'); + expect(badCall).throws('Unexpected token h in JSON at position 0'); }); }); }); diff --git a/packages/connect/test/ws_orderbook_channel_test.ts b/packages/connect/test/ws_orders_channel_test.ts index de097c295..98eb24e6e 100644 --- a/packages/connect/test/ws_orderbook_channel_test.ts +++ b/packages/connect/test/ws_orders_channel_test.ts @@ -11,18 +11,9 @@ chai.config.includeStack = true; chai.use(dirtyChai); const expect = chai.expect; const emptyOrdersChannelHandler = { - onSnapshot: () => { - _.noop(); - }, - onUpdate: () => { - _.noop(); - }, - onError: () => { - _.noop(); - }, - onClose: () => { - _.noop(); - }, + onUpdate: _.noop, + onError: _.noop, + onClose: _.noop, }; describe('WebSocketOrdersChannel', () => { @@ -34,15 +25,14 @@ describe('WebSocketOrdersChannel', () => { const subscriptionOpts = { baseAssetData: '0x323b5d4c32345ced77393b3530b1eed0f346429d', quoteAssetData: '0xef7fff64389b814a946f3e92105513705ca6b990', - snapshot: true, limit: 100, }; describe('#subscribe', () => { it('throws when subscriptionOpts does not conform to schema', () => { - const badSubscribeCall = openOrdersChannel.subscribe.bind(openOrdersChannel, {}); - expect(badSubscribeCall).throws( - 'Expected subscriptionOpts to conform to schema /RelayerApiOrdersChannelSubscribePayload\nEncountered: {}\nValidation errors: instance requires property "baseAssetData", instance requires property "quoteAssetData"', - ); + const badSubscribeCall = openOrdersChannel.subscribe.bind(openOrdersChannel, { + makerAssetData: 5, + }); + expect(badSubscribeCall).throws(); }); it('does not throw when inputs are of correct types', () => { const goodSubscribeCall = openOrdersChannel.subscribe.bind(openOrdersChannel, subscriptionOpts); |