UNPKG

@atomiqlabs/chain-starknet

Version:
108 lines (94 loc) 3.98 kB
import { RPC09, RPC010, RpcProvider, RpcProviderOptions } from "starknet"; import {tryWithRetries} from "../../utils/Utils"; /** * @private */ export class Rpc09ChannelWithRetries extends RPC09.RpcChannel { private readonly retryPolicy?: { maxRetries?: number, delay?: number, exponential?: boolean }; constructor(options?: RpcProviderOptions, retryPolicy?: { maxRetries?: number, delay?: number, exponential?: boolean }) { super(options); this.retryPolicy = retryPolicy; } protected fetchEndpoint(method: any, params?: any): Promise<any> { return tryWithRetries(() => super.fetchEndpoint(method, params), this.retryPolicy, e => { if(!e.message.startsWith("RPC: ")) return false; if(e.message.includes("Unsupported method")) return true; const arr = e.message.split("\n"); const errorCode = parseInt(arr[arr.length-1]); if(isNaN(errorCode)) return false; if(errorCode < 0) return false; //Not defined error, e.g. Rate limit (-32097) return true; }); } } /** * @private */ export class Rpc010ChannelWithRetries extends RPC010.RpcChannel { readonly retryPolicy?: { maxRetries?: number, delay?: number, exponential?: boolean }; constructor(options?: RpcProviderOptions, retryPolicy?: { maxRetries?: number, delay?: number, exponential?: boolean }) { super(options); this.retryPolicy = retryPolicy; } protected fetchEndpoint(method: any, params?: any): Promise<any> { return tryWithRetries(() => super.fetchEndpoint(method, params), this.retryPolicy, e => { if(!e.message.startsWith("RPC: ")) return false; if(e.message.includes("Unsupported method")) return true; const arr = e.message.split("\n"); const errorCode = parseInt(arr[arr.length-1]); if(isNaN(errorCode)) return false; if(errorCode < 0) return false; //Not defined error, e.g. Rate limit (-32097) return true; }); } } /** * An RPC provider with built-in retry functionality, retries calls to the RPC service on failure * * @category Providers */ export class RpcProviderWithRetries extends RpcProvider { /** * Creates a new RPC provider which retries RPC calls on failure, controlled by the passed `retryPolicy` * NOTE: Tries to do naive detection of the spec version based on the suffix of nodeUrl, better pass the `options.specVersion` * in the options! * * @param options * @param retryPolicy */ constructor(options?: RpcProviderOptions, retryPolicy?: { maxRetries?: number, delay?: number, exponential?: boolean }) { options ??= {}; if(options.specVersion==null) { // Default to RPC 0.10.0 (starknetjs v9 default), fallback to 0.9.0 if URL indicates v0_9 if(options.nodeUrl?.endsWith("v0_9")) { (options as any).specVersion = "0.9.0"; } else { // Default to 0.10.0 for v9 (options as any).specVersion = "0.10.0"; } } super(options); const channelId = this.channel.id as string; if(channelId==="RPC090") { this.channel = new Rpc09ChannelWithRetries({ ...options, waitMode: false }, retryPolicy); } else if(channelId==="RPC0100" || channelId==="RPC010" || channelId==="RPC0.10.0" || (channelId && !channelId.startsWith("RPC08"))) { // Handle RPC 0.10 (default in starknetjs v9) - channel ID might be "RPC0100", "RPC010", or other format // Also handle any non-RPC08/RPC09 channel as RPC 0.10 this.channel = new Rpc010ChannelWithRetries({ ...options, waitMode: false }, retryPolicy); } } }