import { APIOrder, HttpClient } from '@0x/connect'; import { AssetPairsItem, PaginatedCollection, SignedOrder } from '@0x/types'; import { OrderStore } from '../order_store'; import { AcceptedRejectedOrders, RejectedOrder } from '../types'; import { utils } from '../utils'; import { BaseOrderProvider } from './base_order_provider'; export const PER_PAGE_DEFAULT = 100; export abstract class BaseSRAOrderProvider extends BaseOrderProvider { protected readonly _httpClient: HttpClient; protected readonly _perPage: number; /** * This is an internal class for Websocket and Polling Order Providers */ constructor(orderStore: OrderStore, httpEndpoint: string, perPage: number = PER_PAGE_DEFAULT) { super(orderStore); this._httpClient = new HttpClient(httpEndpoint); this._perPage = perPage; } /** * Returns the availale Asset pairs from the SRA endpoint. This response is direct from the endpoint * so this call blocks until the response arrives. */ public async getAvailableAssetDatasAsync(): Promise { const requestOpts = { perPage: this._perPage, }; let recordsToReturn: AssetPairsItem[] = []; let hasMorePages = true; let page = 1; while (hasMorePages) { const { total, records, perPage } = await utils.attemptAsync>(() => this._httpClient.getAssetPairsAsync(requestOpts), ); recordsToReturn = [...recordsToReturn, ...records]; page += 1; const lastPage = Math.ceil(total / perPage); hasMorePages = page <= lastPage; } return recordsToReturn; } /** * Submits the SignedOrder to the SRA endpoint * @param orders the set of signed orders to add */ public async addOrdersAsync(orders: SignedOrder[]): Promise { const accepted: SignedOrder[] = []; const rejected: RejectedOrder[] = []; for (const order of orders) { try { await this._httpClient.submitOrderAsync(order); accepted.push(order); } catch (e) { rejected.push({ order, message: e.message }); } } return { accepted, rejected }; } protected async _fetchLatestOrdersAsync(makerAssetData: string, takerAssetData: string): Promise { const [latestSellOrders, latestBuyOrders] = await Promise.all([ this._getAllPaginatedOrdersAsync(makerAssetData, takerAssetData), this._getAllPaginatedOrdersAsync(takerAssetData, makerAssetData), ]); return [...latestSellOrders, ...latestBuyOrders]; } protected async _getAllPaginatedOrdersAsync(makerAssetData: string, takerAssetData: string): Promise { let recordsToReturn: APIOrder[] = []; const requestOpts = { makerAssetData, takerAssetData, perPage: this._perPage, }; let hasMorePages = true; let page = 1; while (hasMorePages) { const { total, records, perPage } = await utils.attemptAsync(() => this._httpClient.getOrdersAsync({ ...requestOpts, page, }), ); recordsToReturn = [...recordsToReturn, ...records]; page += 1; const lastPage = Math.ceil(total / perPage); hasMorePages = page <= lastPage; } return recordsToReturn; } }