UNPKG

@openweb3-io/dex-aggregator

Version:

dex-aggregator API client and webhook verification library

211 lines (184 loc) 5.8 kB
import { StreamApi } from "./api/stream"; import { DexApi, Configuration, TransactionApi, DefiSolanaMoonshotApi, DefiSolanaPumpfunApi, OrderApi, OpenbookApi, BlockchainApi, DexPoolApi, TokenApi, RankingApi, TradeApi, createConfiguration, ServerConfiguration, ResponseContext, RequestContext, Middleware, TokenProvider, WalletApi, } from "./openapi"; import { EventSourcePolyfill } from "event-source-polyfill"; export interface DexRequestContext { baseUrl: string; streamUrl: string; accessToken?: string; tokenProvider?: TokenProvider; } export interface DexAggregatorOptions { accessToken?: string; tokenProvider?: TokenProvider; debug?: boolean; serverUrl?: string; streamUrl?: string; } // const REGIONS = [ // { region: "us", url: "https://api.dex.openweb3.io" }, // { region: "eu", url: "https://api.dex.openweb3.io" }, // { region: "in", url: "https://api.dex.openweb3.io" }, // ]; export const LIB_VERSION = "1.25.68"; class UserAgentMiddleware implements Middleware { public pre(context: RequestContext): Promise<RequestContext> { context.setHeaderParam("User-Agent", `dex/${LIB_VERSION}/javascript`); return Promise.resolve(context); } public post(context: ResponseContext): Promise<ResponseContext> { return Promise.resolve(context); } } export class DexAggregator { public readonly requestCtx: DexRequestContext; public readonly _configuration: Configuration; public readonly dex: DexApi; public readonly blockchain: BlockchainApi; public readonly dexpool: DexPoolApi; public readonly token: TokenApi; public readonly trade: TradeApi; public readonly ranking: RankingApi; public readonly transaction: TransactionApi; public readonly moonshot: DefiSolanaMoonshotApi; public readonly pumpfun: DefiSolanaPumpfunApi; public readonly orderbook: OrderApi; public readonly openbook: OpenbookApi; public readonly stream: StreamApi; public readonly wallet: WalletApi; public constructor(options: DexAggregatorOptions = {}) { const { accessToken, tokenProvider } = options; const baseUrl: string = options.serverUrl ?? "https://api.dex.openweb3.io"; const streamUrl: string = options.streamUrl ?? "wss://realtime.dex.openweb3.io/connection/websocket"; this.requestCtx = { baseUrl, streamUrl, accessToken, tokenProvider }; const config = createConfiguration({ baseServer: new ServerConfiguration<any>(baseUrl, {}), promiseMiddleware: [new UserAgentMiddleware()], authMethods: { bearer: { tokenProvider: tokenProvider ? tokenProvider : { getToken: () => accessToken ?? "", }, }, }, }); this._configuration = config; // this.authentication = new Authentication(config); this.dex = new DexApi(config); this.blockchain = new BlockchainApi(config); this.dexpool = new DexPoolApi(config); this.token = new TokenApi(config); this.trade = new TradeApi(config); this.ranking = new RankingApi(config); this.transaction = new TransactionApi(config); this.moonshot = new DefiSolanaMoonshotApi(config); this.pumpfun = new DefiSolanaPumpfunApi(config); this.orderbook = new OrderApi(config); this.openbook = new OpenbookApi(config); this.stream = new StreamApi(this.requestCtx); this.wallet = new WalletApi(config); this.stream.connect(); } async waitForJob<T>(jobId: string, timeout = 60000): Promise<T> { return new Promise((resolve, reject) => { const sse = new EventSourcePolyfill( `${this.requestCtx.baseUrl}/jobs/${jobId}/streaming`, { headers: { Authorization: `Bearer ${this.requestCtx.accessToken}`, }, } ); const timeoutId = setTimeout(() => { sse.close(); reject(new Error(`Job ${jobId} timed out after ${timeout}ms`)); }, timeout); sse.onmessage = (event: any) => { try { console.log("event.data: ", event.data); const data = JSON.parse(event.data); if (data.status === "error") { sse.close(); reject(new Error(`Error: ${data.message}`)); } else if (data.status === "completed") { clearTimeout(timeoutId); sse.close(); resolve(data as T); } } catch (e) { clearTimeout(timeoutId); sse.close(); reject(new Error("Error parsing event data")); } }; sse.onopen = () => { console.log("SSE connection opened"); }; sse.onerror = (error: any) => { if (error.message?.includes("No activity within")) { console.log("SSE reconnecting due to inactivity..."); return; } clearTimeout(timeoutId); sse.close(); reject(new Error(`Error in SSE connection: ${error}`)); }; }); } } export interface PostOptions { idempotencyKey?: string; } /* class Authentication { private readonly api: AuthenticationApi; public constructor(config: Configuration) { this.api = new AuthenticationApi(config); } public appPortalAccess( appId: string, appPortalAccessIn: AppPortalAccessIn, options?: PostOptions ): Promise<AppPortalAccessOut> { return this.api.v1AuthenticationAppPortalAccess({ appId, appPortalAccessIn, ...options, }); } public dashboardAccess( appId: string, options?: PostOptions ): Promise<DashboardAccessOut> { return this.api.v1AuthenticationDashboardAccess({ appId, ...options, }); } public logout(options?: PostOptions): Promise<void> { return this.api.v1AuthenticationLogout({ ...options }); } } */