diff --git a/src/constants/nearClient.ts b/src/constants/nearClient.ts index 83ec7e60..fa7a17bd 100644 --- a/src/constants/nearClient.ts +++ b/src/constants/nearClient.ts @@ -1,4 +1,4 @@ -import { nearFailoverRpcProvider } from "../utils/failover" +import { nearFailoverRpcProvider } from "@defuse-protocol/internal-utils" import { settings } from "./settings" /** diff --git a/src/queries/solverLiquidityQuerires.ts b/src/queries/solverLiquidityQuerires.ts index f6c5692d..0ecb9cd3 100644 --- a/src/queries/solverLiquidityQuerires.ts +++ b/src/queries/solverLiquidityQuerires.ts @@ -1,6 +1,6 @@ +import { request } from "@defuse-protocol/internal-utils" import { useQuery } from "@tanstack/react-query" import { config as globalConfig } from "../config" -import { request } from "../utils/request" export interface GetSolverLiquidityResponse { address_from: string diff --git a/src/sdk/hyperunit/apis.ts b/src/sdk/hyperunit/apis.ts index aafd37c9..5e1e1ef2 100644 --- a/src/sdk/hyperunit/apis.ts +++ b/src/sdk/hyperunit/apis.ts @@ -1,4 +1,4 @@ -import { request } from "../../utils/request" +import { request } from "@defuse-protocol/internal-utils" import type { GeneratHLAddressParams, GeneratHLAddressResponse, diff --git a/src/sdk/hyperunit/types.ts b/src/sdk/hyperunit/types.ts index 41902a72..3eacf170 100644 --- a/src/sdk/hyperunit/types.ts +++ b/src/sdk/hyperunit/types.ts @@ -1,4 +1,4 @@ -export type { RequestErrorType } from "../../utils/request" +export type { RequestErrorType } from "@defuse-protocol/internal-utils" export type RequestConfig = { timeout?: number | undefined diff --git a/src/sdk/tokensUsdPricesHttpClient/apis.ts b/src/sdk/tokensUsdPricesHttpClient/apis.ts index 59fd594e..6b2c5052 100644 --- a/src/sdk/tokensUsdPricesHttpClient/apis.ts +++ b/src/sdk/tokensUsdPricesHttpClient/apis.ts @@ -1,5 +1,5 @@ +import { request } from "@defuse-protocol/internal-utils" import { config as globalConfig } from "../../config" -import { request } from "../../utils/request" import type { RequestConfig, TokensUsdPricesPayload } from "./types" export async function tokens( diff --git a/src/sdk/tokensUsdPricesHttpClient/types.ts b/src/sdk/tokensUsdPricesHttpClient/types.ts index cb082ef8..39cabba3 100644 --- a/src/sdk/tokensUsdPricesHttpClient/types.ts +++ b/src/sdk/tokensUsdPricesHttpClient/types.ts @@ -1,4 +1,4 @@ -export type { RequestErrorType } from "../../utils/request" +export type { RequestErrorType } from "@defuse-protocol/internal-utils" export type RequestConfig = { timeout?: number | undefined diff --git a/src/utils/failover.test.ts b/src/utils/failover.test.ts deleted file mode 100644 index 9a60a910..00000000 --- a/src/utils/failover.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { providers } from "near-api-js" -import type { FailoverRpcProvider } from "near-api-js/lib/providers" -import { beforeEach, describe, expect, it, vi } from "vitest" -import { createNearFailoverRpcProvider } from "./failover" - -const unstableRpcProvider = { - startTime: Date.now(), - status: vi.fn(() => { - if (Date.now() - unstableRpcProvider.startTime > 500) { - throw new Error("rpc down") - } - return { status: 200, result: "ok", id: 1 } - }), -} - -const stableRpcProvider = { - status: vi.fn(() => { - return { status: 200, result: "ok", id: 2 } - }), -} - -const providers_ = [ - Object.setPrototypeOf( - unstableRpcProvider, - providers.JsonRpcProvider.prototype - ), - Object.setPrototypeOf(stableRpcProvider, providers.JsonRpcProvider.prototype), -] - -describe("createNearFailoverRpcProvider", () => { - let nearClient: FailoverRpcProvider - - beforeEach(() => { - nearClient = createNearFailoverRpcProvider({ providers: providers_ }) - vi.spyOn(nearClient, "status") - }) - - it("should return the status of the first provider when it is operational", async () => { - const response = unstableRpcProvider.status() - expect(response.status).toBe(200) - expect(await nearClient.status()).toStrictEqual(response) - }) - - it("should switch to the second provider after 500ms if the first provider becomes unresponsive", async () => { - const response = stableRpcProvider.status() - vi.useFakeTimers() - vi.advanceTimersByTime(500) - - // Suppress error output - console.error = vi.fn() - - expect(await nearClient.status()).toStrictEqual(response) - vi.useRealTimers() - }) -}) diff --git a/src/utils/failover.ts b/src/utils/failover.ts deleted file mode 100644 index d87a9590..00000000 --- a/src/utils/failover.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { providers } from "near-api-js" -import { FailoverRpcProvider } from "near-api-js/lib/providers" - -/** - * @note This function is specifically designed for NEAR RPC providers and should not be used with other blockchain networks. - * It creates a failover provider that will automatically switch between the provided RPC endpoints if one fails. - */ -export function nearFailoverRpcProvider({ urls }: { urls: string[] }) { - const providers_ = urls.map((url) => new providers.JsonRpcProvider({ url })) - return createNearFailoverRpcProvider({ providers: providers_ }) -} - -export function createNearFailoverRpcProvider({ - providers, -}: { providers: providers.JsonRpcProvider[] }) { - return new FailoverRpcProvider(providers) -} diff --git a/src/utils/promise/withTimeout.ts b/src/utils/promise/withTimeout.ts deleted file mode 100644 index 97e344c0..00000000 --- a/src/utils/promise/withTimeout.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { ErrorType } from "../../errors/types" - -export type WithTimeoutErrorType = ErrorType - -export function withTimeout( - fn: ({ - signal, - }: { signal: AbortController["signal"] | null }) => Promise, - { - errorInstance = new Error("timed out"), - timeout, - signal, - }: { - // The error instance to throw when the timeout is reached. - errorInstance?: Error | undefined - // The timeout (in ms). - timeout: number - // Whether or not the timeout should use an abort signal. - signal?: boolean | undefined - } -): Promise { - return new Promise((resolve, reject) => { - ;(async () => { - let timeoutId!: NodeJS.Timeout - try { - const controller = new AbortController() - if (timeout > 0) { - timeoutId = setTimeout(() => { - if (signal) { - controller.abort() - } else { - reject(errorInstance) - } - }, timeout) as NodeJS.Timeout // need to cast because bun globals.d.ts overrides @types/node - } - resolve(await fn({ signal: controller?.signal || null })) - } catch (err) { - if ((err as Error)?.name === "AbortError") reject(errorInstance) - reject(err) - } finally { - clearTimeout(timeoutId) - } - })() - }) -} diff --git a/src/utils/request.ts b/src/utils/request.ts deleted file mode 100644 index fd396ad5..00000000 --- a/src/utils/request.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { HttpRequestError, TimeoutError } from "../errors/request" -import { isNetworkError } from "../errors/utils/isNetworkError" -import { withTimeout } from "./promise/withTimeout" - -export type RequestErrorType = HttpRequestError | TimeoutError - -export async function request({ - url, - body, - timeout = 10_000, - fetchOptions, -}: { - url: string | URL - body?: unknown | undefined - timeout?: number | undefined - fetchOptions?: Omit | undefined -}): Promise { - const { headers, method, signal: signal_ } = fetchOptions ?? {} - - try { - const response = await withTimeout( - ({ signal }) => { - return fetch(url, { - ...fetchOptions, - method: method, - headers: { - "Content-Type": "application/json", - ...headers, - }, - body: JSON.stringify(body), - signal: signal_ || (timeout > 0 ? signal : null), - }) - }, - { - errorInstance: new TimeoutError({ body, url: url.toString() }), - timeout, - signal: true, - } - ) - - if (!response.ok) { - throw new HttpRequestError({ - body, - details: response.statusText, - headers: response.headers, - status: response.status, - url: url.toString(), - }) - } - - return response - } catch (err: unknown) { - if (err instanceof HttpRequestError) throw err - if (err instanceof TimeoutError) throw err - - if (isNetworkError(err)) { - throw new HttpRequestError({ - body, - cause: err as Error, - url: url.toString(), - }) - } - - throw err - } -}