@across-protocol/sdk 4.3.19 → 4.3.22
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.d.ts +3 -1
- package/dist/cjs/arch/svm/SpokeUtils.js +15 -4
- package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/cjs/arch/svm/utils.js +6 -5
- package/dist/cjs/arch/svm/utils.js.map +1 -1
- package/dist/cjs/providers/mocks/MockCachedSolanaRpcFactory.d.ts +2 -2
- package/dist/cjs/providers/mocks/MockCachedSolanaRpcFactory.js +3 -3
- package/dist/cjs/providers/mocks/MockCachedSolanaRpcFactory.js.map +1 -1
- package/dist/cjs/providers/mocks/MockRetrySolanaRpcFactory.d.ts +5 -0
- package/dist/cjs/providers/mocks/MockRetrySolanaRpcFactory.js +21 -0
- package/dist/cjs/providers/mocks/MockRetrySolanaRpcFactory.js.map +1 -0
- package/dist/cjs/providers/mocks/index.d.ts +1 -0
- package/dist/cjs/providers/mocks/index.js +1 -0
- package/dist/cjs/providers/mocks/index.js.map +1 -1
- package/dist/cjs/providers/solana/cachedRpcFactory.d.ts +4 -4
- package/dist/cjs/providers/solana/cachedRpcFactory.js +14 -14
- package/dist/cjs/providers/solana/cachedRpcFactory.js.map +1 -1
- package/dist/cjs/providers/solana/index.d.ts +1 -0
- package/dist/cjs/providers/solana/index.js +1 -0
- package/dist/cjs/providers/solana/index.js.map +1 -1
- package/dist/cjs/providers/solana/retryRpcFactory.d.ts +14 -0
- package/dist/cjs/providers/solana/retryRpcFactory.js +88 -0
- package/dist/cjs/providers/solana/retryRpcFactory.js.map +1 -0
- package/dist/cjs/providers/utils.js +2 -0
- package/dist/cjs/providers/utils.js.map +1 -1
- package/dist/cjs/utils/BigNumberUtils.d.ts +2 -0
- package/dist/cjs/utils/BigNumberUtils.js +5 -1
- package/dist/cjs/utils/BigNumberUtils.js.map +1 -1
- package/dist/cjs/utils/DepositUtils.d.ts +2 -0
- package/dist/cjs/utils/DepositUtils.js +9 -1
- package/dist/cjs/utils/DepositUtils.js.map +1 -1
- package/dist/cjs/utils/TokenUtils.d.ts +1 -1
- package/dist/cjs/utils/TokenUtils.js +1 -1
- package/dist/cjs/utils/TokenUtils.js.map +1 -1
- package/dist/esm/arch/svm/SpokeUtils.d.ts +3 -1
- package/dist/esm/arch/svm/SpokeUtils.js +13 -3
- package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/esm/arch/svm/utils.js +7 -6
- package/dist/esm/arch/svm/utils.js.map +1 -1
- package/dist/esm/providers/mocks/MockCachedSolanaRpcFactory.d.ts +2 -2
- package/dist/esm/providers/mocks/MockCachedSolanaRpcFactory.js +4 -4
- package/dist/esm/providers/mocks/MockCachedSolanaRpcFactory.js.map +1 -1
- package/dist/esm/providers/mocks/MockRetrySolanaRpcFactory.d.ts +5 -0
- package/dist/esm/providers/mocks/MockRetrySolanaRpcFactory.js +20 -0
- package/dist/esm/providers/mocks/MockRetrySolanaRpcFactory.js.map +1 -0
- package/dist/esm/providers/mocks/index.d.ts +1 -0
- package/dist/esm/providers/mocks/index.js +1 -0
- package/dist/esm/providers/mocks/index.js.map +1 -1
- package/dist/esm/providers/solana/cachedRpcFactory.d.ts +4 -4
- package/dist/esm/providers/solana/cachedRpcFactory.js +15 -15
- package/dist/esm/providers/solana/cachedRpcFactory.js.map +1 -1
- package/dist/esm/providers/solana/index.d.ts +1 -0
- package/dist/esm/providers/solana/index.js +1 -0
- package/dist/esm/providers/solana/index.js.map +1 -1
- package/dist/esm/providers/solana/retryRpcFactory.d.ts +26 -0
- package/dist/esm/providers/solana/retryRpcFactory.js +105 -0
- package/dist/esm/providers/solana/retryRpcFactory.js.map +1 -0
- package/dist/esm/providers/utils.js +4 -1
- package/dist/esm/providers/utils.js.map +1 -1
- package/dist/esm/utils/BigNumberUtils.d.ts +5 -0
- package/dist/esm/utils/BigNumberUtils.js +5 -0
- package/dist/esm/utils/BigNumberUtils.js.map +1 -1
- package/dist/esm/utils/DepositUtils.d.ts +16 -2
- package/dist/esm/utils/DepositUtils.js +20 -2
- package/dist/esm/utils/DepositUtils.js.map +1 -1
- package/dist/esm/utils/TokenUtils.d.ts +3 -23
- package/dist/esm/utils/TokenUtils.js +1 -1
- package/dist/esm/utils/TokenUtils.js.map +1 -1
- package/dist/types/arch/svm/SpokeUtils.d.ts +3 -1
- package/dist/types/arch/svm/SpokeUtils.d.ts.map +1 -1
- package/dist/types/arch/svm/utils.d.ts.map +1 -1
- package/dist/types/providers/mocks/MockCachedSolanaRpcFactory.d.ts +2 -2
- package/dist/types/providers/mocks/MockCachedSolanaRpcFactory.d.ts.map +1 -1
- package/dist/types/providers/mocks/MockRetrySolanaRpcFactory.d.ts +6 -0
- package/dist/types/providers/mocks/MockRetrySolanaRpcFactory.d.ts.map +1 -0
- package/dist/types/providers/mocks/index.d.ts +1 -0
- package/dist/types/providers/mocks/index.d.ts.map +1 -1
- package/dist/types/providers/solana/cachedRpcFactory.d.ts +4 -4
- package/dist/types/providers/solana/cachedRpcFactory.d.ts.map +1 -1
- package/dist/types/providers/solana/index.d.ts +1 -0
- package/dist/types/providers/solana/index.d.ts.map +1 -1
- package/dist/types/providers/solana/retryRpcFactory.d.ts +27 -0
- package/dist/types/providers/solana/retryRpcFactory.d.ts.map +1 -0
- package/dist/types/providers/utils.d.ts.map +1 -1
- package/dist/types/utils/BigNumberUtils.d.ts +5 -0
- package/dist/types/utils/BigNumberUtils.d.ts.map +1 -1
- package/dist/types/utils/DepositUtils.d.ts +16 -2
- package/dist/types/utils/DepositUtils.d.ts.map +1 -1
- package/dist/types/utils/TokenUtils.d.ts +3 -23
- package/dist/types/utils/TokenUtils.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/arch/svm/SpokeUtils.ts +14 -3
- package/src/arch/svm/utils.ts +4 -4
- package/src/providers/mocks/MockCachedSolanaRpcFactory.ts +5 -5
- package/src/providers/mocks/MockRetrySolanaRpcFactory.ts +16 -0
- package/src/providers/mocks/index.ts +1 -0
- package/src/providers/solana/cachedRpcFactory.ts +17 -17
- package/src/providers/solana/index.ts +1 -0
- package/src/providers/solana/retryRpcFactory.ts +97 -0
- package/src/providers/utils.ts +3 -0
- package/src/utils/BigNumberUtils.ts +6 -0
- package/src/utils/DepositUtils.ts +41 -2
- package/src/utils/TokenUtils.ts +2 -2
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { RpcTransport } from "@solana/kit";
|
|
2
|
+
import { SolanaClusterRpcFactory } from "./baseRpcFactories";
|
|
3
|
+
import { RateLimitedSolanaRpcFactory } from "./rateLimitedRpcFactory";
|
|
4
|
+
import { delay } from "../../utils";
|
|
5
|
+
import { getOriginFromURL } from "../../utils/NetworkUtils";
|
|
6
|
+
import { Logger } from "winston";
|
|
7
|
+
|
|
8
|
+
// This factory adds retry logic on top of the RateLimitedSolanaRpcFactory.
|
|
9
|
+
// It follows the same composition pattern as other factories in this module.
|
|
10
|
+
export class RetrySolanaRpcFactory extends SolanaClusterRpcFactory {
|
|
11
|
+
// Holds the underlying transport that the retry wrapper wraps.
|
|
12
|
+
protected rateLimitedTransport: RpcTransport;
|
|
13
|
+
|
|
14
|
+
protected logger: Logger;
|
|
15
|
+
|
|
16
|
+
constructor(
|
|
17
|
+
readonly retries: number,
|
|
18
|
+
readonly retryDelaySeconds: number,
|
|
19
|
+
...rateLimitedConstructorParams: ConstructorParameters<typeof RateLimitedSolanaRpcFactory>
|
|
20
|
+
) {
|
|
21
|
+
// SolanaClusterRpcFactory shares the last two constructor parameters with RateLimitedSolanaRpcFactory.
|
|
22
|
+
const superParams = rateLimitedConstructorParams.slice(-2) as [
|
|
23
|
+
ConstructorParameters<typeof SolanaClusterRpcFactory>[0], // clusterUrl: ClusterUrl
|
|
24
|
+
ConstructorParameters<typeof SolanaClusterRpcFactory>[1], // chainId: number
|
|
25
|
+
];
|
|
26
|
+
super(...superParams);
|
|
27
|
+
|
|
28
|
+
// Validate retry configuration
|
|
29
|
+
if (this.retries < 0 || !Number.isInteger(this.retries)) {
|
|
30
|
+
throw new Error(`retries cannot be < 0 and must be an integer. Currently set to ${this.retries}`);
|
|
31
|
+
}
|
|
32
|
+
if (this.retryDelaySeconds < 0) {
|
|
33
|
+
throw new Error(`retryDelaySeconds cannot be < 0. Currently set to ${this.retryDelaySeconds}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Create the rate limited transport.
|
|
37
|
+
const rateLimitedRpcFactory = new RateLimitedSolanaRpcFactory(...rateLimitedConstructorParams);
|
|
38
|
+
this.rateLimitedTransport = rateLimitedRpcFactory.createTransport();
|
|
39
|
+
this.logger = rateLimitedRpcFactory.logger;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public createTransport(): RpcTransport {
|
|
43
|
+
return <TResponse>(...args: Parameters<RpcTransport>): Promise<TResponse> => {
|
|
44
|
+
return this._tryCall(() => this.rateLimitedTransport<TResponse>(...args), args);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Retry wrapper for transport calls with Solana-specific error handling.
|
|
50
|
+
* @param transportCall Function that makes the transport call
|
|
51
|
+
* @param args Original transport arguments for logging
|
|
52
|
+
* @returns Promise that resolves to the transport response
|
|
53
|
+
*/
|
|
54
|
+
private async _tryCall<TResponse>(
|
|
55
|
+
transportCall: () => Promise<TResponse>,
|
|
56
|
+
args: Parameters<RpcTransport>
|
|
57
|
+
): Promise<TResponse> {
|
|
58
|
+
const { method } = args[0].payload as { method: string; params?: unknown[] };
|
|
59
|
+
let retries = this.retries;
|
|
60
|
+
|
|
61
|
+
// eslint-disable-next-line no-constant-condition
|
|
62
|
+
while (true) {
|
|
63
|
+
try {
|
|
64
|
+
return await transportCall();
|
|
65
|
+
} catch (error) {
|
|
66
|
+
if (retries-- <= 0 || this.shouldFailImmediate(method, error)) {
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Log retry attempt if logger is available
|
|
71
|
+
this.logger.debug({
|
|
72
|
+
at: "RetryRpcFactory",
|
|
73
|
+
message: "Retrying Solana RPC call",
|
|
74
|
+
provider: getOriginFromURL(this.clusterUrl),
|
|
75
|
+
method,
|
|
76
|
+
retryAttempt: this.retries - retries,
|
|
77
|
+
retryDelaySeconds: this.retryDelaySeconds,
|
|
78
|
+
error: error?.toString(),
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
await delay(this.retryDelaySeconds);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Determine whether a Solana RPC error indicates an unrecoverable error that should not be retried.
|
|
88
|
+
* @param method RPC method name
|
|
89
|
+
* @param error Error object from the RPC call
|
|
90
|
+
* @returns True if the request should be aborted immediately, otherwise false
|
|
91
|
+
*/
|
|
92
|
+
private shouldFailImmediate(_method: string, _error: unknown): boolean {
|
|
93
|
+
// TODO: Decide which Solana RPC errors should be considered non-transitory and should not be retried.
|
|
94
|
+
// For now, retry all errors.
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
}
|
package/src/providers/utils.ts
CHANGED
|
@@ -96,14 +96,17 @@ const IGNORED_FIELDS = {
|
|
|
96
96
|
// 2023-08-31 Added blockHash because of upstream zkSync provider disagreements. Consider removing later.
|
|
97
97
|
// 2024-05-07 Added l1BatchNumber and logType due to Alchemy. Consider removing later.
|
|
98
98
|
// 2024-07-11 Added blockTimestamp after zkSync rolled out a new node release.
|
|
99
|
+
// 2025-07-24 Added additional fields returned by Chainstack on (at least) Polygon.
|
|
99
100
|
eth_getBlockByNumber: [
|
|
100
101
|
"miner", // polygon (sometimes)
|
|
101
102
|
"l1BatchNumber", // zkSync
|
|
102
103
|
"l1BatchTimestamp", // zkSync
|
|
104
|
+
"requestsHash", // Chainstack (Polygon)
|
|
103
105
|
"size", // Alchemy/Arbitrum (temporary)
|
|
104
106
|
"totalDifficulty", // Quicknode/Alchemy (sometimes)
|
|
105
107
|
"logsBloom", // zkSync (third-party providers return 0x0..0)
|
|
106
108
|
"transactions", // Polygon yParity field in transactions[]
|
|
109
|
+
"withdrawals", // Chainstack (Polygon)
|
|
107
110
|
],
|
|
108
111
|
eth_getLogs: ["blockTimestamp", "transactionLogIndex", "l1BatchNumber", "logType"],
|
|
109
112
|
};
|
|
@@ -19,6 +19,12 @@ export const bnOne = BigNumber.from("1");
|
|
|
19
19
|
export const bnUint32Max = BigNumber.from("0xffffffff");
|
|
20
20
|
export const bnUint256Max = BigNumber.from("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* BigInt min/max helpers.
|
|
24
|
+
*/
|
|
25
|
+
export const biMin = (a: bigint, b: bigint) => (a > b ? b : a);
|
|
26
|
+
export const biMax = (a: bigint, b: bigint) => (a > b ? a : b);
|
|
27
|
+
|
|
22
28
|
/**
|
|
23
29
|
* Converts a stringified number into a BigNumber with 18 decimal places.
|
|
24
30
|
* @param num The number to parse.
|
|
@@ -265,7 +265,7 @@ export function resolveDepositMessage(deposit: Deposit): string {
|
|
|
265
265
|
* Converts a RelayData object with `Address` types as address fields to a `RelayData`-like object with
|
|
266
266
|
* strings as address fields.
|
|
267
267
|
* @param relayData RelayData type.
|
|
268
|
-
* @returns a RelayData-like type which has strings as fields.
|
|
268
|
+
* @returns a RelayData-like type which has hex 32 byte strings as fields.
|
|
269
269
|
*/
|
|
270
270
|
export function convertRelayDataParamsToBytes32(relayData: RelayData): ConvertedRelayData {
|
|
271
271
|
return {
|
|
@@ -282,7 +282,7 @@ export function convertRelayDataParamsToBytes32(relayData: RelayData): Converted
|
|
|
282
282
|
* Converts a Fill object with `Address` types as address fields to a `RelayData`-like object with
|
|
283
283
|
* strings as address fields.
|
|
284
284
|
* @param relayData RelayData type.
|
|
285
|
-
* @returns a RelayData-like type which has strings as fields.
|
|
285
|
+
* @returns a RelayData-like type which has hex 32 byte strings as fields.
|
|
286
286
|
*/
|
|
287
287
|
export function convertFillParamsToBytes32(fill: Fill): ConvertedFill {
|
|
288
288
|
return {
|
|
@@ -299,3 +299,42 @@ export function convertFillParamsToBytes32(fill: Fill): ConvertedFill {
|
|
|
299
299
|
},
|
|
300
300
|
};
|
|
301
301
|
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Converts a RelayData object with `Address` types as address fields to a `RelayData`-like object with
|
|
305
|
+
* strings as address fields.
|
|
306
|
+
* @param relayData RelayData type.
|
|
307
|
+
* @returns a RelayData-like type which has native address representation strings as fields.
|
|
308
|
+
*/
|
|
309
|
+
export function convertRelayDataParamsToNative(relayData: RelayData): ConvertedRelayData {
|
|
310
|
+
return {
|
|
311
|
+
...relayData,
|
|
312
|
+
depositor: relayData.depositor.toNative(),
|
|
313
|
+
recipient: relayData.recipient.toNative(),
|
|
314
|
+
inputToken: relayData.inputToken.toNative(),
|
|
315
|
+
outputToken: relayData.outputToken.toNative(),
|
|
316
|
+
exclusiveRelayer: relayData.exclusiveRelayer.toNative(),
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Converts a Fill object with `Address` types as address fields to a `RelayData`-like object with
|
|
322
|
+
* strings as address fields.
|
|
323
|
+
* @param relayData RelayData type.
|
|
324
|
+
* @returns a RelayData-like type which has native address representation strings as fields.
|
|
325
|
+
*/
|
|
326
|
+
export function convertFillParamsToNative(fill: Fill): ConvertedFill {
|
|
327
|
+
return {
|
|
328
|
+
...fill,
|
|
329
|
+
depositor: fill.depositor.toNative(),
|
|
330
|
+
recipient: fill.recipient.toNative(),
|
|
331
|
+
inputToken: fill.inputToken.toNative(),
|
|
332
|
+
outputToken: fill.outputToken.toNative(),
|
|
333
|
+
exclusiveRelayer: fill.exclusiveRelayer.toNative(),
|
|
334
|
+
relayer: fill.relayer.toNative(),
|
|
335
|
+
relayExecutionInfo: {
|
|
336
|
+
...fill.relayExecutionInfo,
|
|
337
|
+
updatedRecipient: fill.relayExecutionInfo.updatedRecipient.toNative(),
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
}
|
package/src/utils/TokenUtils.ts
CHANGED
|
@@ -58,12 +58,12 @@ export function resolveSymbolOnChain(chainId: number, symbol: string): TokenInfo
|
|
|
58
58
|
*/
|
|
59
59
|
export const resolveContractFromSymbol = (
|
|
60
60
|
symbol: string,
|
|
61
|
-
chainId:
|
|
61
|
+
chainId: number,
|
|
62
62
|
tokenMapping = TOKEN_SYMBOLS_MAP
|
|
63
63
|
): string | undefined => {
|
|
64
64
|
return Object.values(tokenMapping).find((details) => {
|
|
65
65
|
return details.symbol.toLowerCase() === symbol.toLowerCase();
|
|
66
|
-
})?.addresses[
|
|
66
|
+
})?.addresses[chainId];
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
export function getCoingeckoTokenIdByAddress(address: string, chainId: number): string {
|