diff --git a/packages/extension-chrome/__tests__/services/ownership/backend/backendUtil.test.ts b/packages/extension-chrome/__tests__/services/ownership/backend/request.ts similarity index 70% rename from packages/extension-chrome/__tests__/services/ownership/backend/backendUtil.test.ts rename to packages/extension-chrome/__tests__/services/ownership/backend/request.ts index 17a7efc1..4f68ec67 100644 --- a/packages/extension-chrome/__tests__/services/ownership/backend/backendUtil.test.ts +++ b/packages/extension-chrome/__tests__/services/ownership/backend/request.ts @@ -1,5 +1,5 @@ import fetchMock from 'jest-fetch-mock'; -import { createRpcClient } from '../../../../src/services/ownership/backend/backendUtils'; +import { requestWithRetries } from '../../../../src/services/ownership/backend/request'; describe('refetch', () => { beforeAll(() => { @@ -11,9 +11,7 @@ describe('refetch', () => { it('should refetch when first request fails', async () => { fetchMock.mockRejectOnce(new Error('some error')); fetchMock.mockResponse(JSON.stringify({ result: 'some result' })); - const { request } = createRpcClient(''); - await request('some_method', {}); - + await requestWithRetries(() => fetch('http://dummy')); expect(fetch).toBeCalledTimes(2); }); }); diff --git a/packages/extension-chrome/src/services/ownership/backend/backendUtils.ts b/packages/extension-chrome/src/services/ownership/backend/backendUtils.ts index 8ad0145c..7e760cce 100644 --- a/packages/extension-chrome/src/services/ownership/backend/backendUtils.ts +++ b/packages/extension-chrome/src/services/ownership/backend/backendUtils.ts @@ -3,9 +3,8 @@ import { asserts } from '@nexus-wallet/utils'; import { ScriptConfig } from '@ckb-lumos/config-manager'; import { JSONRPCRequest, JSONRPCResponse } from 'json-rpc-2.0'; import { RPC as RpcType } from '@ckb-lumos/rpc/lib/types/rpc'; +import { RequestOptions, requestWithRetries } from './request'; import { NexusCommonErrors } from '../../../errors'; -import pTimeout from './thirdpartyLib/p-timeout'; -import pRetry from './thirdpartyLib/p-retry'; type Order = 'asc' | 'desc'; type Limit = HexNumber; @@ -91,39 +90,22 @@ type RpcClient = { batchRequest: (method: string, batchParams: Params[]) => Promise; }; -type RpcClientOptions = { - timeout?: number; // in milliseconds - maxRetries?: number; -}; - -function createRpcClient(url: string, options?: RpcClientOptions): RpcClient { +function createRpcClient(url: string, options?: RequestOptions): RpcClient { // auto-increment id let jsonRpcId = 0; async function _request(body: JSONRPCRequest | JSONRPCRequest[]): Promise { ++jsonRpcId; - const retryRunner = async () => { - const res = await fetch(url, { + const fetchProvider = () => + fetch(url, { method: 'POST', body: JSON.stringify(body), headers: { 'Content-Type': 'application/json', }, }); - // Abort retrying if the resource doesn't exist - if (res.status >= 300) { - /* istanbul ignore next */ - throw NexusCommonErrors.RequestCkbFailed(res); - } - return res.json(); - }; - - const retryPromise = pRetry(retryRunner, { retries: options?.maxRetries || 5 }); - const res = await pTimeout(retryPromise, { - milliseconds: options?.timeout || 5_000, - }); - return res as Promise; + return requestWithRetries(fetchProvider, options); } async function request(method: string, params: Params): Promise { diff --git a/packages/extension-chrome/src/services/ownership/backend/request.ts b/packages/extension-chrome/src/services/ownership/backend/request.ts new file mode 100644 index 00000000..a58a8961 --- /dev/null +++ b/packages/extension-chrome/src/services/ownership/backend/request.ts @@ -0,0 +1,31 @@ +import { JSONRPCResponse } from 'json-rpc-2.0'; +import { NexusCommonErrors } from '../../../errors'; +import pRetry from './thirdpartyLib/p-retry'; +import pTimeout from './thirdpartyLib/p-timeout'; + +export type RequestOptions = { + timeout?: number; // in milliseconds + maxRetries?: number; +}; + +export const requestWithRetries = async ( + promiseCtor: () => Promise, + options?: RequestOptions, +): Promise => { + const retryRunner = async () => { + const res = await promiseCtor(); + // Abort retrying if the resource doesn't exist + if (res.status >= 300) { + /* istanbul ignore next */ + throw NexusCommonErrors.RequestCkbFailed(res); + } + return res.json(); + }; + + const retryPromise = pRetry(retryRunner, { retries: options?.maxRetries || 5 }); + const res = await pTimeout(retryPromise, { + milliseconds: options?.timeout || 5_000, + }); + + return res as Promise; +};