aboutsummaryrefslogtreecommitdiffstats
path: root/packages/connect
diff options
context:
space:
mode:
authorBrandon Millman <brandon.millman@gmail.com>2018-08-24 01:52:09 +0800
committerBrandon Millman <brandon.millman@gmail.com>2018-08-24 01:52:09 +0800
commit7ad1a18a4aaa3da23fc013c55babea286a505f9d (patch)
treeae0e8267091b45dcdf661ec8cd76ce7699a82364 /packages/connect
parent572ad4615a3a0fa5649549cbd65eb912ea7a0e92 (diff)
parentb013cf2e145825a9e250c61bc77825384b2af69e (diff)
downloaddexon-sol-tools-7ad1a18a4aaa3da23fc013c55babea286a505f9d.tar
dexon-sol-tools-7ad1a18a4aaa3da23fc013c55babea286a505f9d.tar.gz
dexon-sol-tools-7ad1a18a4aaa3da23fc013c55babea286a505f9d.tar.bz2
dexon-sol-tools-7ad1a18a4aaa3da23fc013c55babea286a505f9d.tar.lz
dexon-sol-tools-7ad1a18a4aaa3da23fc013c55babea286a505f9d.tar.xz
dexon-sol-tools-7ad1a18a4aaa3da23fc013c55babea286a505f9d.tar.zst
dexon-sol-tools-7ad1a18a4aaa3da23fc013c55babea286a505f9d.zip
Merge branch 'development' into feature/forwarder-helper/init
* development: (31 commits) Update CI config to check development instead of v2-prototype branch fix: Make non-interactive npm login for publish tests more robust Run prettier Remove comment in updates json-schemas doc Add documentation for json-schemas Fix typo Remove artifacts Update variable names, make release candidate Update more names in docs Improve documentation Pin sra-report to 0xproject/connect v1.0.4 Run prettier lint everything Update websocket for SRA v2 Remove default query parameters Add networkId request param option Rename websocket files and types Use uuid as string for requestId Update changelogs Add fee recipients test ...
Diffstat (limited to 'packages/connect')
-rw-r--r--packages/connect/CHANGELOG.json9
-rw-r--r--packages/connect/package.json8
-rw-r--r--packages/connect/src/http_client.ts126
-rw-r--r--packages/connect/src/index.ts18
-rw-r--r--packages/connect/src/orderbook_channel_factory.ts32
-rw-r--r--packages/connect/src/orders_channel_factory.ts29
-rw-r--r--packages/connect/src/schemas/asset_pairs_request_opts_schema.ts8
-rw-r--r--packages/connect/src/schemas/fees_request_schema.ts26
-rw-r--r--packages/connect/src/schemas/order_config_request_schema.ts24
-rw-r--r--packages/connect/src/schemas/orderbook_request_schema.ts6
-rw-r--r--packages/connect/src/schemas/orders_request_opts_schema.ts23
-rw-r--r--packages/connect/src/schemas/request_opts_schema.ts7
-rw-r--r--packages/connect/src/schemas/schemas.ts10
-rw-r--r--packages/connect/src/schemas/token_pairs_request_opts_schema.ts8
-rw-r--r--packages/connect/src/types.ts168
-rw-r--r--packages/connect/src/utils/assert.ts7
-rw-r--r--packages/connect/src/utils/orderbook_channel_message_parser.ts43
-rw-r--r--packages/connect/src/utils/orders_channel_message_parser.ts37
-rw-r--r--packages/connect/src/utils/relayer_response_json_parsers.ts50
-rw-r--r--packages/connect/src/utils/type_converters.ts30
-rw-r--r--packages/connect/src/ws_orders_channel.ts (renamed from packages/connect/src/ws_orderbook_channel.ts)56
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/asset_pairs.json21
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/asset_pairs.ts25
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/fee_recipients.json10
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/fee_recipients.ts12
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/fees.json5
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/fees.ts9
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json34
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts32
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/order_config.json6
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/order_config.ts10
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/orderbook.json90
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/orderbook.ts94
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/orders.json45
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/orders.ts47
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/snapshot_orderbook_channel_message.ts17
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/token_pairs.json16
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/token_pairs.ts20
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/unknown_orders_channel_message.ts (renamed from packages/connect/test/fixtures/standard_relayer_api/unknown_orderbook_channel_message.ts)6
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/update_orderbook_channel_message.ts17
-rw-r--r--packages/connect/test/fixtures/standard_relayer_api/update_orders_channel_message.ts17
-rw-r--r--packages/connect/test/http_client_test.ts146
-rw-r--r--packages/connect/test/orderbook_channel_factory_test.ts45
-rw-r--r--packages/connect/test/orderbook_channel_message_parsers_test.ts76
-rw-r--r--packages/connect/test/orders_channel_factory_test.ts34
-rw-r--r--packages/connect/test/orders_channel_message_parsers_test.ts59
-rw-r--r--packages/connect/test/ws_orderbook_channel_test.ts59
-rw-r--r--packages/connect/test/ws_orders_channel_test.ts49
48 files changed, 918 insertions, 808 deletions
diff --git a/packages/connect/CHANGELOG.json b/packages/connect/CHANGELOG.json
index 8d6feaa2e..d7e026b4f 100644
--- a/packages/connect/CHANGELOG.json
+++ b/packages/connect/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "version": "2.0.0-rc.1",
+ "changes": [
+ {
+ "note": "Updated for SRA v2",
+ "pr": 974
+ }
+ ]
+ },
+ {
"timestamp": 1534210131,
"version": "1.0.5",
"changes": [
diff --git a/packages/connect/package.json b/packages/connect/package.json
index 8f2e423b5..ee08104cf 100644
--- a/packages/connect/package.json
+++ b/packages/connect/package.json
@@ -51,14 +51,15 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md",
"dependencies": {
- "@0xproject/assert": "^0.2.14",
- "@0xproject/json-schemas": "^0.8.3",
- "@0xproject/types": "^0.8.2",
+ "@0xproject/assert": "^1.0.5",
+ "@0xproject/json-schemas": "^1.0.1-rc.4",
+ "@0xproject/types": "^1.0.1-rc.4",
"@0xproject/typescript-typings": "^1.0.4",
"@0xproject/utils": "^1.0.5",
"lodash": "^4.17.5",
"query-string": "^5.0.1",
"sinon": "^4.0.0",
+ "uuid": "^3.3.2",
"websocket": "^1.0.25"
},
"devDependencies": {
@@ -69,6 +70,7 @@
"@types/mocha": "^2.2.42",
"@types/query-string": "^5.0.1",
"@types/sinon": "^2.2.2",
+ "@types/uuid": "^3.4.3",
"@types/websocket": "^0.0.39",
"async-child-process": "^1.1.1",
"chai": "^4.0.1",
diff --git a/packages/connect/src/http_client.ts b/packages/connect/src/http_client.ts
index 03cc590e4..b90c2c35f 100644
--- a/packages/connect/src/http_client.ts
+++ b/packages/connect/src/http_client.ts
@@ -7,31 +7,25 @@ import * as queryString from 'query-string';
import { schemas as clientSchemas } from './schemas/schemas';
import {
+ APIOrder,
+ AssetPairsRequestOpts,
+ AssetPairsResponse,
Client,
- FeesRequest,
- FeesResponse,
+ FeeRecipientsResponse,
HttpRequestOptions,
HttpRequestType,
OrderbookRequest,
OrderbookResponse,
+ OrderConfigRequest,
+ OrderConfigResponse,
OrdersRequestOpts,
+ OrdersResponse,
PagedRequestOpts,
- TokenPairsItem,
- TokenPairsRequestOpts,
+ RequestOpts,
} from './types';
import { relayerResponseJsonParsers } from './utils/relayer_response_json_parsers';
const TRAILING_SLASHES_REGEX = /\/+$/;
-const DEFAULT_PAGED_REQUEST_OPTS: PagedRequestOpts = {
- page: 1,
- perPage: 100,
-};
-/**
- * This mapping defines how an option property name gets converted into an HTTP request query field
- */
-const OPTS_TO_QUERY_FIELD_MAP = {
- perPage: 'per_page',
-};
/**
* This class includes all the functionality related to interacting with a set of HTTP endpoints
@@ -47,12 +41,8 @@ export class HttpClient implements Client {
if (_.isUndefined(params) || _.isEmpty(params)) {
return '';
}
- // format params into a form the api expects
- const formattedParams = _.mapKeys(params, (_value: any, key: string) => {
- return _.get(OPTS_TO_QUERY_FIELD_MAP, key, key);
- });
// stringify the formatted object
- const stringifiedParams = queryString.stringify(formattedParams);
+ const stringifiedParams = queryString.stringify(params);
return `?${stringifiedParams}`;
}
/**
@@ -65,34 +55,40 @@ export class HttpClient implements Client {
this._apiEndpointUrl = url.replace(TRAILING_SLASHES_REGEX, ''); // remove trailing slashes
}
/**
- * Retrieve token pair info from the API
- * @param requestOpts Options specifying token information to retrieve and page information, defaults to { page: 1, perPage: 100 }
- * @return The resulting TokenPairsItems that match the request
+ * Retrieve assetData pair info from the API
+ * @param requestOpts Options specifying assetData information to retrieve, page information, and network id.
+ * @return The resulting AssetPairsResponse that match the request
*/
- public async getTokenPairsAsync(requestOpts?: TokenPairsRequestOpts & PagedRequestOpts): Promise<TokenPairsItem[]> {
+ public async getAssetPairsAsync(
+ requestOpts?: RequestOpts & AssetPairsRequestOpts & PagedRequestOpts,
+ ): Promise<AssetPairsResponse> {
if (!_.isUndefined(requestOpts)) {
- assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.tokenPairsRequestOptsSchema);
+ assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.assetPairsRequestOptsSchema);
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
+ assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
}
const httpRequestOpts = {
- params: _.defaults({}, requestOpts, DEFAULT_PAGED_REQUEST_OPTS),
+ params: requestOpts,
};
- const responseJson = await this._requestAsync('/token_pairs', HttpRequestType.Get, httpRequestOpts);
- const tokenPairs = relayerResponseJsonParsers.parseTokenPairsJson(responseJson);
- return tokenPairs;
+ const responseJson = await this._requestAsync('/asset_pairs', HttpRequestType.Get, httpRequestOpts);
+ const assetDataPairs = relayerResponseJsonParsers.parseAssetDataPairsJson(responseJson);
+ return assetDataPairs;
}
/**
* Retrieve orders from the API
- * @param requestOpts Options specifying orders to retrieve and page information, defaults to { page: 1, perPage: 100 }
- * @return The resulting SignedOrders that match the request
+ * @param requestOpts Options specifying orders to retrieve and page information, page information, and network id.
+ * @return The resulting OrdersResponse that match the request
*/
- public async getOrdersAsync(requestOpts?: OrdersRequestOpts & PagedRequestOpts): Promise<SignedOrder[]> {
+ public async getOrdersAsync(
+ requestOpts?: RequestOpts & OrdersRequestOpts & PagedRequestOpts,
+ ): Promise<OrdersResponse> {
if (!_.isUndefined(requestOpts)) {
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.ordersRequestOptsSchema);
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
+ assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
}
const httpRequestOpts = {
- params: _.defaults({}, requestOpts, DEFAULT_PAGED_REQUEST_OPTS),
+ params: requestOpts,
};
const responseJson = await this._requestAsync(`/orders`, HttpRequestType.Get, httpRequestOpts);
const orders = relayerResponseJsonParsers.parseOrdersJson(responseJson);
@@ -101,30 +97,37 @@ export class HttpClient implements Client {
/**
* Retrieve a specific order from the API
* @param orderHash An orderHash generated from the desired order
- * @return The SignedOrder that matches the supplied orderHash
+ * @return The APIOrder that matches the supplied orderHash
*/
- public async getOrderAsync(orderHash: string): Promise<SignedOrder> {
+ public async getOrderAsync(orderHash: string, requestOpts?: RequestOpts): Promise<APIOrder> {
+ if (!_.isUndefined(requestOpts)) {
+ assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
+ }
assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
- const responseJson = await this._requestAsync(`/order/${orderHash}`, HttpRequestType.Get);
- const order = relayerResponseJsonParsers.parseOrderJson(responseJson);
+ const httpRequestOpts = {
+ params: requestOpts,
+ };
+ const responseJson = await this._requestAsync(`/order/${orderHash}`, HttpRequestType.Get, httpRequestOpts);
+ const order = relayerResponseJsonParsers.parseAPIOrderJson(responseJson);
return order;
}
/**
* Retrieve an orderbook from the API
* @param request An OrderbookRequest instance describing the specific orderbook to retrieve
- * @param requestOpts Options specifying page information, defaults to { page: 1, perPage: 100 }
+ * @param requestOpts Options specifying page information, and network id.
* @return The resulting OrderbookResponse that matches the request
*/
public async getOrderbookAsync(
request: OrderbookRequest,
- requestOpts?: PagedRequestOpts,
+ requestOpts?: RequestOpts & PagedRequestOpts,
): Promise<OrderbookResponse> {
assert.doesConformToSchema('request', request, clientSchemas.orderBookRequestSchema);
if (!_.isUndefined(requestOpts)) {
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
+ assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
}
const httpRequestOpts = {
- params: _.defaults({}, request, requestOpts, DEFAULT_PAGED_REQUEST_OPTS),
+ params: _.defaults({}, request, requestOpts),
};
const responseJson = await this._requestAsync('/orderbook', HttpRequestType.Get, httpRequestOpts);
const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(responseJson);
@@ -132,28 +135,55 @@ export class HttpClient implements Client {
}
/**
* Retrieve fee information from the API
- * @param request A FeesRequest instance describing the specific fees to retrieve
- * @return The resulting FeesResponse that matches the request
+ * @param request A OrderConfigRequest instance describing the specific fees to retrieve
+ * @param requestOpts Options specifying network id.
+ * @return The resulting OrderConfigResponse that matches the request
*/
- public async getFeesAsync(request: FeesRequest): Promise<FeesResponse> {
- assert.doesConformToSchema('request', request, clientSchemas.feesRequestSchema);
+ public async getOrderConfigAsync(
+ request: OrderConfigRequest,
+ requestOpts?: RequestOpts,
+ ): Promise<OrderConfigResponse> {
+ if (!_.isUndefined(requestOpts)) {
+ assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
+ }
+ assert.doesConformToSchema('request', request, clientSchemas.orderConfigRequestSchema);
const httpRequestOpts = {
+ params: requestOpts,
payload: request,
};
- const responseJson = await this._requestAsync('/fees', HttpRequestType.Post, httpRequestOpts);
- const fees = relayerResponseJsonParsers.parseFeesResponseJson(responseJson);
+ const responseJson = await this._requestAsync('/order_config', HttpRequestType.Post, httpRequestOpts);
+ const fees = relayerResponseJsonParsers.parseOrderConfigResponseJson(responseJson);
return fees;
}
/**
+ * Retrieve the list of fee recipient addresses used by the relayer.
+ * @param requestOpts Options specifying page information, and network id.
+ * @return The resulting FeeRecipientsResponse
+ */
+ public async getFeeRecipientsAsync(requestOpts?: RequestOpts & PagedRequestOpts): Promise<FeeRecipientsResponse> {
+ if (!_.isUndefined(requestOpts)) {
+ assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
+ assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
+ }
+ const httpRequestOpts = {
+ params: requestOpts,
+ };
+ const feeRecipients = await this._requestAsync('/fee_recipients', HttpRequestType.Get, httpRequestOpts);
+ assert.doesConformToSchema('feeRecipients', feeRecipients, schemas.relayerApiFeeRecipientsResponseSchema);
+ return feeRecipients;
+ }
+ /**
* Submit a signed order to the API
* @param signedOrder A SignedOrder instance to submit
+ * @param requestOpts Options specifying network id.
*/
- public async submitOrderAsync(signedOrder: SignedOrder): Promise<void> {
+ public async submitOrderAsync(signedOrder: SignedOrder, requestOpts?: RequestOpts): Promise<void> {
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
- const requestOpts = {
+ const httpRequestOpts = {
+ params: requestOpts,
payload: signedOrder,
};
- await this._requestAsync('/order', HttpRequestType.Post, requestOpts);
+ await this._requestAsync('/order', HttpRequestType.Post, httpRequestOpts);
}
private async _requestAsync(
path: string,
diff --git a/packages/connect/src/index.ts b/packages/connect/src/index.ts
index 7f5eb8ed3..33e1222b0 100644
--- a/packages/connect/src/index.ts
+++ b/packages/connect/src/index.ts
@@ -1,19 +1,19 @@
export { HttpClient } from './http_client';
-export { orderbookChannelFactory } from './orderbook_channel_factory';
+export { ordersChannelFactory } from './orders_channel_factory';
export {
Client,
- FeesRequest,
- FeesResponse,
- OrderbookChannel,
- OrderbookChannelHandler,
- OrderbookChannelSubscriptionOpts,
+ OrderConfigRequest,
+ OrderConfigResponse,
+ OrdersChannel,
+ OrdersChannelHandler,
+ OrdersChannelSubscriptionOpts,
OrderbookRequest,
OrderbookResponse,
OrdersRequestOpts,
PagedRequestOpts,
- TokenPairsItem,
- TokenPairsRequestOpts,
- TokenTradeInfo,
+ AssetPairsItem,
+ AssetPairsRequestOpts,
+ Asset,
} from './types';
export { Order, SignedOrder } from '@0xproject/types';
diff --git a/packages/connect/src/orderbook_channel_factory.ts b/packages/connect/src/orderbook_channel_factory.ts
deleted file mode 100644
index 5134af323..000000000
--- a/packages/connect/src/orderbook_channel_factory.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import * as WebSocket from 'websocket';
-
-import { OrderbookChannel, OrderbookChannelHandler } from './types';
-import { assert } from './utils/assert';
-import { WebSocketOrderbookChannel } from './ws_orderbook_channel';
-
-export const orderbookChannelFactory = {
- /**
- * Instantiates a new WebSocketOrderbookChannel instance
- * @param url The relayer API base WS url you would like to interact with
- * @param handler An OrderbookChannelHandler instance that responds to various
- * channel updates
- * @return An OrderbookChannel Promise
- */
- async createWebSocketOrderbookChannelAsync(
- url: string,
- handler: OrderbookChannelHandler,
- ): Promise<OrderbookChannel> {
- assert.isUri('url', url);
- assert.isOrderbookChannelHandler('handler', handler);
- return new Promise<OrderbookChannel>((resolve, reject) => {
- const client = new WebSocket.w3cwebsocket(url);
- client.onopen = () => {
- const orderbookChannel = new WebSocketOrderbookChannel(client, handler);
- resolve(orderbookChannel);
- };
- client.onerror = err => {
- reject(err);
- };
- });
- },
-};
diff --git a/packages/connect/src/orders_channel_factory.ts b/packages/connect/src/orders_channel_factory.ts
new file mode 100644
index 000000000..5986d2a77
--- /dev/null
+++ b/packages/connect/src/orders_channel_factory.ts
@@ -0,0 +1,29 @@
+import * as WebSocket from 'websocket';
+
+import { OrdersChannel, OrdersChannelHandler } from './types';
+import { assert } from './utils/assert';
+import { WebSocketOrdersChannel } from './ws_orders_channel';
+
+export const ordersChannelFactory = {
+ /**
+ * Instantiates a new WebSocketOrdersChannel instance
+ * @param url The relayer API base WS url you would like to interact with
+ * @param handler An OrdersChannelHandler instance that responds to various
+ * channel updates
+ * @return An OrdersChannel Promise
+ */
+ async createWebSocketOrdersChannelAsync(url: string, handler: OrdersChannelHandler): Promise<OrdersChannel> {
+ assert.isUri('url', url);
+ assert.isOrdersChannelHandler('handler', handler);
+ return new Promise<OrdersChannel>((resolve, reject) => {
+ const client = new WebSocket.w3cwebsocket(url);
+ client.onopen = () => {
+ const ordersChannel = new WebSocketOrdersChannel(client, handler);
+ resolve(ordersChannel);
+ };
+ client.onerror = err => {
+ reject(err);
+ };
+ });
+ },
+};
diff --git a/packages/connect/src/schemas/asset_pairs_request_opts_schema.ts b/packages/connect/src/schemas/asset_pairs_request_opts_schema.ts
new file mode 100644
index 000000000..a9e3942a4
--- /dev/null
+++ b/packages/connect/src/schemas/asset_pairs_request_opts_schema.ts
@@ -0,0 +1,8 @@
+export const assetPairsRequestOptsSchema = {
+ id: '/AssetPairsRequestOpts',
+ type: 'object',
+ properties: {
+ assetDataA: { $ref: '/hexSchema' },
+ assetDataB: { $ref: '/hexSchema' },
+ },
+};
diff --git a/packages/connect/src/schemas/fees_request_schema.ts b/packages/connect/src/schemas/fees_request_schema.ts
deleted file mode 100644
index ff3d7b9d3..000000000
--- a/packages/connect/src/schemas/fees_request_schema.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-export const feesRequestSchema = {
- id: '/FeesRequest',
- type: 'object',
- properties: {
- exchangeContractAddress: { $ref: '/Address' },
- maker: { $ref: '/Address' },
- taker: { $ref: '/Address' },
- makerTokenAddress: { $ref: '/Address' },
- takerTokenAddress: { $ref: '/Address' },
- makerTokenAmount: { $ref: '/Number' },
- takerTokenAmount: { $ref: '/Number' },
- expirationUnixTimestampSec: { $ref: '/Number' },
- salt: { $ref: '/Number' },
- },
- required: [
- 'exchangeContractAddress',
- 'maker',
- 'taker',
- 'makerTokenAddress',
- 'takerTokenAddress',
- 'makerTokenAmount',
- 'takerTokenAmount',
- 'expirationUnixTimestampSec',
- 'salt',
- ],
-};
diff --git a/packages/connect/src/schemas/order_config_request_schema.ts b/packages/connect/src/schemas/order_config_request_schema.ts
new file mode 100644
index 000000000..0eda430e8
--- /dev/null
+++ b/packages/connect/src/schemas/order_config_request_schema.ts
@@ -0,0 +1,24 @@
+export const orderConfigRequestSchema = {
+ id: '/OrderConfigRequest',
+ type: 'object',
+ properties: {
+ makerAddress: { $ref: '/addressSchema' },
+ takerAddress: { $ref: '/addressSchema' },
+ makerAssetAmount: { $ref: '/numberSchema' },
+ takerAssetAmount: { $ref: '/numberSchema' },
+ makerAssetData: { $ref: '/hexSchema' },
+ takerAssetData: { $ref: '/hexSchema' },
+ exchangeAddress: { $ref: '/addressSchema' },
+ expirationTimeSeconds: { $ref: '/numberSchema' },
+ },
+ required: [
+ 'makerAddress',
+ 'takerAddress',
+ 'makerAssetAmount',
+ 'takerAssetAmount',
+ 'makerAssetData',
+ 'takerAssetData',
+ 'exchangeAddress',
+ 'expirationTimeSeconds',
+ ],
+};
diff --git a/packages/connect/src/schemas/orderbook_request_schema.ts b/packages/connect/src/schemas/orderbook_request_schema.ts
index 5f3463242..0c9389d50 100644
--- a/packages/connect/src/schemas/orderbook_request_schema.ts
+++ b/packages/connect/src/schemas/orderbook_request_schema.ts
@@ -2,8 +2,8 @@ export const orderBookRequestSchema = {
id: '/OrderBookRequest',
type: 'object',
properties: {
- baseTokenAddress: { $ref: '/Address' },
- quoteTokenAddress: { $ref: '/Address' },
+ baseAssetData: { $ref: '/hexSchema' },
+ quoteAssetData: { $ref: '/hexSchema' },
},
- required: ['baseTokenAddress', 'quoteTokenAddress'],
+ required: ['baseAssetData', 'quoteAssetData'],
};
diff --git a/packages/connect/src/schemas/orders_request_opts_schema.ts b/packages/connect/src/schemas/orders_request_opts_schema.ts
index 5facbc959..71ce3d06f 100644
--- a/packages/connect/src/schemas/orders_request_opts_schema.ts
+++ b/packages/connect/src/schemas/orders_request_opts_schema.ts
@@ -2,15 +2,18 @@ export const ordersRequestOptsSchema = {
id: '/OrdersRequestOpts',
type: 'object',
properties: {
- exchangeContractAddress: { $ref: '/Address' },
- tokenAddress: { $ref: '/Address' },
- makerTokenAddress: { $ref: '/Address' },
- takerTokenAddress: { $ref: '/Address' },
- tokenA: { $ref: '/Address' },
- tokenB: { $ref: '/Address' },
- maker: { $ref: '/Address' },
- taker: { $ref: '/Address' },
- trader: { $ref: '/Address' },
- feeRecipient: { $ref: '/Address' },
+ makerAssetProxyId: { $ref: '/hexSchema' },
+ takerAssetProxyId: { $ref: '/hexSchema' },
+ makerAssetAddress: { $ref: '/addressSchema' },
+ takerAssetAddress: { $ref: '/addressSchema' },
+ exchangeAddress: { $ref: '/addressSchema' },
+ senderAddress: { $ref: '/addressSchema' },
+ makerAssetData: { $ref: '/hexSchema' },
+ takerAssetData: { $ref: '/hexSchema' },
+ traderAssetData: { $ref: '/hexSchema' },
+ makerAddress: { $ref: '/addressSchema' },
+ takerAddress: { $ref: '/addressSchema' },
+ traderAddress: { $ref: '/addressSchema' },
+ feeRecipientAddress: { $ref: '/addressSchema' },
},
};
diff --git a/packages/connect/src/schemas/request_opts_schema.ts b/packages/connect/src/schemas/request_opts_schema.ts
new file mode 100644
index 000000000..a51e98069
--- /dev/null
+++ b/packages/connect/src/schemas/request_opts_schema.ts
@@ -0,0 +1,7 @@
+export const requestOptsSchema = {
+ id: '/RequestOpts',
+ type: 'object',
+ properties: {
+ networkId: { type: 'number' },
+ },
+};
diff --git a/packages/connect/src/schemas/schemas.ts b/packages/connect/src/schemas/schemas.ts
index 0b8b798a9..8d101ed6f 100644
--- a/packages/connect/src/schemas/schemas.ts
+++ b/packages/connect/src/schemas/schemas.ts
@@ -1,13 +1,15 @@
-import { feesRequestSchema } from './fees_request_schema';
+import { assetPairsRequestOptsSchema } from './asset_pairs_request_opts_schema';
+import { orderConfigRequestSchema } from './order_config_request_schema';
import { orderBookRequestSchema } from './orderbook_request_schema';
import { ordersRequestOptsSchema } from './orders_request_opts_schema';
import { pagedRequestOptsSchema } from './paged_request_opts_schema';
-import { tokenPairsRequestOptsSchema } from './token_pairs_request_opts_schema';
+import { requestOptsSchema } from './request_opts_schema';
export const schemas = {
- feesRequestSchema,
+ orderConfigRequestSchema,
orderBookRequestSchema,
ordersRequestOptsSchema,
pagedRequestOptsSchema,
- tokenPairsRequestOptsSchema,
+ requestOptsSchema,
+ assetPairsRequestOptsSchema,
};
diff --git a/packages/connect/src/schemas/token_pairs_request_opts_schema.ts b/packages/connect/src/schemas/token_pairs_request_opts_schema.ts
deleted file mode 100644
index 9b73a917b..000000000
--- a/packages/connect/src/schemas/token_pairs_request_opts_schema.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export const tokenPairsRequestOptsSchema = {
- id: '/TokenPairsRequestOpts',
- type: 'object',
- properties: {
- tokenA: { $ref: '/Address' },
- tokenB: { $ref: '/Address' },
- },
-};
diff --git a/packages/connect/src/types.ts b/packages/connect/src/types.ts
index fc7a4b24d..06ae732a5 100644
--- a/packages/connect/src/types.ts
+++ b/packages/connect/src/types.ts
@@ -2,73 +2,55 @@ import { SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
export interface Client {
- getTokenPairsAsync: (requestOpts?: TokenPairsRequestOpts & PagedRequestOpts) => Promise<TokenPairsItem[]>;
- getOrdersAsync: (requestOpts?: OrdersRequestOpts & PagedRequestOpts) => Promise<SignedOrder[]>;
- getOrderAsync: (orderHash: string) => Promise<SignedOrder>;
+ getAssetPairsAsync: (
+ requestOpts?: AssetPairsRequestOpts & PagedRequestOpts,
+ ) => Promise<PaginatedCollection<AssetPairsItem>>;
+ getOrdersAsync: (requestOpts?: OrdersRequestOpts & PagedRequestOpts) => Promise<PaginatedCollection<APIOrder>>;
+ getOrderAsync: (orderHash: string) => Promise<APIOrder>;
getOrderbookAsync: (request: OrderbookRequest, requestOpts?: PagedRequestOpts) => Promise<OrderbookResponse>;
- getFeesAsync: (request: FeesRequest) => Promise<FeesResponse>;
+ getOrderConfigAsync: (request: OrderConfigRequest) => Promise<OrderConfigResponse>;
+ getFeeRecipientsAsync: (requestOpts?: PagedRequestOpts) => Promise<FeeRecipientsResponse>;
submitOrderAsync: (signedOrder: SignedOrder) => Promise<void>;
}
-export interface OrderbookChannel {
- subscribe: (subscriptionOpts: OrderbookChannelSubscriptionOpts) => void;
+export interface OrdersChannel {
+ subscribe: (subscriptionOpts: OrdersChannelSubscriptionOpts) => void;
close: () => void;
}
/**
- * baseTokenAddress: The address of token designated as the baseToken in the currency pair calculation of price
- * quoteTokenAddress: The address of token designated as the quoteToken in the currency pair calculation of price
- * snapshot: If true, a snapshot of the orderbook will be sent before the updates to the orderbook
+ * baseAssetData: The address of assetData designated as the baseToken in the currency pair calculation of price
+ * quoteAssetData: The address of assetData designated as the quoteToken in the currency pair calculation of price
* limit: Maximum number of bids and asks in orderbook snapshot
*/
-export interface OrderbookChannelSubscriptionOpts {
- baseTokenAddress: string;
- quoteTokenAddress: string;
- snapshot: boolean;
+export interface OrdersChannelSubscriptionOpts {
+ baseAssetData: string;
+ quoteAssetData: string;
limit: number;
}
-export interface OrderbookChannelHandler {
- onSnapshot: (
- channel: OrderbookChannel,
- subscriptionOpts: OrderbookChannelSubscriptionOpts,
- snapshot: OrderbookResponse,
- ) => void;
- onUpdate: (
- channel: OrderbookChannel,
- subscriptionOpts: OrderbookChannelSubscriptionOpts,
- order: SignedOrder,
- ) => void;
- onError: (channel: OrderbookChannel, err: Error, subscriptionOpts?: OrderbookChannelSubscriptionOpts) => void;
- onClose: (channel: OrderbookChannel) => void;
-}
-
-export type OrderbookChannelMessage =
- | SnapshotOrderbookChannelMessage
- | UpdateOrderbookChannelMessage
- | UnknownOrderbookChannelMessage;
-
-export enum OrderbookChannelMessageTypes {
- Snapshot = 'snapshot',
- Update = 'update',
- Unknown = 'unknown',
+export interface OrdersChannelHandler {
+ onUpdate: (channel: OrdersChannel, subscriptionOpts: OrdersChannelSubscriptionOpts, orders: APIOrder[]) => void;
+ onError: (channel: OrdersChannel, err: Error, subscriptionOpts?: OrdersChannelSubscriptionOpts) => void;
+ onClose: (channel: OrdersChannel) => void;
}
-export interface SnapshotOrderbookChannelMessage {
- type: OrderbookChannelMessageTypes.Snapshot;
- requestId: number;
- payload: OrderbookResponse;
+export type OrdersChannelMessage = UpdateOrdersChannelMessage | UnknownOrdersChannelMessage;
+
+export enum OrdersChannelMessageTypes {
+ Update = 'update',
+ Unknown = 'unknown',
}
-export interface UpdateOrderbookChannelMessage {
- type: OrderbookChannelMessageTypes.Update;
- requestId: number;
- payload: SignedOrder;
+export interface UpdateOrdersChannelMessage {
+ type: OrdersChannelMessageTypes.Update;
+ requestId: string;
+ payload: APIOrder[];
}
-export interface UnknownOrderbookChannelMessage {
- type: OrderbookChannelMessageTypes.Unknown;
- requestId: number;
+export interface UnknownOrdersChannelMessage {
+ type: OrdersChannelMessageTypes.Unknown;
+ requestId: string;
payload: undefined;
}
@@ -83,60 +65,86 @@ export enum WebsocketClientEventType {
ConnectFailed = 'connectFailed',
}
-export interface TokenPairsRequestOpts {
- tokenA?: string;
- tokenB?: string;
+export type OrdersResponse = PaginatedCollection<APIOrder>;
+
+export interface APIOrder {
+ order: SignedOrder;
+ metaData: object;
+}
+
+export interface AssetPairsRequestOpts {
+ assetDataA?: string;
+ assetDataB?: string;
}
-export interface TokenPairsItem {
- tokenA: TokenTradeInfo;
- tokenB: TokenTradeInfo;
+export type AssetPairsResponse = PaginatedCollection<AssetPairsItem>;
+
+export interface AssetPairsItem {
+ assetDataA: Asset;
+ assetDataB: Asset;
}
-export interface TokenTradeInfo {
- address: string;
+export interface Asset {
+ assetData: string;
minAmount: BigNumber;
maxAmount: BigNumber;
precision: number;
}
export interface OrdersRequestOpts {
- exchangeContractAddress?: string;
- tokenAddress?: string;
- makerTokenAddress?: string;
- takerTokenAddress?: string;
- maker?: string;
- taker?: string;
- trader?: string;
- feeRecipient?: string;
+ makerAssetProxyId?: string;
+ takerAssetProxyId?: string;
+ makerAssetAddress?: string;
+ takerAssetAddress?: string;
+ exchangeAddress?: string;
+ senderAddress?: string;
+ makerAssetData?: string;
+ takerAssetData?: string;
+ makerAddress?: string;
+ takerAddress?: string;
+ traderAddress?: string;
+ feeRecipientAddress?: string;
}
export interface OrderbookRequest {
- baseTokenAddress: string;
- quoteTokenAddress: string;
+ baseAssetData: string;
+ quoteAssetData: string;
}
export interface OrderbookResponse {
- bids: SignedOrder[];
- asks: SignedOrder[];
+ bids: PaginatedCollection<APIOrder>;
+ asks: PaginatedCollection<APIOrder>;
+}
+
+export interface PaginatedCollection<T> {
+ total: number;
+ page: number;
+ perPage: number;
+ records: T[];
}
-export interface FeesRequest {
- exchangeContractAddress: string;
- maker: string;
- taker: string;
- makerTokenAddress: string;
- takerTokenAddress: string;
- makerTokenAmount: BigNumber;
- takerTokenAmount: BigNumber;
- expirationUnixTimestampSec: BigNumber;
- salt: BigNumber;
+export interface OrderConfigRequest {
+ makerAddress: string;
+ takerAddress: string;
+ makerAssetAmount: string;
+ takerAssetAmount: string;
+ makerAssetData: string;
+ takerAssetData: string;
+ exchangeAddress: string;
+ expirationTimeSeconds: string;
}
-export interface FeesResponse {
- feeRecipient: string;
+export interface OrderConfigResponse {
makerFee: BigNumber;
takerFee: BigNumber;
+ feeRecipientAddress: string;
+ senderAddress: string;
+}
+
+export type FeeRecipientsResponse = PaginatedCollection<string>;
+
+export interface RequestOpts {
+ networkId?: number;
}
export interface PagedRequestOpts {
diff --git a/packages/connect/src/utils/assert.ts b/packages/connect/src/utils/assert.ts
index a0fd12fbd..3d8f1c799 100644
--- a/packages/connect/src/utils/assert.ts
+++ b/packages/connect/src/utils/assert.ts
@@ -10,15 +10,14 @@ import * as _ from 'lodash';
export const assert = {
...sharedAssert,
- isOrderbookChannelSubscriptionOpts(variableName: string, subscriptionOpts: any): void {
+ isOrdersChannelSubscriptionOpts(variableName: string, subscriptionOpts: any): void {
sharedAssert.doesConformToSchema(
variableName,
subscriptionOpts,
- schemas.relayerApiOrderbookChannelSubscribePayload,
+ schemas.relayerApiOrdersChannelSubscribePayload,
);
},
- isOrderbookChannelHandler(variableName: string, handler: any): void {
- sharedAssert.isFunction(`${variableName}.onSnapshot`, _.get(handler, 'onSnapshot'));
+ isOrdersChannelHandler(variableName: string, handler: any): void {
sharedAssert.isFunction(`${variableName}.onUpdate`, _.get(handler, 'onUpdate'));
sharedAssert.isFunction(`${variableName}.onError`, _.get(handler, 'onError'));
sharedAssert.isFunction(`${variableName}.onClose`, _.get(handler, 'onClose'));
diff --git a/packages/connect/src/utils/orderbook_channel_message_parser.ts b/packages/connect/src/utils/orderbook_channel_message_parser.ts
deleted file mode 100644
index 593288078..000000000
--- a/packages/connect/src/utils/orderbook_channel_message_parser.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { assert } from '@0xproject/assert';
-import { schemas } from '@0xproject/json-schemas';
-import * as _ from 'lodash';
-
-import { OrderbookChannelMessage, OrderbookChannelMessageTypes } from '../types';
-
-import { relayerResponseJsonParsers } from './relayer_response_json_parsers';
-
-export const orderbookChannelMessageParser = {
- parse(utf8Data: string): OrderbookChannelMessage {
- // parse the message
- const messageObj = JSON.parse(utf8Data);
- // ensure we have a type parameter to switch on
- const type: string = _.get(messageObj, 'type');
- 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');
- assert.assert(!_.isUndefined(requestId), `Message is missing a requestId parameter: ${utf8Data}`);
- assert.isNumber('requestId', requestId);
- switch (type) {
- case OrderbookChannelMessageTypes.Snapshot: {
- assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelSnapshotSchema);
- const orderbookJson = messageObj.payload;
- const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(orderbookJson);
- return _.assign(messageObj, { payload: orderbook });
- }
- case OrderbookChannelMessageTypes.Update: {
- assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelUpdateSchema);
- const orderJson = messageObj.payload;
- const order = relayerResponseJsonParsers.parseOrderJson(orderJson);
- return _.assign(messageObj, { payload: order });
- }
- default: {
- return {
- type: OrderbookChannelMessageTypes.Unknown,
- requestId,
- payload: undefined,
- };
- }
- }
- },
-};
diff --git a/packages/connect/src/utils/orders_channel_message_parser.ts b/packages/connect/src/utils/orders_channel_message_parser.ts
new file mode 100644
index 000000000..1b6cda17b
--- /dev/null
+++ b/packages/connect/src/utils/orders_channel_message_parser.ts
@@ -0,0 +1,37 @@
+import { assert } from '@0xproject/assert';
+import { schemas } from '@0xproject/json-schemas';
+import * as _ from 'lodash';
+
+import { OrdersChannelMessage, OrdersChannelMessageTypes } from '../types';
+
+import { relayerResponseJsonParsers } from './relayer_response_json_parsers';
+
+export const ordersChannelMessageParser = {
+ parse(utf8Data: string): OrdersChannelMessage {
+ // parse the message
+ const messageObj = JSON.parse(utf8Data);
+ // ensure we have a type parameter to switch on
+ const type: string = _.get(messageObj, 'type');
+ 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: string = _.get(messageObj, 'requestId');
+ assert.assert(!_.isUndefined(requestId), `Message is missing a requestId parameter: ${utf8Data}`);
+ assert.isString('requestId', requestId);
+ switch (type) {
+ case OrdersChannelMessageTypes.Update: {
+ assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrdersChannelUpdateSchema);
+ const ordersJson = messageObj.payload;
+ const orders = relayerResponseJsonParsers.parseAPIOrdersJson(ordersJson);
+ return _.assign(messageObj, { payload: orders });
+ }
+ default: {
+ return {
+ type: OrdersChannelMessageTypes.Unknown,
+ requestId,
+ payload: undefined,
+ };
+ }
+ }
+ },
+};
diff --git a/packages/connect/src/utils/relayer_response_json_parsers.ts b/packages/connect/src/utils/relayer_response_json_parsers.ts
index ccae8b115..ebd877b70 100644
--- a/packages/connect/src/utils/relayer_response_json_parsers.ts
+++ b/packages/connect/src/utils/relayer_response_json_parsers.ts
@@ -1,37 +1,49 @@
import { assert } from '@0xproject/assert';
import { schemas } from '@0xproject/json-schemas';
-import { SignedOrder } from '@0xproject/types';
-import { FeesResponse, OrderbookResponse, TokenPairsItem } from '../types';
+import {
+ APIOrder,
+ AssetPairsItem,
+ AssetPairsResponse,
+ OrderbookResponse,
+ OrderConfigResponse,
+ OrdersResponse,
+} from '../types';
import { typeConverters } from './type_converters';
export const relayerResponseJsonParsers = {
- parseTokenPairsJson(json: any): TokenPairsItem[] {
- assert.doesConformToSchema('tokenPairs', json, schemas.relayerApiTokenPairsResponseSchema);
- return json.map((tokenPair: any) => {
- return typeConverters.convertStringsFieldsToBigNumbers(tokenPair, [
- 'tokenA.minAmount',
- 'tokenA.maxAmount',
- 'tokenB.minAmount',
- 'tokenB.maxAmount',
+ parseAssetDataPairsJson(json: any): AssetPairsResponse {
+ assert.doesConformToSchema('assetDataPairsResponse', json, schemas.relayerApiAssetDataPairsResponseSchema);
+ return { ...json, records: relayerResponseJsonParsers.parseAssetPairsItemsJson(json.records) };
+ },
+ parseAssetPairsItemsJson(json: any): AssetPairsItem[] {
+ return json.map((assetDataPair: any) => {
+ return typeConverters.convertStringsFieldsToBigNumbers(assetDataPair, [
+ 'assetDataA.minAmount',
+ 'assetDataA.maxAmount',
+ 'assetDataB.minAmount',
+ 'assetDataB.maxAmount',
]);
});
},
- parseOrdersJson(json: any): SignedOrder[] {
- assert.doesConformToSchema('orders', json, schemas.signedOrdersSchema);
- return json.map((order: object) => typeConverters.convertOrderStringFieldsToBigNumber(order));
+ parseOrdersJson(json: any): OrdersResponse {
+ assert.doesConformToSchema('relayerApiOrdersResponse', json, schemas.relayerApiOrdersResponseSchema);
+ return { ...json, records: relayerResponseJsonParsers.parseAPIOrdersJson(json.records) };
+ },
+ parseAPIOrdersJson(json: any): APIOrder[] {
+ return json.map(relayerResponseJsonParsers.parseAPIOrderJson.bind(relayerResponseJsonParsers));
},
- parseOrderJson(json: any): SignedOrder {
- assert.doesConformToSchema('order', json, schemas.signedOrderSchema);
- return typeConverters.convertOrderStringFieldsToBigNumber(json);
+ parseAPIOrderJson(json: any): APIOrder {
+ assert.doesConformToSchema('relayerApiOrder', json, schemas.relayerApiOrderSchema);
+ return typeConverters.convertAPIOrderStringFieldsToBigNumber(json);
},
parseOrderbookResponseJson(json: any): OrderbookResponse {
- assert.doesConformToSchema('orderBook', json, schemas.relayerApiOrderBookResponseSchema);
+ assert.doesConformToSchema('orderBookResponse', json, schemas.relayerApiOrderbookResponseSchema);
return typeConverters.convertOrderbookStringFieldsToBigNumber(json);
},
- parseFeesResponseJson(json: any): FeesResponse {
- assert.doesConformToSchema('fees', json, schemas.relayerApiFeesResponseSchema);
+ parseOrderConfigResponseJson(json: any): OrderConfigResponse {
+ assert.doesConformToSchema('orderConfigResponse', json, schemas.relayerApiOrderConfigResponseSchema);
return typeConverters.convertStringsFieldsToBigNumbers(json, ['makerFee', 'takerFee']);
},
};
diff --git a/packages/connect/src/utils/type_converters.ts b/packages/connect/src/utils/type_converters.ts
index 210d452b9..4b211a0b2 100644
--- a/packages/connect/src/utils/type_converters.ts
+++ b/packages/connect/src/utils/type_converters.ts
@@ -1,29 +1,47 @@
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
+import { APIOrder } from '../types';
+
export const typeConverters = {
convertOrderbookStringFieldsToBigNumber(orderbook: any): any {
const bids = _.get(orderbook, 'bids', []);
const asks = _.get(orderbook, 'asks', []);
+ const convertedBids = {
+ ...bids,
+ records: bids.records.map((order: any) => typeConverters.convertAPIOrderStringFieldsToBigNumber(order)),
+ };
+ const convertedAsks = {
+ ...asks,
+ records: asks.records.map((order: any) => typeConverters.convertAPIOrderStringFieldsToBigNumber(order)),
+ };
return {
- bids: bids.map((order: any) => typeConverters.convertOrderStringFieldsToBigNumber(order)),
- asks: asks.map((order: any) => typeConverters.convertOrderStringFieldsToBigNumber(order)),
+ bids: convertedBids,
+ asks: convertedAsks,
};
},
+ convertAPIOrderStringFieldsToBigNumber(apiOrder: any): APIOrder {
+ return { ...apiOrder, order: typeConverters.convertOrderStringFieldsToBigNumber(apiOrder.order) };
+ },
convertOrderStringFieldsToBigNumber(order: any): any {
return typeConverters.convertStringsFieldsToBigNumbers(order, [
- 'makerTokenAmount',
- 'takerTokenAmount',
+ 'makerAssetAmount',
+ 'takerAssetAmount',
'makerFee',
'takerFee',
- 'expirationUnixTimestampSec',
+ 'expirationTimeSeconds',
'salt',
]);
},
convertStringsFieldsToBigNumbers(obj: any, fields: string[]): any {
const result = _.assign({}, obj);
_.each(fields, field => {
- _.update(result, field, (value: string) => new BigNumber(value));
+ _.update(result, field, (value: string) => {
+ if (_.isUndefined(value)) {
+ throw new Error(`Could not find field '${field}' while converting string fields to BigNumber.`);
+ }
+ return new BigNumber(value);
+ });
});
return result;
},
diff --git a/packages/connect/src/ws_orderbook_channel.ts b/packages/connect/src/ws_orders_channel.ts
index fa9f5e37f..cde4acbc3 100644
--- a/packages/connect/src/ws_orderbook_channel.ts
+++ b/packages/connect/src/ws_orders_channel.ts
@@ -1,32 +1,32 @@
import * as _ from 'lodash';
+import { v4 as uuid } from 'uuid';
import * as WebSocket from 'websocket';
-import {
- OrderbookChannel,
- OrderbookChannelHandler,
- OrderbookChannelMessageTypes,
- OrderbookChannelSubscriptionOpts,
-} from './types';
+import { OrdersChannel, OrdersChannelHandler, OrdersChannelMessageTypes, OrdersChannelSubscriptionOpts } from './types';
import { assert } from './utils/assert';
-import { orderbookChannelMessageParser } 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
* that implements the standard relayer API v0
*/
-export class WebSocketOrderbookChannel implements OrderbookChannel {
+export class WebSocketOrdersChannel implements OrdersChannel {
private readonly _client: WebSocket.w3cwebsocket;
- private readonly _handler: OrderbookChannelHandler;
- private readonly _subscriptionOptsList: OrderbookChannelSubscriptionOpts[] = [];
+ private readonly _handler: OrdersChannelHandler;
+ private readonly _subscriptionOptsMap: OrdersChannelSubscriptionOptsMap = {};
/**
- * Instantiates a new WebSocketOrderbookChannel instance
+ * Instantiates a new WebSocketOrdersChannel instance
* @param client A WebSocket client
- * @param handler An OrderbookChannelHandler instance that responds to various
+ * @param handler An OrdersChannelHandler instance that responds to various
* channel updates
- * @return An instance of WebSocketOrderbookChannel
+ * @return An instance of WebSocketOrdersChannel
*/
- constructor(client: WebSocket.w3cwebsocket, handler: OrderbookChannelHandler) {
- assert.isOrderbookChannelHandler('handler', handler);
+ constructor(client: WebSocket.w3cwebsocket, handler: OrdersChannelHandler) {
+ assert.isOrdersChannelHandler('handler', handler);
// set private members
this._client = client;
this._handler = handler;
@@ -43,18 +43,18 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
}
/**
* Subscribe to orderbook snapshots and updates from the websocket
- * @param subscriptionOpts An OrderbookChannelSubscriptionOpts instance describing which
- * token pair to subscribe to
+ * @param subscriptionOpts An OrdersChannelSubscriptionOpts instance describing which
+ * assetData pair to subscribe to
*/
- public subscribe(subscriptionOpts: OrderbookChannelSubscriptionOpts): void {
- assert.isOrderbookChannelSubscriptionOpts('subscriptionOpts', subscriptionOpts);
+ 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);
- // TODO: update requestId management to use UUIDs for v2
+ const requestId = uuid();
+ this._subscriptionOptsMap[requestId] = subscriptionOpts;
const subscribeMessage = {
type: 'subscribe',
- channel: 'orderbook',
- requestId: this._subscriptionOptsList.length - 1,
+ channel: 'orders',
+ requestId,
payload: subscriptionOpts,
};
this._client.send(JSON.stringify(subscribeMessage));
@@ -72,8 +72,8 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
}
try {
const data = message.data;
- const parserResult = orderbookChannelMessageParser.parse(data);
- const subscriptionOpts = this._subscriptionOptsList[parserResult.requestId];
+ const parserResult = ordersChannelMessageParser.parse(data);
+ const subscriptionOpts = this._subscriptionOptsMap[parserResult.requestId];
if (_.isUndefined(subscriptionOpts)) {
this._handler.onError(
this,
@@ -82,11 +82,7 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
return;
}
switch (parserResult.type) {
- case OrderbookChannelMessageTypes.Snapshot: {
- this._handler.onSnapshot(this, subscriptionOpts, parserResult.payload);
- break;
- }
- case OrderbookChannelMessageTypes.Update: {
+ case OrdersChannelMessageTypes.Update: {
this._handler.onUpdate(this, subscriptionOpts, parserResult.payload);
break;
}
diff --git a/packages/connect/test/fixtures/standard_relayer_api/asset_pairs.json b/packages/connect/test/fixtures/standard_relayer_api/asset_pairs.json
new file mode 100644
index 000000000..603e9f67e
--- /dev/null
+++ b/packages/connect/test/fixtures/standard_relayer_api/asset_pairs.json
@@ -0,0 +1,21 @@
+{
+ "total": 43,
+ "page": 1,
+ "perPage": 100,
+ "records": [
+ {
+ "assetDataA": {
+ "minAmount": "0",
+ "maxAmount": "10000000000000000000",
+ "precision": 5,
+ "assetData": "0xf47261b04c32345ced77393b3530b1eed0f346429d"
+ },
+ "assetDataB": {
+ "minAmount": "0",
+ "maxAmount": "50000000000000000000",
+ "precision": 5,
+ "assetData": "0x0257179264389b814a946f3e92105513705ca6b990"
+ }
+ }
+ ]
+}
diff --git a/packages/connect/test/fixtures/standard_relayer_api/asset_pairs.ts b/packages/connect/test/fixtures/standard_relayer_api/asset_pairs.ts
new file mode 100644
index 000000000..5ce703317
--- /dev/null
+++ b/packages/connect/test/fixtures/standard_relayer_api/asset_pairs.ts
@@ -0,0 +1,25 @@
+import { BigNumber } from '@0xproject/utils';
+
+import { AssetPairsResponse } from '../../../src/types';
+
+export const assetDataPairsResponse: AssetPairsResponse = {
+ total: 43,
+ page: 1,
+ perPage: 100,
+ records: [
+ {
+ assetDataA: {
+ minAmount: new BigNumber('0'),
+ maxAmount: new BigNumber('10000000000000000000'),
+ precision: 5,
+ assetData: '0xf47261b04c32345ced77393b3530b1eed0f346429d',
+ },
+ assetDataB: {
+ minAmount: new BigNumber('0'),
+ maxAmount: new BigNumber('50000000000000000000'),
+ precision: 5,
+ assetData: '0x0257179264389b814a946f3e92105513705ca6b990',
+ },
+ },
+ ],
+};
diff --git a/packages/connect/test/fixtures/standard_relayer_api/fee_recipients.json b/packages/connect/test/fixtures/standard_relayer_api/fee_recipients.json
new file mode 100644
index 000000000..b1d570b03
--- /dev/null
+++ b/packages/connect/test/fixtures/standard_relayer_api/fee_recipients.json
@@ -0,0 +1,10 @@
+{
+ "total": 3,
+ "page": 1,
+ "perPage": 10,
+ "records": [
+ "0x6ec92694ea172ebc430c30fa31de87620967a082",
+ "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+ "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32"
+ ]
+}
diff --git a/packages/connect/test/fixtures/standard_relayer_api/fee_recipients.ts b/packages/connect/test/fixtures/standard_relayer_api/fee_recipients.ts
new file mode 100644
index 000000000..e17ffe7a8
--- /dev/null
+++ b/packages/connect/test/fixtures/standard_relayer_api/fee_recipients.ts
@@ -0,0 +1,12 @@
+import { FeeRecipientsResponse } from '../../../src/types';
+
+export const feeRecipientsResponse: FeeRecipientsResponse = {
+ total: 3,
+ page: 1,
+ perPage: 10,
+ records: [
+ '0x6ec92694ea172ebc430c30fa31de87620967a082',
+ '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+ '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+ ],
+};
diff --git a/packages/connect/test/fixtures/standard_relayer_api/fees.json b/packages/connect/test/fixtures/standard_relayer_api/fees.json
deleted file mode 100644
index 483a74254..000000000
--- a/packages/connect/test/fixtures/standard_relayer_api/fees.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "feeRecipient": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
- "makerFee": "10000000000000000",
- "takerFee": "30000000000000000"
-}
diff --git a/packages/connect/test/fixtures/standard_relayer_api/fees.ts b/packages/connect/test/fixtures/standard_relayer_api/fees.ts
deleted file mode 100644
index fecbaacff..000000000
--- a/packages/connect/test/fixtures/standard_relayer_api/fees.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { BigNumber } from '@0xproject/utils';
-
-import { FeesResponse } from '../../../src/types';
-
-export const feesResponse: FeesResponse = {
- feeRecipient: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
- makerFee: new BigNumber('10000000000000000'),
- takerFee: new BigNumber('30000000000000000'),
-};
diff --git a/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json b/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json
index e84954b0d..8d2cdd8ed 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json
@@ -1,19 +1,19 @@
{
- "maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
- "taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
- "makerFee": "100000000000000",
- "takerFee": "200000000000000",
- "makerTokenAmount": "10000000000000000",
- "takerTokenAmount": "20000000000000000",
- "makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
- "takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
- "salt": "256",
- "feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
- "exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
- "expirationUnixTimestampSec": "42",
- "ecSignature": {
- "v": 27,
- "r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
- "s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
- }
+ "order": {
+ "makerAddress": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+ "takerAddress": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+ "feeRecipientAddress": "0xb046140686d052fff581f63f8136cce132e857da",
+ "senderAddress": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+ "makerAssetAmount": "10000000000000000",
+ "takerAssetAmount": "20000000000000000",
+ "makerFee": "100000000000000",
+ "takerFee": "200000000000000",
+ "expirationTimeSeconds": "1532560590",
+ "salt": "1532559225",
+ "makerAssetData": "0xf47261b04c32345ced77393b3530b1eed0f346429d",
+ "takerAssetData": "0x0257179264389b814a946f3e92105513705ca6b990",
+ "exchangeAddress": "0x12459c951127e0c374ff9105dda097662a027093",
+ "signature": "0x012761a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33"
+ },
+ "metaData": {}
}
diff --git a/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts b/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts
index 5a03a2ff6..c8a669b3b 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.ts
@@ -1,21 +1,21 @@
import { BigNumber } from '@0xproject/utils';
export const orderResponse = {
- maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
- taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
- makerFee: new BigNumber('100000000000000'),
- takerFee: new BigNumber('200000000000000'),
- makerTokenAmount: new BigNumber('10000000000000000'),
- takerTokenAmount: new BigNumber('20000000000000000'),
- makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
- takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
- salt: new BigNumber('256'),
- feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
- exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
- expirationUnixTimestampSec: new BigNumber('42'),
- ecSignature: {
- v: 27,
- r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
- s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+ order: {
+ makerAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+ takerAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+ feeRecipientAddress: '0xb046140686d052fff581f63f8136cce132e857da',
+ senderAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+ makerAssetAmount: new BigNumber('10000000000000000'),
+ takerAssetAmount: new BigNumber('20000000000000000'),
+ makerFee: new BigNumber('100000000000000'),
+ takerFee: new BigNumber('200000000000000'),
+ expirationTimeSeconds: new BigNumber('1532560590'),
+ salt: new BigNumber('1532559225'),
+ makerAssetData: '0xf47261b04c32345ced77393b3530b1eed0f346429d',
+ takerAssetData: '0x0257179264389b814a946f3e92105513705ca6b990',
+ exchangeAddress: '0x12459c951127e0c374ff9105dda097662a027093',
+ signature: '0x012761a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
},
+ metaData: {},
};
diff --git a/packages/connect/test/fixtures/standard_relayer_api/order_config.json b/packages/connect/test/fixtures/standard_relayer_api/order_config.json
new file mode 100644
index 000000000..39da91e6d
--- /dev/null
+++ b/packages/connect/test/fixtures/standard_relayer_api/order_config.json
@@ -0,0 +1,6 @@
+{
+ "senderAddress": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+ "feeRecipientAddress": "0xb046140686d052fff581f63f8136cce132e857da",
+ "makerFee": "100000000000000",
+ "takerFee": "200000000000000"
+}
diff --git a/packages/connect/test/fixtures/standard_relayer_api/order_config.ts b/packages/connect/test/fixtures/standard_relayer_api/order_config.ts
new file mode 100644
index 000000000..36f01a009
--- /dev/null
+++ b/packages/connect/test/fixtures/standard_relayer_api/order_config.ts
@@ -0,0 +1,10 @@
+import { BigNumber } from '@0xproject/utils';
+
+import { OrderConfigResponse } from '../../../src/types';
+
+export const orderConfigResponse: OrderConfigResponse = {
+ senderAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+ feeRecipientAddress: '0xb046140686d052fff581f63f8136cce132e857da',
+ makerFee: new BigNumber('100000000000000'),
+ takerFee: new BigNumber('200000000000000'),
+};
diff --git a/packages/connect/test/fixtures/standard_relayer_api/orderbook.json b/packages/connect/test/fixtures/standard_relayer_api/orderbook.json
index 825be34c2..5206c2217 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/orderbook.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/orderbook.json
@@ -1,44 +1,54 @@
{
- "bids": [
- {
- "maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
- "taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
- "makerFee": "100000000000000",
- "takerFee": "200000000000000",
- "makerTokenAmount": "10000000000000000",
- "takerTokenAmount": "20000000000000000",
- "makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
- "takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
- "salt": "256",
- "feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
- "exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
- "expirationUnixTimestampSec": "42",
- "ecSignature": {
- "v": 27,
- "r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
- "s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
+ "bids": {
+ "total": 325,
+ "page": 2,
+ "perPage": 100,
+ "records": [
+ {
+ "order": {
+ "makerAddress": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+ "takerAddress": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+ "feeRecipientAddress": "0xb046140686d052fff581f63f8136cce132e857da",
+ "senderAddress": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+ "makerAssetAmount": "10000000000000000",
+ "takerAssetAmount": "20000000000000000",
+ "makerFee": "100000000000000",
+ "takerFee": "200000000000000",
+ "expirationTimeSeconds": "1532560590",
+ "salt": "1532559225",
+ "makerAssetData": "0xf47261b04c32345ced77393b3530b1eed0f346429d",
+ "takerAssetData": "0x0257179264389b814a946f3e92105513705ca6b990",
+ "exchangeAddress": "0x12459c951127e0c374ff9105dda097662a027093",
+ "signature": "0x012761a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33"
+ },
+ "metaData": {}
}
- }
- ],
- "asks": [
- {
- "maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
- "taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
- "makerFee": "100000000000000",
- "takerFee": "200000000000000",
- "makerTokenAmount": "10000000000000000",
- "takerTokenAmount": "20000000000000000",
- "makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
- "takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
- "salt": "256",
- "feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
- "exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
- "expirationUnixTimestampSec": "42",
- "ecSignature": {
- "v": 27,
- "r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
- "s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
+ ]
+ },
+ "asks": {
+ "total": 500,
+ "page": 2,
+ "perPage": 100,
+ "records": [
+ {
+ "order": {
+ "makerAddress": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+ "takerAddress": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+ "feeRecipientAddress": "0xb046140686d052fff581f63f8136cce132e857da",
+ "senderAddress": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+ "makerAssetAmount": "20000000000000000",
+ "takerAssetAmount": "10000000000000000",
+ "makerFee": "200000000000000",
+ "takerFee": "100000000000000",
+ "expirationTimeSeconds": "1532560590",
+ "salt": "1532559225",
+ "makerAssetData": "0x0257179264389b814a946f3e92105513705ca6b990",
+ "takerAssetData": "0xf47261b04c32345ced77393b3530b1eed0f346429d",
+ "exchangeAddress": "0x12459c951127e0c374ff9105dda097662a027093",
+ "signature": "0x013842a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b3518891"
+ },
+ "metaData": {}
}
- }
- ]
+ ]
+ }
}
diff --git a/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts b/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts
index 6684ac2e5..d5f39a51f 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts
@@ -1,46 +1,58 @@
import { BigNumber } from '@0xproject/utils';
-export const orderbookResponse = {
- bids: [
- {
- maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
- taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
- makerFee: new BigNumber('100000000000000'),
- takerFee: new BigNumber('200000000000000'),
- makerTokenAmount: new BigNumber('10000000000000000'),
- takerTokenAmount: new BigNumber('20000000000000000'),
- makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
- takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
- salt: new BigNumber('256'),
- feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
- exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
- expirationUnixTimestampSec: new BigNumber('42'),
- ecSignature: {
- v: 27,
- r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
- s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+import { OrderbookResponse } from '../../../src/types';
+
+export const orderbookResponse: OrderbookResponse = {
+ bids: {
+ total: 325,
+ page: 2,
+ perPage: 100,
+ records: [
+ {
+ order: {
+ makerAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+ takerAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+ feeRecipientAddress: '0xb046140686d052fff581f63f8136cce132e857da',
+ senderAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+ makerAssetAmount: new BigNumber('10000000000000000'),
+ takerAssetAmount: new BigNumber('20000000000000000'),
+ makerFee: new BigNumber('100000000000000'),
+ takerFee: new BigNumber('200000000000000'),
+ expirationTimeSeconds: new BigNumber('1532560590'),
+ salt: new BigNumber('1532559225'),
+ makerAssetData: '0xf47261b04c32345ced77393b3530b1eed0f346429d',
+ takerAssetData: '0x0257179264389b814a946f3e92105513705ca6b990',
+ exchangeAddress: '0x12459c951127e0c374ff9105dda097662a027093',
+ signature: '0x012761a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+ },
+ metaData: {},
},
- },
- ],
- asks: [
- {
- maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
- taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
- makerFee: new BigNumber('100000000000000'),
- takerFee: new BigNumber('200000000000000'),
- makerTokenAmount: new BigNumber('10000000000000000'),
- takerTokenAmount: new BigNumber('20000000000000000'),
- makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
- takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
- salt: new BigNumber('256'),
- feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
- exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
- expirationUnixTimestampSec: new BigNumber('42'),
- ecSignature: {
- v: 27,
- r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
- s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+ ],
+ },
+ asks: {
+ total: 500,
+ page: 2,
+ perPage: 100,
+ records: [
+ {
+ order: {
+ makerAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+ takerAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+ feeRecipientAddress: '0xb046140686d052fff581f63f8136cce132e857da',
+ senderAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+ makerAssetAmount: new BigNumber('20000000000000000'),
+ takerAssetAmount: new BigNumber('10000000000000000'),
+ makerFee: new BigNumber('200000000000000'),
+ takerFee: new BigNumber('100000000000000'),
+ expirationTimeSeconds: new BigNumber('1532560590'),
+ salt: new BigNumber('1532559225'),
+ makerAssetData: '0x0257179264389b814a946f3e92105513705ca6b990',
+ takerAssetData: '0xf47261b04c32345ced77393b3530b1eed0f346429d',
+ exchangeAddress: '0x12459c951127e0c374ff9105dda097662a027093',
+ signature: '0x013842a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b3518891',
+ },
+ metaData: {},
},
- },
- ],
+ ],
+ },
};
diff --git a/packages/connect/test/fixtures/standard_relayer_api/orders.json b/packages/connect/test/fixtures/standard_relayer_api/orders.json
index cfa780dc4..683612071 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/orders.json
+++ b/packages/connect/test/fixtures/standard_relayer_api/orders.json
@@ -1,21 +1,26 @@
-[
- {
- "maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
- "taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
- "makerFee": "100000000000000",
- "takerFee": "200000000000000",
- "makerTokenAmount": "10000000000000000",
- "takerTokenAmount": "20000000000000000",
- "makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
- "takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
- "salt": "256",
- "feeRecipient": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
- "exchangeContractAddress": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
- "expirationUnixTimestampSec": "42",
- "ecSignature": {
- "v": 27,
- "r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
- "s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
+{
+ "total": 984,
+ "page": 1,
+ "perPage": 100,
+ "records": [
+ {
+ "order": {
+ "makerAddress": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
+ "takerAddress": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+ "feeRecipientAddress": "0xb046140686d052fff581f63f8136cce132e857da",
+ "senderAddress": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
+ "makerAssetAmount": "10000000000000000",
+ "takerAssetAmount": "20000000000000000",
+ "makerFee": "100000000000000",
+ "takerFee": "200000000000000",
+ "expirationTimeSeconds": "1532560590",
+ "salt": "1532559225",
+ "makerAssetData": "0xf47261b04c32345ced77393b3530b1eed0f346429d",
+ "takerAssetData": "0x0257179264389b814a946f3e92105513705ca6b990",
+ "exchangeAddress": "0x12459c951127e0c374ff9105dda097662a027093",
+ "signature": "0x012761a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33"
+ },
+ "metaData": {}
}
- }
-]
+ ]
+}
diff --git a/packages/connect/test/fixtures/standard_relayer_api/orders.ts b/packages/connect/test/fixtures/standard_relayer_api/orders.ts
index 5044777bd..01f8974b8 100644
--- a/packages/connect/test/fixtures/standard_relayer_api/orders.ts
+++ b/packages/connect/test/fixtures/standard_relayer_api/orders.ts
@@ -1,23 +1,30 @@
import { BigNumber } from '@0xproject/utils';
-export const ordersResponse = [
- {
- maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
- taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
- makerFee: new BigNumber('100000000000000'),
- takerFee: new BigNumber('200000000000000'),
- makerTokenAmount: new BigNumber('10000000000000000'),
- takerTokenAmount: new BigNumber('20000000000000000'),
- makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
- takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
- salt: new BigNumber('256'),
- feeRecipient: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
- exchangeContractAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
- expirationUnixTimestampSec: new BigNumber('42'),
- ecSignature: {
- v: 27,
- r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
- s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+import { OrdersResponse } from '../../../src/types';
+
+export const ordersResponse: OrdersResponse = {
+ total: 984,
+ page: 1,
+ perPage: 100,
+ records: [
+ {
+ order: {
+ makerAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+ takerAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+ feeRecipientAddress: '0xb046140686d052fff581f63f8136cce132e857da',
+ senderAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+ makerAssetAmount: new BigNumber('10000000000000000'),
+ takerAssetAmount: new BigNumber('20000000000000000'),
+ makerFee: new BigNumber('100000000000000'),
+ takerFee: new BigNumber('200000000000000'),
+ expirationTimeSeconds: new BigNumber('1532560590'),
+ salt: new BigNumber('1532559225'),
+ makerAssetData: '0xf47261b04c32345ced77393b3530b1eed0f346429d',
+ takerAssetData: '0x0257179264389b814a946f3e92105513705ca6b990',
+ exchangeAddress: '0x12459c951127e0c374ff9105dda097662a027093',
+ signature: '0x012761a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
+ },
+ metaData: {},
},
- },
-];
+ ],
+};
diff --git a/packages/connect/test/fixtures/standard_relayer_api/snapshot_orderbook_channel_message.ts b/packages/connect/test/fixtures/standard_relayer_api/snapshot_orderbook_channel_message.ts
deleted file mode 100644
index 1d7e67055..000000000
--- a/packages/connect/test/fixtures/standard_relayer_api/snapshot_orderbook_channel_message.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import * as orderbookJSON from './orderbook.json';
-
-const orderbookJsonString = JSON.stringify(orderbookJSON);
-
-export const snapshotOrderbookChannelMessage = `{
- "type": "snapshot",
- "channel": "orderbook",
- "requestId": 1,
- "payload": ${orderbookJsonString}
-}`;
-
-export const malformedSnapshotOrderbookChannelMessage = `{
- "type": "snapshot",
- "channel": "orderbook",
- "requestId": 1,
- "payload": {}
-}`;
diff --git a/packages/connect/test/fixtures/standard_relayer_api/token_pairs.json b/packages/connect/test/fixtures/standard_relayer_api/token_pairs.json
deleted file mode 100644
index 90f57a974..000000000
--- a/packages/connect/test/fixtures/standard_relayer_api/token_pairs.json
+++ /dev/null
@@ -1,16 +0,0 @@
-[
- {
- "tokenA": {
- "address": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
- "minAmount": "0",
- "maxAmount": "10000000000000000000",
- "precision": 5
- },
- "tokenB": {
- "address": "0xef7fff64389b814a946f3e92105513705ca6b990",
- "minAmount": "0",
- "maxAmount": "50000000000000000000",
- "precision": 5
- }
- }
-]
diff --git a/packages/connect/test/fixtures/standard_relayer_api/token_pairs.ts b/packages/connect/test/fixtures/standard_relayer_api/token_pairs.ts
deleted file mode 100644
index f48b1e877..000000000
--- a/packages/connect/test/fixtures/standard_relayer_api/token_pairs.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { BigNumber } from '@0xproject/utils';
-
-import { TokenPairsItem } from '../../../src/types';
-
-export const tokenPairsResponse: TokenPairsItem[] = [
- {
- tokenA: {
- address: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
- minAmount: new BigNumber(0),
- maxAmount: new BigNumber('10000000000000000000'),
- precision: 5,
- },
- tokenB: {
- address: '0xef7fff64389b814a946f3e92105513705ca6b990',
- minAmount: new BigNumber(0),
- maxAmount: new BigNumber('50000000000000000000'),
- precision: 5,
- },
- },
-];
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 cbedff60e..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
@@ -2,9 +2,9 @@ import * as orderResponseJSON from './order/0xabc67323774bdbd24d94f977fa9ac94a50
const orderJSONString = JSON.stringify(orderResponseJSON);
-export const unknownOrderbookChannelMessage = `{
+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 0e2c7523b..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 updateOrderbookChannelMessage = `{
- "type": "update",
- "channel": "orderbook",
- "requestId": 1,
- "payload": ${orderJSONString}
-}`;
-
-export const malformedUpdateOrderbookChannelMessage = `{
- "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 311dc96e6..5b564e97b 100644
--- a/packages/connect/test/http_client_test.ts
+++ b/packages/connect/test/http_client_test.ts
@@ -1,4 +1,3 @@
-import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
import * as dirtyChai from 'dirty-chai';
@@ -7,16 +6,18 @@ import 'mocha';
import { HttpClient } from '../src/index';
-import { feesResponse } from './fixtures/standard_relayer_api/fees';
-import * as feesResponseJSON from './fixtures/standard_relayer_api/fees.json';
+import { assetDataPairsResponse } from './fixtures/standard_relayer_api/asset_pairs';
+import * as assetDataPairsResponseJSON from './fixtures/standard_relayer_api/asset_pairs.json';
+import { feeRecipientsResponse } from './fixtures/standard_relayer_api/fee_recipients';
+import * as feeRecipientsResponseJSON from './fixtures/standard_relayer_api/fee_recipients.json';
import { orderResponse } from './fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f';
import * as orderResponseJSON from './fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json';
+import { orderConfigResponse } from './fixtures/standard_relayer_api/order_config';
+import * as orderConfigResponseJSON from './fixtures/standard_relayer_api/order_config.json';
import { orderbookResponse } from './fixtures/standard_relayer_api/orderbook';
import * as orderbookJSON from './fixtures/standard_relayer_api/orderbook.json';
import { ordersResponse } from './fixtures/standard_relayer_api/orders';
import * as ordersResponseJSON from './fixtures/standard_relayer_api/orders.json';
-import { tokenPairsResponse } from './fixtures/standard_relayer_api/token_pairs';
-import * as tokenPairsResponseJSON from './fixtures/standard_relayer_api/token_pairs.json';
chai.config.includeStack = true;
chai.use(dirtyChai);
@@ -26,7 +27,7 @@ const expect = chai.expect;
describe('HttpClient', () => {
const relayUrl = 'https://example.com';
const relayerClient = new HttpClient(relayUrl);
- afterEach(() => {
+ beforeEach(() => {
fetchMock.restore();
});
describe('#constructor', () => {
@@ -38,47 +39,47 @@ describe('HttpClient', () => {
expect(sanitizedUrl).to.be.deep.equal(urlWithoutTrailingSlash);
});
});
- describe('#getTokenPairsAsync', () => {
- const url = `${relayUrl}/token_pairs`;
- it('gets token pairs with default options when none are provided', async () => {
- const urlWithQuery = `${url}?page=1&per_page=100`;
- fetchMock.get(urlWithQuery, tokenPairsResponseJSON);
- const tokenPairs = await relayerClient.getTokenPairsAsync();
- expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
- });
- it('gets token pairs with specified request options', async () => {
- const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
- const tokenPairsRequestOpts = {
- tokenA: tokenAddress,
+ describe('#getAssetPairsAsync', () => {
+ const url = `${relayUrl}/asset_pairs`;
+ it('gets assetData pairs with default options when none are provided', async () => {
+ fetchMock.get(url, assetDataPairsResponseJSON);
+ const assetDataPairs = await relayerClient.getAssetPairsAsync();
+ expect(assetDataPairs).to.be.deep.equal(assetDataPairsResponse);
+ });
+ it('gets assetData pairs with specified request options', async () => {
+ const assetData = '0xf47261b04c32345ced77393b3530b1eed0f346429d';
+ const assetPairsRequestOpts = {
+ assetDataA: assetData,
page: 3,
perPage: 50,
+ networkdId: 42,
};
- const urlWithQuery = `${url}?page=3&per_page=50&tokenA=${tokenAddress}`;
- fetchMock.get(urlWithQuery, tokenPairsResponseJSON);
- const tokenPairs = await relayerClient.getTokenPairsAsync(tokenPairsRequestOpts);
- expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
+ const urlWithQuery = `${url}?assetDataA=${assetData}&networkdId=42&page=3&perPage=50`;
+ fetchMock.get(urlWithQuery, assetDataPairsResponseJSON);
+ const assetDataPairs = await relayerClient.getAssetPairsAsync(assetPairsRequestOpts);
+ expect(assetDataPairs).to.be.deep.equal(assetDataPairsResponse);
});
it('throws an error for invalid JSON response', async () => {
fetchMock.get(url, { test: 'dummy' });
- expect(relayerClient.getTokenPairsAsync()).to.be.rejected();
+ expect(relayerClient.getAssetPairsAsync()).to.be.rejected();
});
});
describe('#getOrdersAsync', () => {
const url = `${relayUrl}/orders`;
it('gets orders with default options when none are provided', async () => {
- const urlWithQuery = `${url}?page=1&per_page=100`;
- fetchMock.get(urlWithQuery, ordersResponseJSON);
+ fetchMock.get(url, ordersResponseJSON);
const orders = await relayerClient.getOrdersAsync();
expect(orders).to.be.deep.equal(ordersResponse);
});
it('gets orders with specified request options', async () => {
- const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
+ const assetDataAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
const ordersRequest = {
- tokenAddress,
+ assetDataAddress,
page: 3,
perPage: 50,
+ networkdId: 42,
};
- const urlWithQuery = `${url}?page=3&per_page=50&tokenAddress=${tokenAddress}`;
+ const urlWithQuery = `${url}?assetDataAddress=${assetDataAddress}&networkdId=42&page=3&perPage=50`;
fetchMock.get(urlWithQuery, ordersResponseJSON);
const orders = await relayerClient.getOrdersAsync(ordersRequest);
expect(orders).to.be.deep.equal(ordersResponse);
@@ -103,26 +104,27 @@ describe('HttpClient', () => {
});
describe('#getOrderBookAsync', () => {
const request = {
- baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
- quoteTokenAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+ baseAssetData: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+ quoteAssetData: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
};
const url = `${relayUrl}/orderbook`;
it('gets orderbook with default page options when none are provided', async () => {
- const urlWithQuery = `${url}?baseTokenAddress=${
- request.baseTokenAddress
- }&page=1&per_page=100&quoteTokenAddress=${request.quoteTokenAddress}`;
+ const urlWithQuery = `${url}?baseAssetData=${request.baseAssetData}&quoteAssetData=${
+ request.quoteAssetData
+ }`;
fetchMock.get(urlWithQuery, orderbookJSON);
const orderbook = await relayerClient.getOrderbookAsync(request);
expect(orderbook).to.be.deep.equal(orderbookResponse);
});
it('gets orderbook with specified page options', async () => {
- const urlWithQuery = `${url}?baseTokenAddress=${
- request.baseTokenAddress
- }&page=3&per_page=50&quoteTokenAddress=${request.quoteTokenAddress}`;
+ const urlWithQuery = `${url}?baseAssetData=${
+ request.baseAssetData
+ }&networkId=42&page=3&perPage=50&quoteAssetData=${request.quoteAssetData}`;
fetchMock.get(urlWithQuery, orderbookJSON);
const pagedRequestOptions = {
page: 3,
perPage: 50,
+ networkId: 42,
};
const orderbook = await relayerClient.getOrderbookAsync(request, pagedRequestOptions);
expect(orderbook).to.be.deep.equal(orderbookResponse);
@@ -132,39 +134,59 @@ describe('HttpClient', () => {
expect(relayerClient.getOrderbookAsync(request)).to.be.rejected();
});
});
- describe('#getFeesAsync', () => {
+ describe('#getOrderConfigAsync', () => {
const request = {
- exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
- maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
- taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
- makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
- takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
- makerTokenAmount: new BigNumber('10000000000000000000'),
- takerTokenAmount: new BigNumber('30000000000000000000'),
- salt: new BigNumber('256'),
- expirationUnixTimestampSec: new BigNumber('42'),
+ makerAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
+ takerAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
+ makerAssetAmount: '10000000000000000',
+ takerAssetAmount: '20000000000000000',
+ expirationTimeSeconds: '1532560590',
+ makerAssetData: '0xf47261b04c32345ced77393b3530b1eed0f346429d',
+ takerAssetData: '0x0257179264389b814a946f3e92105513705ca6b990',
+ exchangeAddress: '0x12459c951127e0c374ff9105dda097662a027093',
};
- const url = `${relayUrl}/fees`;
- it('gets fees', async () => {
- fetchMock.post(url, feesResponseJSON);
- const fees = await relayerClient.getFeesAsync(request);
- expect(fees).to.be.deep.equal(feesResponse);
+ const url = `${relayUrl}/order_config`;
+ it('gets order config', async () => {
+ fetchMock.post(url, orderConfigResponseJSON);
+ const fees = await relayerClient.getOrderConfigAsync(request);
+ expect(fees).to.be.deep.equal(orderConfigResponse);
});
it('does not mutate input', async () => {
- fetchMock.post(url, feesResponseJSON);
- const makerTokenAmountBefore = new BigNumber(request.makerTokenAmount);
- const takerTokenAmountBefore = new BigNumber(request.takerTokenAmount);
- const saltBefore = new BigNumber(request.salt);
- const expirationUnixTimestampSecBefore = new BigNumber(request.expirationUnixTimestampSec);
- await relayerClient.getFeesAsync(request);
- expect(makerTokenAmountBefore).to.be.deep.equal(request.makerTokenAmount);
- expect(takerTokenAmountBefore).to.be.deep.equal(request.takerTokenAmount);
- expect(saltBefore).to.be.deep.equal(request.salt);
- expect(expirationUnixTimestampSecBefore).to.be.deep.equal(request.expirationUnixTimestampSec);
+ fetchMock.post(url, orderConfigResponseJSON);
+ const makerAssetAmountBefore = request.makerAssetAmount;
+ const takerAssetAmountBefore = request.takerAssetAmount;
+ const expirationTimeSecondsBefore = request.expirationTimeSeconds;
+ await relayerClient.getOrderConfigAsync(request);
+ expect(makerAssetAmountBefore).to.be.deep.equal(request.makerAssetAmount);
+ expect(takerAssetAmountBefore).to.be.deep.equal(request.takerAssetAmount);
+ expect(expirationTimeSecondsBefore).to.be.deep.equal(request.expirationTimeSeconds);
});
it('throws an error for invalid JSON response', async () => {
fetchMock.post(url, { test: 'dummy' });
- expect(relayerClient.getFeesAsync(request)).to.be.rejected();
+ expect(relayerClient.getOrderConfigAsync(request)).to.be.rejected();
+ });
+ });
+ describe('#getFeeRecipientsAsync', () => {
+ const url = `${relayUrl}/fee_recipients`;
+ it('gets fee recipients with default page options when none are provided', async () => {
+ fetchMock.get(url, feeRecipientsResponseJSON);
+ const feeRecipients = await relayerClient.getFeeRecipientsAsync();
+ expect(feeRecipients).to.be.deep.equal(feeRecipientsResponse);
+ });
+ it('gets fee recipient with specified page options', async () => {
+ const urlWithQuery = `${url}?networkId=42&page=3&perPage=50`;
+ fetchMock.get(urlWithQuery, feeRecipientsResponseJSON);
+ const pagedRequestOptions = {
+ page: 3,
+ perPage: 50,
+ networkId: 42,
+ };
+ const feeRecipients = await relayerClient.getFeeRecipientsAsync(pagedRequestOptions);
+ expect(feeRecipients).to.be.deep.equal(feeRecipientsResponse);
+ });
+ it('throws an error for invalid JSON response', async () => {
+ fetchMock.get(url, { test: 'dummy' });
+ expect(relayerClient.getFeeRecipientsAsync()).to.be.rejected();
});
});
});
diff --git a/packages/connect/test/orderbook_channel_factory_test.ts b/packages/connect/test/orderbook_channel_factory_test.ts
deleted file mode 100644
index 2ce361bd2..000000000
--- a/packages/connect/test/orderbook_channel_factory_test.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import * as chai from 'chai';
-import * as dirtyChai from 'dirty-chai';
-import * as _ from 'lodash';
-import 'mocha';
-
-import { orderbookChannelFactory } from '../src/orderbook_channel_factory';
-
-chai.config.includeStack = true;
-chai.use(dirtyChai);
-const expect = chai.expect;
-const emptyOrderbookChannelHandler = {
- onSnapshot: () => {
- _.noop();
- },
- onUpdate: () => {
- _.noop();
- },
- onError: () => {
- _.noop();
- },
- onClose: () => {
- _.noop();
- },
-};
-
-describe('orderbookChannelFactory', () => {
- const websocketUrl = 'ws://localhost:8080';
- describe('#createWebSocketOrderbookChannelAsync', () => {
- it('throws when input is not a url', () => {
- const badUrlInput = 54;
- expect(
- orderbookChannelFactory.createWebSocketOrderbookChannelAsync(
- badUrlInput as any,
- emptyOrderbookChannelHandler,
- ),
- ).to.be.rejected();
- });
- it('throws when handler has the incorrect members', () => {
- const badHandlerInput = {};
- expect(
- orderbookChannelFactory.createWebSocketOrderbookChannelAsync(websocketUrl, badHandlerInput as any),
- ).to.be.rejected();
- });
- });
-});
diff --git a/packages/connect/test/orderbook_channel_message_parsers_test.ts b/packages/connect/test/orderbook_channel_message_parsers_test.ts
deleted file mode 100644
index 3e1f44384..000000000
--- a/packages/connect/test/orderbook_channel_message_parsers_test.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import * as chai from 'chai';
-import * as dirtyChai from 'dirty-chai';
-import 'mocha';
-
-import { orderbookChannelMessageParser } from '../src/utils/orderbook_channel_message_parser';
-
-import { orderResponse } from './fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f';
-import { orderbookResponse } from './fixtures/standard_relayer_api/orderbook';
-import {
- malformedSnapshotOrderbookChannelMessage,
- snapshotOrderbookChannelMessage,
-} from './fixtures/standard_relayer_api/snapshot_orderbook_channel_message';
-import { unknownOrderbookChannelMessage } from './fixtures/standard_relayer_api/unknown_orderbook_channel_message';
-import {
- malformedUpdateOrderbookChannelMessage,
- updateOrderbookChannelMessage,
-} from './fixtures/standard_relayer_api/update_orderbook_channel_message';
-
-chai.config.includeStack = true;
-chai.use(dirtyChai);
-const expect = chai.expect;
-
-describe('orderbookChannelMessageParser', () => {
- describe('#parser', () => {
- it('parses snapshot messages', () => {
- const snapshotMessage = orderbookChannelMessageParser.parse(snapshotOrderbookChannelMessage);
- expect(snapshotMessage.type).to.be.equal('snapshot');
- expect(snapshotMessage.payload).to.be.deep.equal(orderbookResponse);
- });
- it('parses update messages', () => {
- const updateMessage = orderbookChannelMessageParser.parse(updateOrderbookChannelMessage);
- expect(updateMessage.type).to.be.equal('update');
- expect(updateMessage.payload).to.be.deep.equal(orderResponse);
- });
- it('returns unknown message for messages with unsupported types', () => {
- const unknownMessage = orderbookChannelMessageParser.parse(unknownOrderbookChannelMessage);
- expect(unknownMessage.type).to.be.equal('unknown');
- expect(unknownMessage.payload).to.be.undefined();
- });
- it('throws when message does not include a type', () => {
- const typelessMessage = `{
- "channel": "orderbook",
- "requestId": 1,
- "payload": {}
- }`;
- const badCall = () => orderbookChannelMessageParser.parse(typelessMessage);
- expect(badCall).throws(`Message is missing a type parameter: ${typelessMessage}`);
- });
- it('throws when type is not a string', () => {
- const messageWithBadType = `{
- "type": 1,
- "channel": "orderbook",
- "requestId": 1,
- "payload": {}
- }`;
- const badCall = () => orderbookChannelMessageParser.parse(messageWithBadType);
- expect(badCall).throws('Expected type to be of type string, encountered: 1');
- });
- it('throws when snapshot message has malformed payload', () => {
- const badCall = () => orderbookChannelMessageParser.parse(malformedSnapshotOrderbookChannelMessage);
- // tslint:disable-next-line:max-line-length
- const errMsg =
- 'Validation errors: instance.payload requires property "bids", instance.payload requires property "asks"';
- expect(badCall).throws(errMsg);
- });
- it('throws when update message has malformed payload', () => {
- const badCall = () => orderbookChannelMessageParser.parse(malformedUpdateOrderbookChannelMessage);
- expect(badCall).throws(/^Expected message to conform to schema/);
- });
- it('throws when input message is not valid JSON', () => {
- const nonJsonString = 'h93b{sdfs9fsd f';
- const badCall = () => orderbookChannelMessageParser.parse(nonJsonString);
- expect(badCall).throws('Unexpected token h in JSON at position 0');
- });
- });
-});
diff --git a/packages/connect/test/orders_channel_factory_test.ts b/packages/connect/test/orders_channel_factory_test.ts
new file mode 100644
index 000000000..29aa87c65
--- /dev/null
+++ b/packages/connect/test/orders_channel_factory_test.ts
@@ -0,0 +1,34 @@
+import * as chai from 'chai';
+import * as dirtyChai from 'dirty-chai';
+import * as _ from 'lodash';
+
+import 'mocha';
+
+import { ordersChannelFactory } from '../src/orders_channel_factory';
+
+chai.config.includeStack = true;
+chai.use(dirtyChai);
+const expect = chai.expect;
+const emptyOrdersChannelHandler = {
+ onUpdate: _.noop.bind(_),
+ onError: _.noop.bind(_),
+ onClose: _.noop.bind(_),
+};
+
+describe('ordersChannelFactory', () => {
+ const websocketUrl = 'ws://localhost:8080';
+ describe('#createWebSocketOrdersChannelAsync', () => {
+ it('throws when input is not a url', () => {
+ const badUrlInput = 54;
+ expect(
+ ordersChannelFactory.createWebSocketOrdersChannelAsync(badUrlInput as any, emptyOrdersChannelHandler),
+ ).to.be.rejected();
+ });
+ it('throws when handler has the incorrect members', () => {
+ const badHandlerInput = {};
+ expect(
+ ordersChannelFactory.createWebSocketOrdersChannelAsync(websocketUrl, badHandlerInput as any),
+ ).to.be.rejected();
+ });
+ });
+});
diff --git a/packages/connect/test/orders_channel_message_parsers_test.ts b/packages/connect/test/orders_channel_message_parsers_test.ts
new file mode 100644
index 000000000..4d4a2d23f
--- /dev/null
+++ b/packages/connect/test/orders_channel_message_parsers_test.ts
@@ -0,0 +1,59 @@
+import * as chai from 'chai';
+import * as dirtyChai from 'dirty-chai';
+import 'mocha';
+
+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_orders_channel_message';
+import {
+ malformedUpdateOrdersChannelMessage,
+ updateOrdersChannelMessage,
+} from './fixtures/standard_relayer_api/update_orders_channel_message';
+
+chai.config.includeStack = true;
+chai.use(dirtyChai);
+const expect = chai.expect;
+
+describe('ordersChannelMessageParser', () => {
+ describe('#parser', () => {
+ it('parses update messages', () => {
+ const updateMessage = ordersChannelMessageParser.parse(updateOrdersChannelMessage);
+ expect(updateMessage.type).to.be.equal('update');
+ expect(updateMessage.payload).to.be.deep.equal([orderResponse]);
+ });
+ it('returns unknown message for messages with unsupported types', () => {
+ const unknownMessage = ordersChannelMessageParser.parse(unknownOrdersChannelMessage);
+ expect(unknownMessage.type).to.be.equal('unknown');
+ expect(unknownMessage.payload).to.be.undefined();
+ });
+ it('throws when message does not include a type', () => {
+ const typelessMessage = `{
+ "channel": "orders",
+ "requestId": "4d8efcee-adde-4475-9601-f0b30962ca2b",
+ "payload": []
+ }`;
+ const badCall = () => ordersChannelMessageParser.parse(typelessMessage);
+ expect(badCall).throws(`Message is missing a type parameter: ${typelessMessage}`);
+ });
+ it('throws when type is not a string', () => {
+ const messageWithBadType = `{
+ "type": 1,
+ "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');
+ });
+ it('throws when update message has malformed payload', () => {
+ const badCall = () => ordersChannelMessageParser.parse(malformedUpdateOrdersChannelMessage);
+ expect(badCall).throws(/^Expected message to conform to schema/);
+ });
+ it('throws when input message is not valid JSON', () => {
+ const nonJsonString = 'h93b{sdfs9fsd f';
+ const badCall = () => ordersChannelMessageParser.parse(nonJsonString);
+ 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_orderbook_channel_test.ts
deleted file mode 100644
index 5a63cbdcc..000000000
--- a/packages/connect/test/ws_orderbook_channel_test.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import * as chai from 'chai';
-import * as dirtyChai from 'dirty-chai';
-import * as _ from 'lodash';
-import 'mocha';
-import * as Sinon from 'sinon';
-import * as WebSocket from 'websocket';
-
-import { WebSocketOrderbookChannel } from '../src/ws_orderbook_channel';
-
-chai.config.includeStack = true;
-chai.use(dirtyChai);
-const expect = chai.expect;
-const emptyOrderbookChannelHandler = {
- onSnapshot: () => {
- _.noop();
- },
- onUpdate: () => {
- _.noop();
- },
- onError: () => {
- _.noop();
- },
- onClose: () => {
- _.noop();
- },
-};
-
-describe('WebSocketOrderbookChannel', () => {
- const websocketUrl = 'ws://localhost:8080';
- const openClient = new WebSocket.w3cwebsocket(websocketUrl);
- Sinon.stub(openClient, 'readyState').get(() => WebSocket.w3cwebsocket.OPEN);
- Sinon.stub(openClient, 'send').callsFake(_.noop.bind(_));
- const openOrderbookChannel = new WebSocketOrderbookChannel(openClient, emptyOrderbookChannelHandler);
- const subscriptionOpts = {
- baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
- quoteTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
- snapshot: true,
- limit: 100,
- };
- describe('#subscribe', () => {
- it('throws when subscriptionOpts does not conform to schema', () => {
- const badSubscribeCall = openOrderbookChannel.subscribe.bind(openOrderbookChannel, {});
- expect(badSubscribeCall).throws(
- 'Expected subscriptionOpts to conform to schema /RelayerApiOrderbookChannelSubscribePayload\nEncountered: {}\nValidation errors: instance requires property "baseTokenAddress", instance requires property "quoteTokenAddress"',
- );
- });
- it('does not throw when inputs are of correct types', () => {
- const goodSubscribeCall = openOrderbookChannel.subscribe.bind(openOrderbookChannel, subscriptionOpts);
- expect(goodSubscribeCall).to.not.throw();
- });
- it('throws when client is closed', () => {
- const closedClient = new WebSocket.w3cwebsocket(websocketUrl);
- Sinon.stub(closedClient, 'readyState').get(() => WebSocket.w3cwebsocket.CLOSED);
- const closedOrderbookChannel = new WebSocketOrderbookChannel(closedClient, emptyOrderbookChannelHandler);
- const badSubscribeCall = closedOrderbookChannel.subscribe.bind(closedOrderbookChannel, subscriptionOpts);
- expect(badSubscribeCall).throws('WebSocket connection is closed');
- });
- });
-});
diff --git a/packages/connect/test/ws_orders_channel_test.ts b/packages/connect/test/ws_orders_channel_test.ts
new file mode 100644
index 000000000..df30bc41d
--- /dev/null
+++ b/packages/connect/test/ws_orders_channel_test.ts
@@ -0,0 +1,49 @@
+import * as chai from 'chai';
+import * as dirtyChai from 'dirty-chai';
+import * as _ from 'lodash';
+import 'mocha';
+import * as Sinon from 'sinon';
+import * as WebSocket from 'websocket';
+
+import { WebSocketOrdersChannel } from '../src/ws_orders_channel';
+
+chai.config.includeStack = true;
+chai.use(dirtyChai);
+const expect = chai.expect;
+const emptyOrdersChannelHandler = {
+ onUpdate: _.noop.bind(_),
+ onError: _.noop.bind(_),
+ onClose: _.noop.bind(_),
+};
+
+describe('WebSocketOrdersChannel', () => {
+ const websocketUrl = 'ws://localhost:8080';
+ const openClient = new WebSocket.w3cwebsocket(websocketUrl);
+ Sinon.stub(openClient, 'readyState').get(() => WebSocket.w3cwebsocket.OPEN);
+ Sinon.stub(openClient, 'send').callsFake(_.noop.bind(_));
+ const openOrdersChannel = new WebSocketOrdersChannel(openClient, emptyOrdersChannelHandler);
+ const subscriptionOpts = {
+ baseAssetData: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
+ quoteAssetData: '0xef7fff64389b814a946f3e92105513705ca6b990',
+ limit: 100,
+ };
+ describe('#subscribe', () => {
+ it('throws when subscriptionOpts does not conform to schema', () => {
+ 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);
+ expect(goodSubscribeCall).to.not.throw();
+ });
+ it('throws when client is closed', () => {
+ const closedClient = new WebSocket.w3cwebsocket(websocketUrl);
+ Sinon.stub(closedClient, 'readyState').get(() => WebSocket.w3cwebsocket.CLOSED);
+ const closedOrdersChannel = new WebSocketOrdersChannel(closedClient, emptyOrdersChannelHandler);
+ const badSubscribeCall = closedOrdersChannel.subscribe.bind(closedOrdersChannel, subscriptionOpts);
+ expect(badSubscribeCall).throws('WebSocket connection is closed');
+ });
+ });
+});