diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..4260a78 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,16 @@ +{ + "env": { + "es2021": true, + "node": true + }, + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": ["@typescript-eslint"], + "rules": { + "@typescript-eslint/no-explicit-any": "off" + } +} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..c58eb3a --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,20 @@ +name: Run tests + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20.x] + + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - run: yarn install + - run: yarn test diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..1a3c566 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "singleQuote": false, + "semi": true, + "trailingComma": "es5", + "tabWidth": 2, + "printWidth": 100 +} diff --git a/jest.config.js b/jest.config.js index b413e10..3abcbd9 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,5 +1,5 @@ /** @type {import('ts-jest').JestConfigWithTsJest} */ module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', -}; \ No newline at end of file + preset: "ts-jest", + testEnvironment: "node", +}; diff --git a/package.json b/package.json index f4c7755..07373a2 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,10 @@ "types": "dist/index.d.ts", "scripts": { "build": "tsc", - "test": "jest" + "test": "jest", + "lint": "eslint --ext .js,.ts", + "lint:fix": "eslint --fix --ext .js,.ts", + "format": "prettier --ignore-path .gitignore --write \"**/*.+(js|ts|json)\"" }, "repository": { "type": "git", @@ -31,7 +34,11 @@ "devDependencies": { "@types/jest": "^29.5.12", "@types/node": "^20.11.28", + "@typescript-eslint/eslint-plugin": "^7.3.0", + "@typescript-eslint/parser": "^7.3.0", + "eslint": "^8.57.0", "jest": "^29.7.0", + "prettier": "^3.2.5", "ts-jest": "^29.1.2", "typescript": "^5.4.2" } diff --git a/src/authenticated-api.ts b/src/authenticated-api.ts index d68f276..ed25319 100644 --- a/src/authenticated-api.ts +++ b/src/authenticated-api.ts @@ -1,61 +1,53 @@ -import { APICommunication } from "./utils/api-communication"; +import { APIClient } from "./utils/api-client"; import { Cryptography } from "./utils/cryptography"; -import { - Balance, - Deposit, - Withdrawal, - DepositAddress, - Order, - Fill, -} from "./types"; +import { Balance, Deposit, Withdrawal, DepositAddress, Order, Fill } from "./types"; +import { AUTHENTICATED_ENDPOINTS } from "./constants/authenticated-endpoints"; +import { INSTRUCTIONS } from "./constants/instructions"; +import { HttpMethod } from "./constants"; export class AuthenticatedAPI { - private apiCommunication: APICommunication; + private apiClient: APIClient; constructor(params: { apiKey: string; secretKey: string }) { const { apiKey, secretKey } = params; - if (!apiKey || !secretKey) - throw new Error("API Key and Secret Key are required"); + if (!apiKey || !secretKey) throw new Error("API Key and Secret Key are required"); const cryptography = new Cryptography(apiKey, secretKey); - this.apiCommunication = new APICommunication(cryptography); + this.apiClient = new APIClient(cryptography); } async getBalances(): Promise> { - return this.apiCommunication.sendRequest("GET", "/api/v1/capital", { - instruction: "balanceQuery", + return this.apiClient.sendRequest(HttpMethod.GET, AUTHENTICATED_ENDPOINTS.CAPITAL, { + instruction: INSTRUCTIONS.BALANCE_QUERY, }); } - async getDeposits({ - limit = 100, - offset = 0, - }: { limit?: number; offset?: number } = {}): Promise { - return this.apiCommunication.sendRequest( - "GET", - `/wapi/v1/capital/deposits?limit=${limit}&offset=${offset}`, - { instruction: "depositQueryAll" } + async getDeposits({ limit = 100, offset = 0 }: { limit?: number; offset?: number } = {}): Promise< + Deposit[] + > { + return this.apiClient.sendRequest( + HttpMethod.GET, + AUTHENTICATED_ENDPOINTS.DEPOSITS(limit, offset), + { instruction: INSTRUCTIONS.DEPOSIT_QUERY_ALL } ); } async getDepositAddress(blockchain: string): Promise { - return this.apiCommunication.sendRequest( - "GET", - `/wapi/v1/capital/deposit/address?blockchain=${blockchain}`, - { instruction: "depositAddressQuery" } + return this.apiClient.sendRequest( + HttpMethod.GET, + AUTHENTICATED_ENDPOINTS.DEPOSIT_ADDRESS(blockchain), + { instruction: INSTRUCTIONS.DEPOSIT_ADDRESS_QUERY } ); } - async getWithdrawals( - params: { limit?: number; offset?: number } = {} - ): Promise { + async getWithdrawals(params: { limit?: number; offset?: number } = {}): Promise { const { limit = 100, offset = 0 } = params; - return this.apiCommunication.sendRequest( - "GET", - `/wapi/v1/capital/withdrawals?limit=${limit}&offset=${offset}`, + return this.apiClient.sendRequest( + HttpMethod.GET, + AUTHENTICATED_ENDPOINTS.WITHDRAWALS(limit, offset), { - instruction: "withdrawalQueryAll", + instruction: INSTRUCTIONS.WITHDRAWAL_QUERY_ALL, } ); } @@ -68,8 +60,7 @@ export class AuthenticatedAPI { clientId?: number; twoFactorToken?: string; }): Promise { - const { address, blockchain, quantity, symbol, clientId, twoFactorToken } = - params; + const { address, blockchain, quantity, symbol, clientId, twoFactorToken } = params; const body = { address, @@ -79,14 +70,10 @@ export class AuthenticatedAPI { clientId, twoFactorToken, }; - return this.apiCommunication.sendRequest( - "POST", - "/wapi/v1/capital/withdrawals", - { - ...body, - instruction: "withdraw", - } - ); + return this.apiClient.sendRequest(HttpMethod.POST, AUTHENTICATED_ENDPOINTS.WITHDRAWALS(), { + ...body, + instruction: INSTRUCTIONS.WITHDRAW, + }); } async getOrderHistory( @@ -94,27 +81,23 @@ export class AuthenticatedAPI { ): Promise { const { limit = 100, offset = 0, symbol } = params; - let endpoint = `/wapi/v1/history/orders?limit=${limit}&offset=${offset}`; - if (symbol) { - endpoint += `&symbol=${symbol}`; - } - return this.apiCommunication.sendRequest("GET", endpoint, { - instruction: "orderHistoryQueryAll", - }); + return this.apiClient.sendRequest( + HttpMethod.GET, + AUTHENTICATED_ENDPOINTS.ORDER_HISTORY(limit, offset, symbol), + { + instruction: INSTRUCTIONS.ORDER_HISTORY_QUERY_ALL, + } + ); } - async getFillHistory( - symbol?: string, - limit: number = 100, - offset: number = 0 - ): Promise { - let endpoint = `/wapi/v1/history/fills?limit=${limit}&offset=${offset}`; - if (symbol) { - endpoint += `&symbol=${symbol}`; - } - return this.apiCommunication.sendRequest("GET", endpoint, { - instruction: "fillHistoryQueryAll", - }); + async getFillHistory(symbol?: string, limit: number = 100, offset: number = 0): Promise { + return this.apiClient.sendRequest( + HttpMethod.GET, + AUTHENTICATED_ENDPOINTS.FILL_HISTORY(limit, offset, symbol), + { + instruction: INSTRUCTIONS.FILL_HISTORY_QUERY_ALL, + } + ); } async executeOrder({ @@ -136,12 +119,7 @@ export class AuthenticatedAPI { price: number; quantity: number; quoteQuantity?: string; - selfTradePrevention?: - | string - | "RejectTaker" - | "RejectMaker" - | "RejectBoth" - | "Allow"; + selfTradePrevention?: string | "RejectTaker" | "RejectMaker" | "RejectBoth" | "Allow"; side: string | "Bid" | "Ask"; symbol: string; timeInForce?: string; @@ -160,9 +138,9 @@ export class AuthenticatedAPI { timeInForce, triggerPrice, }; - return this.apiCommunication.sendRequest("POST", "/api/v1/order", { + return this.apiClient.sendRequest(HttpMethod.POST, AUTHENTICATED_ENDPOINTS.ORDER(), { ...body, - instruction: "orderExecute", + instruction: INSTRUCTIONS.ORDER_EXECUTE, }); } @@ -175,49 +153,33 @@ export class AuthenticatedAPI { clientId?: string; symbol: string; }): Promise { - let endpoint = `/api/v1/order?`; - if (orderId) { - endpoint += `orderId=${orderId}`; - } else if (clientId) { - endpoint += `clientId=${clientId}`; - } - if (symbol) { - endpoint += `&symbol=${symbol}`; - } - return this.apiCommunication.sendRequest("GET", endpoint, { - instruction: "orderQuery", - }); + return this.apiClient.sendRequest( + HttpMethod.GET, + AUTHENTICATED_ENDPOINTS.ORDER(symbol, orderId, clientId), + { + instruction: INSTRUCTIONS.ORDER_QUERY, + } + ); } - async cancelOrder({ - orderId, - symbol, - }: { - orderId: string; - symbol: string; - }): Promise { + async cancelOrder({ orderId, symbol }: { orderId: string; symbol: string }): Promise { const body = { orderId, symbol }; - return this.apiCommunication.sendRequest("DELETE", "/api/v1/order", { + return this.apiClient.sendRequest(HttpMethod.DELETE, AUTHENTICATED_ENDPOINTS.ORDER(), { ...body, - instruction: "orderCancel", + instruction: INSTRUCTIONS.ORDER_CANCEL, }); } async getOpenOrders(symbol?: string): Promise { - let endpoint = `/api/v1/orders`; - if (symbol) { - endpoint += `?symbol=${symbol}`; - } - return this.apiCommunication.sendRequest("GET", endpoint, { - instruction: "orderQueryAll", + return this.apiClient.sendRequest(HttpMethod.GET, AUTHENTICATED_ENDPOINTS.ORDERS(symbol), { + instruction: INSTRUCTIONS.ORDER_QUERY_ALL, }); } async cancelOpenOrders(symbol: string): Promise { - const body = { symbol }; - return this.apiCommunication.sendRequest("DELETE", "/api/v1/orders", { - ...body, - instruction: "orderCancelAll", + return this.apiClient.sendRequest(HttpMethod.DELETE, AUTHENTICATED_ENDPOINTS.ORDERS(), { + symbol, + instruction: INSTRUCTIONS.ORDER_CANCEL_ALL, }); } } diff --git a/src/constants/authenticated-endpoints.ts b/src/constants/authenticated-endpoints.ts new file mode 100644 index 0000000..4f7252c --- /dev/null +++ b/src/constants/authenticated-endpoints.ts @@ -0,0 +1,53 @@ +import { BASE_URL } from "."; +import { buildUrl } from "../utils/build-url"; + +export const AUTHENTICATED_ENDPOINTS = { + CAPITAL: buildUrl({ endpoint: "/capital" }), + + DEPOSITS: (limit: number, offset: number) => + buildUrl({ + endpoint: "/capital/deposits", + baseUrl: BASE_URL.WAPI, + params: { limit: limit.toString(), offset: offset.toString() }, + }), + + DEPOSIT_ADDRESS: (blockchain: string) => + buildUrl({ + endpoint: "/capital/deposit/address", + baseUrl: BASE_URL.WAPI, + params: { blockchain }, + }), + + WITHDRAWALS: (limit?: number, offset?: number) => + buildUrl({ + endpoint: "/capital/withdrawals", + baseUrl: BASE_URL.WAPI, + params: { limit: limit?.toString(), offset: offset?.toString() }, + }), + + ORDER_HISTORY: (limit: number, offset: number, symbol?: string) => + buildUrl({ + endpoint: "/history/orders", + baseUrl: BASE_URL.WAPI, + params: { symbol, limit: limit.toString(), offset: offset.toString() }, + }), + + FILL_HISTORY: (limit: number, offset: number, symbol?: string) => + buildUrl({ + endpoint: "/history/fills", + baseUrl: BASE_URL.WAPI, + params: { symbol, limit: limit.toString(), offset: offset.toString() }, + }), + + ORDER: (symbol?: string, orderId?: string, clientId?: string) => + buildUrl({ + endpoint: "/order", + params: { symbol, orderId, clientId }, + }), + + ORDERS: (symbol?: string) => + buildUrl({ + endpoint: "/orders", + params: { symbol }, + }), +}; diff --git a/src/constants/index.ts b/src/constants/index.ts new file mode 100644 index 0000000..15972da --- /dev/null +++ b/src/constants/index.ts @@ -0,0 +1,16 @@ +const BASE_API_URL = "https://api.backpack.exchange"; + +export const API_VERSION = "v1"; + +export enum BASE_URL { + API = `${BASE_API_URL}/api/${API_VERSION}`, + WAPI = `${BASE_API_URL}/wapi/${API_VERSION}`, +} + +export enum HttpMethod { + GET = "GET", + POST = "POST", + PUT = "PUT", + PATCH = "PATCH", + DELETE = "DELETE", +} diff --git a/src/constants/instructions.ts b/src/constants/instructions.ts new file mode 100644 index 0000000..9c2732f --- /dev/null +++ b/src/constants/instructions.ts @@ -0,0 +1,14 @@ +export const INSTRUCTIONS = { + BALANCE_QUERY: "balanceQuery", + DEPOSIT_QUERY_ALL: "depositQueryAll", + DEPOSIT_ADDRESS_QUERY: "depositAddressQuery", + WITHDRAWAL_QUERY_ALL: "withdrawalQueryAll", + WITHDRAW: "withdraw", + ORDER_HISTORY_QUERY_ALL: "orderHistoryQueryAll", + FILL_HISTORY_QUERY_ALL: "fillHistoryQueryAll", + ORDER_EXECUTE: "orderExecute", + ORDER_QUERY: "orderQuery", + ORDER_CANCEL: "orderCancel", + ORDER_QUERY_ALL: "orderQueryAll", + ORDER_CANCEL_ALL: "orderCancelAll", +}; diff --git a/src/constants/market-endpoints.ts b/src/constants/market-endpoints.ts new file mode 100644 index 0000000..e371223 --- /dev/null +++ b/src/constants/market-endpoints.ts @@ -0,0 +1,37 @@ +import { buildUrl } from "../utils/build-url"; + +export const MARKET_ENDPOINTS = { + ASSETS: buildUrl({ endpoint: "/assets" }), + MARKETS: buildUrl({ endpoint: "/markets" }), + TICKERS: buildUrl({ endpoint: "/tickers" }), + STATUS: buildUrl({ endpoint: "/status" }), + PING: buildUrl({ endpoint: "/ping" }), + TIME: buildUrl({ endpoint: "/time" }), + + TICKER: (symbol: string) => buildUrl({ endpoint: "/ticker", params: { symbol } }), + + DEPTH: (symbol: string) => buildUrl({ endpoint: "/depth", params: { symbol } }), + + RECENT_TRADES: (symbol: string, limit: number) => + buildUrl({ + endpoint: "/trades", + params: { symbol, limit: limit.toString() }, + }), + + HISTORICAL_TRADES: (symbol: string, limit: number, offset: number) => + buildUrl({ + endpoint: "/trades/history", + params: { symbol, limit: limit.toString(), offset: offset.toString() }, + }), + + KLINES: (symbol: string, interval: string, startTime?: number, endTime?: number) => + buildUrl({ + endpoint: "/klines", + params: { + symbol, + interval, + startTime: startTime?.toString(), + endTime: endTime?.toString(), + }, + }), +}; diff --git a/src/market-api.ts b/src/market-api.ts index dd4ee55..8fa5926 100644 --- a/src/market-api.ts +++ b/src/market-api.ts @@ -1,38 +1,34 @@ -import { APICommunication } from "./utils/api-communication"; +import { APIClient } from "./utils/api-client"; import { Asset, Market, Ticker, Trade, Kline, SystemStatus } from "./types"; +import { MARKET_ENDPOINTS } from "./constants/market-endpoints"; +import { HttpMethod } from "./constants"; export class MarketAPI { - private apiCommunication: APICommunication; + private apiClient: APIClient; constructor() { - this.apiCommunication = new APICommunication(null); + this.apiClient = new APIClient(null); } async getAssets(): Promise { - return this.apiCommunication.sendRequest("GET", "/api/v1/assets"); + return this.apiClient.sendRequest(HttpMethod.GET, MARKET_ENDPOINTS.ASSETS); } async getMarkets(): Promise { - return this.apiCommunication.sendRequest("GET", "/api/v1/markets"); + return this.apiClient.sendRequest(HttpMethod.GET, MARKET_ENDPOINTS.MARKETS); } async getTicker(symbol: string): Promise { - return this.apiCommunication.sendRequest( - "GET", - `/api/v1/ticker?symbol=${symbol}` - ); + return this.apiClient.sendRequest(HttpMethod.GET, MARKET_ENDPOINTS.TICKER(symbol)); } async getTickers(): Promise { - return this.apiCommunication.sendRequest("GET", "/api/v1/tickers"); + return this.apiClient.sendRequest(HttpMethod.GET, MARKET_ENDPOINTS.TICKERS); } async getDepth(symbol: string): Promise { // Define a specific type for depth - return this.apiCommunication.sendRequest( - "GET", - `/api/v1/depth?symbol=${symbol}` - ); + return this.apiClient.sendRequest(HttpMethod.GET, MARKET_ENDPOINTS.DEPTH(symbol)); } async getKlines( @@ -41,29 +37,28 @@ export class MarketAPI { startTime?: number, endTime?: number ): Promise { - let url = `/api/v1/klines?symbol=${symbol}&interval=${interval}`; - if (startTime) url += `&startTime=${startTime}`; - if (endTime) url += `&endTime=${endTime}`; - - return this.apiCommunication.sendRequest("GET", url); + return this.apiClient.sendRequest( + HttpMethod.GET, + MARKET_ENDPOINTS.KLINES(symbol, interval, startTime, endTime) + ); } async getStatus(): Promise { - return this.apiCommunication.sendRequest("GET", "/api/v1/status"); + return this.apiClient.sendRequest(HttpMethod.GET, MARKET_ENDPOINTS.STATUS); } async getPing(): Promise { - return this.apiCommunication.sendRequest("GET", "/api/v1/ping"); + return this.apiClient.sendRequest(HttpMethod.GET, MARKET_ENDPOINTS.PING); } async getSystemTime(): Promise { - return this.apiCommunication.sendRequest("GET", "/api/v1/time"); + return this.apiClient.sendRequest(HttpMethod.GET, MARKET_ENDPOINTS.TIME); } async getRecentTrades(symbol: string, limit: number = 100): Promise { - return this.apiCommunication.sendRequest( - "GET", - `/api/v1/trades?symbol=${symbol}&limit=${limit}` + return this.apiClient.sendRequest( + HttpMethod.GET, + MARKET_ENDPOINTS.RECENT_TRADES(symbol, limit) ); } @@ -72,9 +67,9 @@ export class MarketAPI { limit: number = 100, offset: number = 0 ): Promise { - return this.apiCommunication.sendRequest( - "GET", - `/api/v1/trades/history?symbol=${symbol}&limit=${limit}&offset=${offset}` + return this.apiClient.sendRequest( + HttpMethod.GET, + MARKET_ENDPOINTS.HISTORICAL_TRADES(symbol, limit, offset) ); } } diff --git a/src/types.ts b/src/types.ts index 76e6b2b..dd2f405 100644 --- a/src/types.ts +++ b/src/types.ts @@ -146,12 +146,7 @@ export interface ExecuteOrderParams { price: number; quantity: number; quoteQuantity?: string; - selfTradePrevention?: - | string - | "RejectTaker" - | "RejectMaker" - | "RejectBoth" - | "Allow"; + selfTradePrevention?: string | "RejectTaker" | "RejectMaker" | "RejectBoth" | "Allow"; side: string | "Bid" | "Ask"; symbol: string; timeInForce?: string; diff --git a/src/utils/api-communication.ts b/src/utils/api-client.ts similarity index 50% rename from src/utils/api-communication.ts rename to src/utils/api-client.ts index e7ba3ae..73667fc 100644 --- a/src/utils/api-communication.ts +++ b/src/utils/api-client.ts @@ -1,17 +1,17 @@ import axios, { AxiosRequestConfig } from "axios"; import { Cryptography } from "./cryptography"; +import { HttpMethod } from "../constants"; -axios.defaults.baseURL = "https://api.backpack.exchange"; - -export class APICommunication { +export class APIClient { private cryptography: Cryptography | null; + private signatureBase64 = ""; constructor(cryptography: Cryptography | null) { this.cryptography = cryptography; } async sendRequest( - method: "GET" | "POST" | "DELETE", + method: HttpMethod, endpoint: string, additionalParams: Record = {}, headers: Record = {} @@ -19,32 +19,14 @@ export class APICommunication { const timestamp = Date.now(); const window = 60000; - const params: Record = { - ...additionalParams, - timestamp, - window, - }; - const orderedParams: Record = {}; - Object.keys(params) - .sort() - .forEach((key) => { - orderedParams[key] = params[key]; - }); - - const paramString = Object.entries(orderedParams) - .map(([key, value]) => `${key}=${value}`) - .join("&"); - - let signatureBase64 = ""; if (this.cryptography) { - const encodedParams = this.cryptography.encodeParams(paramString); - const signature = this.cryptography.generateSignature(encodedParams); - signatureBase64 = this.cryptography.encodeBase64(signature); + const paramString = this.buildOrderedParamString(timestamp, window, additionalParams); + this.signatureBase64 = this.createSignature(paramString); } const requestHeaders = { "X-API-Key": this.cryptography ? this.cryptography.getApiKeyBase64() : "", - "X-Signature": signatureBase64, + "X-Signature": this.signatureBase64, "X-Timestamp": timestamp, "X-Window": window, "Content-Type": "application/json", @@ -68,4 +50,30 @@ export class APICommunication { console.log(error); } } + + private buildOrderedParamString( + timestamp: number, + window: number, + additionalParams: Record = {} + ) { + const params = new URLSearchParams(); + + params.append("timestamp", timestamp.toString()); + params.append("window", window.toString()); + + Object.entries(additionalParams).forEach(([key, value]) => { + params.append(key, value); + }); + + const orderedParams = Array.from(params.entries()).sort(); + return new URLSearchParams(orderedParams).toString(); + } + + private createSignature(paramString: string) { + if (!this.cryptography) return ""; + + const encodedParams = this.cryptography.encodeParams(paramString); + const signature = this.cryptography.generateSignature(encodedParams); + return this.cryptography.encodeBase64(signature); + } } diff --git a/src/utils/build-url.ts b/src/utils/build-url.ts new file mode 100644 index 0000000..d0a57cb --- /dev/null +++ b/src/utils/build-url.ts @@ -0,0 +1,18 @@ +import { BASE_URL } from "../constants"; + +export function buildUrl(options: { + endpoint: string; + params?: Record; + baseUrl?: BASE_URL; +}) { + options.params = options.params || {}; + options.baseUrl = options.baseUrl || BASE_URL.API; + + const url = new URL(`${options.baseUrl}${options.endpoint}`); + + Object.entries(options.params).forEach(([key, value]) => { + if (!value) return; + url.searchParams.append(key, value); + }); + return url.toString(); +} diff --git a/src/utils/cryptography.ts b/src/utils/cryptography.ts index 7dbb320..6fc568d 100644 --- a/src/utils/cryptography.ts +++ b/src/utils/cryptography.ts @@ -16,10 +16,7 @@ export class Cryptography { } generateSignature(encodedParams: Uint8Array): Uint8Array { - const signatureKey = new Uint8Array([ - ...this.secretKeyUint8Array, - ...this.apiKeyUint8Array, - ]); + const signatureKey = new Uint8Array([...this.secretKeyUint8Array, ...this.apiKeyUint8Array]); return nacl.sign.detached(encodedParams, signatureKey); } diff --git a/tests/authenticated-api.test.ts b/tests/authenticated-api.test.ts index fabe02a..4feb1f6 100644 --- a/tests/authenticated-api.test.ts +++ b/tests/authenticated-api.test.ts @@ -86,9 +86,7 @@ describe("AuthenticatedAPI", () => { }); test("cancelOpenOrders", async () => { - const cancelOpenOrders = await authenticatedApi.cancelOpenOrders( - "SOL_USDC" - ); + const cancelOpenOrders = await authenticatedApi.cancelOpenOrders("SOL_USDC"); expect(cancelOpenOrders).toBeDefined(); }); });