diff --git a/src/index.ts b/src/index.ts index 80efdcd0..967102d7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,4 +6,5 @@ export * from './fetch'; export * from './inflight-cache'; export * from './providerAsMiddleware'; export * from './retryOnEmpty'; +export * from './retryOnRateLimit'; export * from './wallet'; diff --git a/src/retryOnRateLimit.ts b/src/retryOnRateLimit.ts new file mode 100644 index 00000000..8fba97f7 --- /dev/null +++ b/src/retryOnRateLimit.ts @@ -0,0 +1,23 @@ +import { EthereumRpcError, errorCodes } from 'eth-rpc-errors'; +import type { JsonRpcMiddleware } from 'json-rpc-engine'; +import { createAsyncMiddleware } from 'json-rpc-engine'; +import { timeout } from './utils/timeout'; + +export function createRetryOnRateLimitMiddleware(): JsonRpcMiddleware { + return createAsyncMiddleware(async (_req, _res, next) => { + const maxAttempts = 5; + const retryInterval = 800; + for (let attempt = 0; attempt < maxAttempts; attempt++) { + try { + return next(); + } catch (err) { + if (!(err instanceof EthereumRpcError && + err.code == errorCodes.rpc.limitExceeded)) { + // re-throw error if not limit exceeded + throw err; + } + await timeout(retryInterval); + } + } + }); +} \ No newline at end of file