@across-protocol/sdk 4.3.72 → 4.3.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/arch/svm/SpokeUtils.js +1 -1
- package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/cjs/arch/svm/provider.d.ts +12 -1
- package/dist/cjs/arch/svm/provider.js +17 -6
- package/dist/cjs/arch/svm/provider.js.map +1 -1
- package/dist/cjs/arch/svm/utils.d.ts +0 -1
- package/dist/cjs/arch/svm/utils.js +1 -3
- package/dist/cjs/arch/svm/utils.js.map +1 -1
- package/dist/cjs/providers/solana/quorumFallbackRpcFactory.d.ts +1 -1
- package/dist/cjs/providers/solana/quorumFallbackRpcFactory.js +7 -3
- package/dist/cjs/providers/solana/quorumFallbackRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/retryRpcFactory.d.ts +1 -2
- package/dist/cjs/providers/solana/retryRpcFactory.js +4 -16
- package/dist/cjs/providers/solana/retryRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/utils.d.ts +1 -0
- package/dist/cjs/providers/solana/utils.js +15 -0
- package/dist/cjs/providers/solana/utils.js.map +1 -1
- package/dist/esm/arch/svm/SpokeUtils.js +1 -1
- package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/esm/arch/svm/provider.d.ts +28 -1
- package/dist/esm/arch/svm/provider.js +29 -1
- package/dist/esm/arch/svm/provider.js.map +1 -1
- package/dist/esm/arch/svm/utils.d.ts +0 -1
- package/dist/esm/arch/svm/utils.js +0 -1
- package/dist/esm/arch/svm/utils.js.map +1 -1
- package/dist/esm/providers/solana/quorumFallbackRpcFactory.d.ts +1 -1
- package/dist/esm/providers/solana/quorumFallbackRpcFactory.js +8 -3
- package/dist/esm/providers/solana/quorumFallbackRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/retryRpcFactory.d.ts +1 -8
- package/dist/esm/providers/solana/retryRpcFactory.js +4 -24
- package/dist/esm/providers/solana/retryRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/utils.d.ts +7 -0
- package/dist/esm/providers/solana/utils.js +22 -1
- package/dist/esm/providers/solana/utils.js.map +1 -1
- package/dist/types/arch/svm/provider.d.ts +28 -1
- package/dist/types/arch/svm/provider.d.ts.map +1 -1
- package/dist/types/arch/svm/utils.d.ts +0 -1
- package/dist/types/arch/svm/utils.d.ts.map +1 -1
- package/dist/types/providers/solana/quorumFallbackRpcFactory.d.ts +1 -1
- package/dist/types/providers/solana/quorumFallbackRpcFactory.d.ts.map +1 -1
- package/dist/types/providers/solana/retryRpcFactory.d.ts +1 -8
- package/dist/types/providers/solana/retryRpcFactory.d.ts.map +1 -1
- package/dist/types/providers/solana/utils.d.ts +7 -0
- package/dist/types/providers/solana/utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/arch/svm/SpokeUtils.ts +1 -1
- package/src/arch/svm/provider.ts +46 -1
- package/src/arch/svm/utils.ts +0 -3
- package/src/providers/solana/quorumFallbackRpcFactory.ts +10 -4
- package/src/providers/solana/retryRpcFactory.ts +5 -27
- package/src/providers/solana/utils.ts +24 -0
|
@@ -5,7 +5,6 @@ import { RelayData, RelayDataWithMessageHash } from "../../interfaces";
|
|
|
5
5
|
import { BigNumber, Address as SdkAddress } from "../../utils";
|
|
6
6
|
import { AttestedCCTPMessage, EventName, SVMProvider, LatestBlockhash } from "./types";
|
|
7
7
|
import winston from "winston";
|
|
8
|
-
export { isSolanaError } from "@solana/kit";
|
|
9
8
|
/**
|
|
10
9
|
* Basic void TransactionSigner type
|
|
11
10
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/arch/svm/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgD,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC1G,OAAO,EAAuB,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EACL,OAAO,EACP,YAAY,EACZ,aAAa,EAcb,KAAK,UAAU,EACf,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAY,SAAS,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,OAAO,IAAI,UAAU,EAAkD,MAAM,aAAa,CAAC;AAE/G,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAiB,WAAW,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACtG,OAAO,OAAO,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/arch/svm/utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { Logger } from "winston";
|
|
1
2
|
import { RpcFromTransport, RpcTransport, SolanaRpcApiFromTransport } from "@solana/kit";
|
|
2
3
|
import { CachedSolanaRpcFactory } from "./cachedRpcFactory";
|
|
3
4
|
import { SolanaBaseRpcFactory } from "./baseRpcFactories";
|
|
4
|
-
import { Logger } from "winston";
|
|
5
5
|
export declare class QuorumFallbackSolanaRpcFactory extends SolanaBaseRpcFactory {
|
|
6
6
|
readonly nodeQuorumThreshold: number;
|
|
7
7
|
readonly logger: Logger;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quorumFallbackRpcFactory.d.ts","sourceRoot":"","sources":["../../../../src/providers/solana/quorumFallbackRpcFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAe,YAAY,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"quorumFallbackRpcFactory.d.ts","sourceRoot":"","sources":["../../../../src/providers/solana/quorumFallbackRpcFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAe,YAAY,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAGrG,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAA2B,MAAM,oBAAoB,CAAC;AAMnF,qBAAa,8BAA+B,SAAQ,oBAAoB;IASpE,QAAQ,CAAC,mBAAmB,EAAE,MAAM;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM;IATzB,QAAQ,CAAC,YAAY,EAAE;QACrB,SAAS,EAAE,YAAY,CAAC;QACxB,SAAS,EAAE,gBAAgB,CAAC,yBAAyB,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,CAAC;QACnF,UAAU,EAAE,sBAAsB,CAAC;KACpC,EAAE,CAAM;gBAGP,wBAAwB,EAAE,qBAAqB,CAAC,OAAO,sBAAsB,CAAC,EAAE,EACvE,mBAAmB,EAAE,MAAM,EAC3B,MAAM,EAAE,MAAM;IAkBlB,eAAe,IAAI,YAAY;IAsMtC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,MAAM;CAY5D"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { Logger } from "winston";
|
|
1
2
|
import { RpcTransport } from "@solana/kit";
|
|
2
3
|
import { SolanaClusterRpcFactory } from "./baseRpcFactories";
|
|
3
4
|
import { RateLimitedSolanaRpcFactory } from "./rateLimitedRpcFactory";
|
|
4
|
-
import { Logger } from "winston";
|
|
5
5
|
export declare class RetrySolanaRpcFactory extends SolanaClusterRpcFactory {
|
|
6
6
|
readonly retries: number;
|
|
7
7
|
readonly retryDelaySeconds: number;
|
|
@@ -16,13 +16,6 @@ export declare class RetrySolanaRpcFactory extends SolanaClusterRpcFactory {
|
|
|
16
16
|
* @returns Promise that resolves to the transport response
|
|
17
17
|
*/
|
|
18
18
|
private _tryCall;
|
|
19
|
-
/**
|
|
20
|
-
* Determine whether a Solana RPC error indicates an unrecoverable error that should not be retried.
|
|
21
|
-
* @param method RPC method name
|
|
22
|
-
* @param error Error object from the RPC call
|
|
23
|
-
* @returns True if the request should be aborted immediately, otherwise false
|
|
24
|
-
*/
|
|
25
|
-
private shouldFailImmediate;
|
|
26
19
|
/**
|
|
27
20
|
* Identify whether an error thrown was the result of an RPC provider 429 response.
|
|
28
21
|
* @param error Error object from the RPC query.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retryRpcFactory.d.ts","sourceRoot":"","sources":["../../../../src/providers/solana/retryRpcFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"retryRpcFactory.d.ts","sourceRoot":"","sources":["../../../../src/providers/solana/retryRpcFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,YAAY,EAA2C,MAAM,aAAa,CAAC;AAIpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAKtE,qBAAa,qBAAsB,SAAQ,uBAAuB;IAO9D,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,iBAAiB,EAAE,MAAM;IANpC,SAAS,CAAC,oBAAoB,EAAE,YAAY,CAAC;IAE7C,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;gBAGd,OAAO,EAAE,MAAM,EACf,iBAAiB,EAAE,MAAM,EAClC,GAAG,4BAA4B,EAAE,qBAAqB,CAAC,OAAO,2BAA2B,CAAC;IAuBrF,eAAe,IAAI,YAAY;IAMtC;;;;;OAKG;YACW,QAAQ;IA8BtB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;CAQ5B"}
|
|
@@ -7,4 +7,11 @@ export interface SolanaRateLimitTask {
|
|
|
7
7
|
resolve: (result: unknown) => void;
|
|
8
8
|
reject: (err: unknown) => void;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Determine whether a Solana RPC error indicates an unrecoverable error that should not be retried.
|
|
12
|
+
* @param method RPC method name.
|
|
13
|
+
* @param error Error object from the RPC call.
|
|
14
|
+
* @returns True if the request should be aborted immediately, otherwise false.
|
|
15
|
+
*/
|
|
16
|
+
export declare function shouldFailImmediate(method: string, error: unknown): boolean;
|
|
10
17
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/providers/solana/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/providers/solana/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAElC,OAAO,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IAIlC,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAe3E"}
|
package/package.json
CHANGED
|
@@ -176,7 +176,7 @@ async function _callGetTimestampForSlotWithRetry(
|
|
|
176
176
|
const at = "getTimestampForSlot";
|
|
177
177
|
const { __code: code } = err.context;
|
|
178
178
|
|
|
179
|
-
switch (
|
|
179
|
+
switch (code) {
|
|
180
180
|
case SVM_SLOT_SKIPPED:
|
|
181
181
|
case SVM_LONG_TERM_STORAGE_SLOT_SKIPPED:
|
|
182
182
|
// No block available for this slot; caller must decide on how to handle this.
|
package/src/arch/svm/provider.ts
CHANGED
|
@@ -1,11 +1,56 @@
|
|
|
1
|
+
import { isSolanaError as _isSolanaError } from "@solana/kit";
|
|
2
|
+
import { is, type, number, string } from "superstruct";
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* SVM RPC provider error codes
|
|
3
6
|
* See https://www.quicknode.com/docs/solana/error-references
|
|
4
7
|
*/
|
|
5
8
|
export {
|
|
6
|
-
isSolanaError,
|
|
7
9
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE as SVM_BLOCK_NOT_AVAILABLE,
|
|
8
10
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED as SVM_SLOT_SKIPPED,
|
|
9
11
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED as SVM_LONG_TERM_STORAGE_SLOT_SKIPPED,
|
|
10
12
|
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE as SVM_TRANSACTION_PREFLIGHT_FAILURE,
|
|
11
13
|
} from "@solana/kit";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Superstruct schema for validating SolanaError structure.
|
|
17
|
+
* Handles serialized errors that have lost their prototype chain.
|
|
18
|
+
* Uses partial validation to allow additional properties in the context object.
|
|
19
|
+
*/
|
|
20
|
+
const SolanaErrorStruct = type({
|
|
21
|
+
name: string(),
|
|
22
|
+
context: type({
|
|
23
|
+
__code: number(),
|
|
24
|
+
}),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Type definition for SolanaError structure.
|
|
29
|
+
* Includes common context properties for better type inference.
|
|
30
|
+
*/
|
|
31
|
+
export interface SolanaErrorLike {
|
|
32
|
+
name: string;
|
|
33
|
+
context: {
|
|
34
|
+
__code: number;
|
|
35
|
+
__serverMessage?: string;
|
|
36
|
+
statusCode?: number;
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
};
|
|
39
|
+
cause?: unknown;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Enhanced type guard to check if an error is a SolanaError.
|
|
44
|
+
*
|
|
45
|
+
* This function uses a two-tier approach:
|
|
46
|
+
* 1. First attempts the official instanceof-based check from @solana/kit
|
|
47
|
+
* 2. Falls back to structural validation using superstruct for errors that have been
|
|
48
|
+
* serialized/deserialized (e.g., when crossing async boundaries or through JSON parsing)
|
|
49
|
+
*
|
|
50
|
+
* @param error The error to check
|
|
51
|
+
* @param code Optional error code to match against context.__code
|
|
52
|
+
* @returns True if the error is a SolanaError (or has valid SolanaError structure)
|
|
53
|
+
*/
|
|
54
|
+
export function isSolanaError(error: unknown): error is SolanaErrorLike {
|
|
55
|
+
return _isSolanaError(error) || is(error, SolanaErrorStruct);
|
|
56
|
+
}
|
package/src/arch/svm/utils.ts
CHANGED
|
@@ -28,9 +28,6 @@ import { BigNumber, Address as SdkAddress, biMin, getMessageHash, isDefined, isU
|
|
|
28
28
|
import { getTimestampForSlot, getSlot, getRelayDataHash } from "./SpokeUtils";
|
|
29
29
|
import { AttestedCCTPMessage, EventName, SVMEventNames, SVMProvider, LatestBlockhash } from "./types";
|
|
30
30
|
import winston from "winston";
|
|
31
|
-
|
|
32
|
-
export { isSolanaError } from "@solana/kit";
|
|
33
|
-
|
|
34
31
|
/**
|
|
35
32
|
* Basic void TransactionSigner type
|
|
36
33
|
*/
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { Logger } from "winston";
|
|
1
2
|
import { RpcFromTransport, RpcResponse, RpcTransport, SolanaRpcApiFromTransport } from "@solana/kit";
|
|
2
|
-
import { CachedSolanaRpcFactory } from "./cachedRpcFactory";
|
|
3
|
-
import { SolanaBaseRpcFactory, SolanaClusterRpcFactory } from "./baseRpcFactories";
|
|
4
3
|
import { isPromiseFulfilled, isPromiseRejected } from "../../utils/TypeGuards";
|
|
5
4
|
import { compareSvmRpcResults, createSendErrorWithMessage } from "../utils";
|
|
6
|
-
import {
|
|
5
|
+
import { CachedSolanaRpcFactory } from "./cachedRpcFactory";
|
|
6
|
+
import { SolanaBaseRpcFactory, SolanaClusterRpcFactory } from "./baseRpcFactories";
|
|
7
|
+
import { shouldFailImmediate } from "./utils";
|
|
7
8
|
|
|
8
9
|
// This factory stores multiple Cached RPC factories so that users of this factory can specify multiple RPC providers
|
|
9
10
|
// and the factory will fallback through them if any RPC calls fail. This factory also implements quorum logic amongst
|
|
@@ -64,13 +65,18 @@ export class QuorumFallbackSolanaRpcFactory extends SolanaBaseRpcFactory {
|
|
|
64
65
|
throw error;
|
|
65
66
|
}
|
|
66
67
|
|
|
68
|
+
// If one RPC provider reverted, others likely will too. Skip them.
|
|
69
|
+
if (quorumThreshold === 1 && shouldFailImmediate(method, error)) {
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
|
|
67
73
|
const currentFactory = factory.rpcFactory.clusterUrl;
|
|
68
74
|
const nextFactory = fallbackFactories.shift()!;
|
|
69
75
|
this.logger.debug({
|
|
70
76
|
at: "FallbackSolanaRpcFactory#createTransport::tryWithFallback",
|
|
71
77
|
message: `[${method}] ${currentFactory} failed, falling back to ${nextFactory.rpcFactory.clusterUrl}, new fallback providers length: ${fallbackFactories.length}`,
|
|
72
78
|
method,
|
|
73
|
-
error,
|
|
79
|
+
jsonError: error,
|
|
74
80
|
});
|
|
75
81
|
return tryWithFallback(nextFactory, ...args);
|
|
76
82
|
});
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { Logger } from "winston";
|
|
1
2
|
import { RpcTransport, SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR } from "@solana/kit";
|
|
2
3
|
import { getThrowSolanaErrorResponseTransformer } from "@solana/rpc-transformers";
|
|
4
|
+
import { isSolanaError } from "../../arch/svm";
|
|
5
|
+
import { delay } from "../../utils";
|
|
3
6
|
import { SolanaClusterRpcFactory } from "./baseRpcFactories";
|
|
4
7
|
import { RateLimitedSolanaRpcFactory } from "./rateLimitedRpcFactory";
|
|
5
|
-
import {
|
|
6
|
-
import { delay } from "../../utils";
|
|
7
|
-
import { Logger } from "winston";
|
|
8
|
+
import { shouldFailImmediate } from "./utils";
|
|
8
9
|
|
|
9
10
|
// This factory adds retry logic on top of the RateLimitedSolanaRpcFactory.
|
|
10
11
|
// It follows the same composition pattern as other factories in this module.
|
|
@@ -67,7 +68,7 @@ export class RetrySolanaRpcFactory extends SolanaClusterRpcFactory {
|
|
|
67
68
|
getThrowSolanaErrorResponseTransformer()(response, { methodName: method, params });
|
|
68
69
|
return response;
|
|
69
70
|
} catch (error) {
|
|
70
|
-
if (retryAttempt++ >= this.retries ||
|
|
71
|
+
if (retryAttempt++ >= this.retries || shouldFailImmediate(method, error)) {
|
|
71
72
|
throw error;
|
|
72
73
|
}
|
|
73
74
|
|
|
@@ -82,29 +83,6 @@ export class RetrySolanaRpcFactory extends SolanaClusterRpcFactory {
|
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
|
|
85
|
-
/**
|
|
86
|
-
* Determine whether a Solana RPC error indicates an unrecoverable error that should not be retried.
|
|
87
|
-
* @param method RPC method name
|
|
88
|
-
* @param error Error object from the RPC call
|
|
89
|
-
* @returns True if the request should be aborted immediately, otherwise false
|
|
90
|
-
*/
|
|
91
|
-
private shouldFailImmediate(method: string, error: unknown): boolean {
|
|
92
|
-
if (!isSolanaError(error)) {
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// JSON-RPC errors: https://www.quicknode.com/docs/solana/error-references
|
|
97
|
-
const { __code: code } = error.context;
|
|
98
|
-
switch (method) {
|
|
99
|
-
case "getBlock":
|
|
100
|
-
case "getBlockTime":
|
|
101
|
-
// No block at the requested slot. This may not be correct for blocks > 1 year old.
|
|
102
|
-
return [SVM_SLOT_SKIPPED, SVM_LONG_TERM_STORAGE_SLOT_SKIPPED].includes(code);
|
|
103
|
-
default:
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
86
|
/**
|
|
109
87
|
* Identify whether an error thrown was the result of an RPC provider 429 response.
|
|
110
88
|
* @param error Error object from the RPC query.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RpcTransport } from "@solana/rpc-spec";
|
|
2
|
+
import { isSolanaError, SVM_SLOT_SKIPPED, SVM_LONG_TERM_STORAGE_SLOT_SKIPPED } from "../../arch/svm";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* This is the type we pass to define a Solana RPC request "task".
|
|
@@ -12,3 +13,26 @@ export interface SolanaRateLimitTask {
|
|
|
12
13
|
resolve: (result: unknown) => void;
|
|
13
14
|
reject: (err: unknown) => void;
|
|
14
15
|
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Determine whether a Solana RPC error indicates an unrecoverable error that should not be retried.
|
|
19
|
+
* @param method RPC method name.
|
|
20
|
+
* @param error Error object from the RPC call.
|
|
21
|
+
* @returns True if the request should be aborted immediately, otherwise false.
|
|
22
|
+
*/
|
|
23
|
+
export function shouldFailImmediate(method: string, error: unknown): boolean {
|
|
24
|
+
if (!isSolanaError(error)) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// JSON-RPC errors: https://www.quicknode.com/docs/solana/error-references
|
|
29
|
+
const { __code: code } = error.context;
|
|
30
|
+
switch (method) {
|
|
31
|
+
case "getBlock":
|
|
32
|
+
case "getBlockTime":
|
|
33
|
+
// No block at the requested slot. This may not be correct for blocks > 1 year old.
|
|
34
|
+
return [SVM_SLOT_SKIPPED, SVM_LONG_TERM_STORAGE_SLOT_SKIPPED].includes(code);
|
|
35
|
+
default:
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|