UNPKG

@bigmi/core

Version:

TypeScript library for Bitcoin apps.

111 lines 4.05 kB
import { BaseError } from '../errors/base.js'; import { HttpRequestError } from '../errors/request.js'; import { MethodNotSupportedRpcError, RpcErrorCode, UserRejectedRequestError, } from '../errors/rpc.js'; import { stringToHex } from './converter.js'; import { stringify } from './stringify.js'; import { withDedupe } from './withDedupe.js'; import { withRetry } from './withRetry.js'; export function buildRequest(request, options = {}) { return async (args, overrideOptions = {}) => { const { dedupe = false, methods, retryDelay = 150, retryCount = 3, uid, } = { ...options, ...overrideOptions, }; const { method } = args; if (methods?.exclude?.includes(method)) { throw new MethodNotSupportedRpcError(method); } if (methods?.include && !methods.include.includes(method)) { throw new MethodNotSupportedRpcError(method); } const requestId = dedupe ? stringToHex(`${uid}.${stringify(args)}`) : undefined; return withDedupe(() => withRetry(async () => { try { return await request(args); } catch (err_) { const err = err_; switch (err.code) { case RpcErrorCode.METHOD_NOT_SUPPORTED: throw new MethodNotSupportedRpcError(method); case RpcErrorCode.USER_REJECTION: throw new UserRejectedRequestError(err.message); // CAIP-25: User Rejected Error // https://docs.walletconnect.com/2.0/specs/clients/sign/error-codes#rejected-caip-25 case 5000: throw new UserRejectedRequestError(err.message); default: if (err_ instanceof BaseError) { throw err_; } throw new BaseError('Unknown Error', { cause: err_ }); } } }, { delay: ({ count, error }) => { // If we find a Retry-After header, let's retry after the given time. if (error && error instanceof HttpRequestError) { const retryAfter = error?.headers?.get('Retry-After'); if (retryAfter?.match(/\d/)) { return Number.parseInt(retryAfter, 10) * 1000; } } // Otherwise, let's retry with an exponential backoff. return ~~(1 << count) * retryDelay; }, retryCount, shouldRetry: ({ error }) => shouldRetry(error), }), { enabled: dedupe, id: requestId }); }; } /** @internal */ export function shouldRetry(error) { if ('code' in error && typeof error.code === 'number') { if (error.code === -1) { return true; // Unknown error } if (error.code === RpcErrorCode.INTERNAL_ERROR) { return true; } return false; } if (error instanceof HttpRequestError && error.status) { // Forbidden if (error.status === 403) { return true; } // Request Timeout if (error.status === 408) { return true; } // Request Entity Too Large if (error.status === 413) { return true; } // Too Many Requests if (error.status === 429) { return true; } // Internal Server Error if (error.status === 500) { return true; } // Bad Gateway if (error.status === 502) { return true; } // Service Unavailable if (error.status === 503) { return true; } // Gateway Timeout if (error.status === 504) { return true; } return false; } return true; } //# sourceMappingURL=buildRequest.js.map