11import {
22 BaseError ,
3- type ClientConfig ,
43 type EIP1193RequestFn ,
54 HttpRequestError ,
65 type HttpTransport ,
@@ -16,14 +15,30 @@ import {
1615 withRetry ,
1716} from "viem" ;
1817import type { HttpRpcClientOptions } from "viem/utils" ;
19- import type { ILogger , NetworkType } from "../sdk/index.js" ;
18+ import { z } from "zod/v4" ;
19+ import { type ILogger , NetworkType } from "../sdk/index.js" ;
20+ import { httpTransportConfigSchema } from "./transports.js" ;
2021
21- export interface ProviderConfig {
22- name : string ;
23- url : string ;
24- cooldown ?: number ;
25- httpClientOptions ?: HttpRpcClientOptions | undefined ;
26- }
22+ export const providerConfigSchema = z . object ( {
23+ /**
24+ * Provider name for display purposes
25+ */
26+ name : z . string ( ) ,
27+ /**
28+ * Provider URL
29+ */
30+ url : z . url ( ) ,
31+ /**
32+ * How long, in milliseconds, to wait before try this provider again
33+ */
34+ cooldown : z . number ( ) . optional ( ) ,
35+ /**
36+ * HTTP transport options to use for this provider
37+ */
38+ httpClientOptions : httpTransportConfigSchema . optional ( ) ,
39+ } ) ;
40+
41+ export type ProviderConfig = z . infer < typeof providerConfigSchema > ;
2742
2843interface TransportEntry {
2944 name : string ;
@@ -49,23 +64,42 @@ type OnResponseFn = (
4964 ...args : Parameters < Required < HttpRpcClientOptions > [ "onResponse" ] >
5065) => ReturnType < Required < HttpRpcClientOptions > [ "onResponse" ] > ;
5166
67+ export const SelectionStrategy = z . enum ( [ "simple" , "ordered" ] ) ;
68+
5269/**
5370 * How to select the next transport
5471 * - simple: selects next transport after current that is not in cooldown by checking all transports in cyclic order
5572 * - ordered: will select first available transport that is not in cooldown
5673 */
57- export type SelectionStrategy = "simple" | "ordered" ;
74+ export type SelectionStrategy = z . infer < typeof SelectionStrategy > ;
75+
76+ export const revolverTransportConfigSchema = z . object ( {
77+ network : NetworkType ,
78+ /**
79+ * Providers to use
80+ */
81+ providers : z . array ( providerConfigSchema ) ,
82+ /**
83+ * How to select the next transport
84+ * Defaults to "simple"
85+ */
86+ selectionStrategy : SelectionStrategy . optional ( ) ,
87+ /** The key of the transport. */
88+ key : z . string ( ) . optional ( ) ,
89+ /** The name of the transport. */
90+ name : z . string ( ) . optional ( ) ,
91+ /**
92+ * Default HTTP options to use for all providers, can be overridden by provider config
93+ */
94+ defaultHTTPOptions : httpTransportConfigSchema . optional ( ) ,
95+ /**
96+ * Default cooldown, in milliseconds, to wait before try this transport again
97+ */
98+ defaultCooldown : z . number ( ) . optional ( ) ,
99+ } ) ;
58100
59- export interface RevolverTransportConfig {
60- network : NetworkType ;
61- providers : ProviderConfig [ ] ;
101+ export type RevolverTransportConfig = {
62102 logger ?: ILogger ;
63- key ?: TransportConfig [ "key" ] | undefined ;
64- name ?: TransportConfig [ "name" ] | undefined ;
65- pollingInterval ?: ClientConfig [ "pollingInterval" ] | undefined ;
66- retryCount ?: TransportConfig [ "retryCount" ] | undefined ;
67- retryDelay ?: TransportConfig [ "retryDelay" ] | undefined ;
68- timeout ?: TransportConfig [ "timeout" ] | undefined ;
69103 /**
70104 * When single http transport should retry?
71105 * Defaults to some less strict criteria, so it'll retry "blockNumber from the future" errors
@@ -78,10 +112,6 @@ export interface RevolverTransportConfig {
78112 shouldRetry ?:
79113 | ( ( iter : { count : number ; error : Error } ) => Promise < boolean > | boolean )
80114 | undefined ;
81- /**
82- * Allow batching of json-rpc requests
83- */
84- batch ?: boolean | undefined ;
85115 /**
86116 * Spying function that also returns provider name in additional to the request
87117 */
@@ -105,16 +135,7 @@ export interface RevolverTransportConfig {
105135 oldTransportName : string ,
106136 reason ?: BaseError ,
107137 ) => void | Promise < void > ;
108- /**
109- * How long, in milliseconds, to wait before try this transport again
110- */
111- cooldown ?: number | undefined ;
112- /**
113- * How to select the next transport
114- * Defaults to "simple"
115- */
116- selectionStrategy ?: SelectionStrategy ;
117- }
138+ } & z . infer < typeof revolverTransportConfigSchema > ;
118139
119140export class NoAvailableTransportsError extends BaseError {
120141 constructor ( cause ?: Error ) {
@@ -184,11 +205,8 @@ export class RevolverTransport
184205 ( { url, name, cooldown, httpClientOptions } ) : TransportEntry => ( {
185206 name,
186207 transport : http ( url , {
208+ ...config . defaultHTTPOptions ,
187209 ...httpClientOptions ,
188- retryCount : config . retryCount ,
189- retryDelay : config . retryDelay ,
190- timeout : config . timeout ,
191- batch : ! ! config . batch ,
192210 key : name ,
193211 name : name ,
194212 onFetchRequest : this . #config. onRequest
@@ -209,8 +227,8 @@ export class RevolverTransport
209227 const selectionStrategy = config . selectionStrategy ?? "simple" ;
210228 this . #selector =
211229 selectionStrategy === "simple"
212- ? new SimpleTransportSelector ( transports , config . cooldown )
213- : new OrderedTransportSelector ( transports , config . cooldown ) ;
230+ ? new SimpleTransportSelector ( transports , config . defaultCooldown )
231+ : new OrderedTransportSelector ( transports , config . defaultCooldown ) ;
214232 }
215233
216234 public get value ( ) : RevolverTransportValue {
@@ -241,8 +259,8 @@ export class RevolverTransport
241259
242260 // for explanation, see shouldRetry comment
243261 const resp = await withRetry ( ( ) => transport . request ( r ) , {
244- delay : this . #config. retryDelay ,
245- retryCount : this . #config. retryCount ,
262+ delay : this . #config. defaultHTTPOptions ?. retryDelay ,
263+ retryCount : this . #config. defaultHTTPOptions ?. retryCount ,
246264 shouldRetry : this . #config. shouldRetry ,
247265 } ) ;
248266 this . #requests. delete ( r ) ;
@@ -275,10 +293,10 @@ export class RevolverTransport
275293 name : "revolver" ,
276294 type : "revolver" ,
277295 request : this . request ,
278- retryCount : this . #config. retryCount ,
279- methods : undefined ,
280- retryDelay : this . #config. retryDelay ,
281- timeout : this . #config. timeout ,
296+ retryCount : this . #config. defaultHTTPOptions ?. retryCount ,
297+ methods : this . #config . defaultHTTPOptions ?. methods ,
298+ retryDelay : this . #config. defaultHTTPOptions ?. retryDelay ,
299+ timeout : this . #config. defaultHTTPOptions ?. timeout ,
282300 } ;
283301 }
284302
0 commit comments