aboutsummaryrefslogtreecommitdiffstats
path: root/packages/connect/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/connect/src')
-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
19 files changed, 386 insertions, 322 deletions
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;
}