@chainlink/ccip-sdk 0.93.0 → 0.95.0
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/api/index.d.ts +80 -4
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +262 -6
- package/dist/api/index.js.map +1 -1
- package/dist/api/types.d.ts +138 -13
- package/dist/api/types.d.ts.map +1 -1
- package/dist/aptos/index.d.ts +5 -9
- package/dist/aptos/index.d.ts.map +1 -1
- package/dist/aptos/index.js +26 -25
- package/dist/aptos/index.js.map +1 -1
- package/dist/aptos/logs.js +3 -3
- package/dist/aptos/logs.js.map +1 -1
- package/dist/aptos/send.js +1 -1
- package/dist/aptos/send.js.map +1 -1
- package/dist/chain.d.ts +96 -10
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js +77 -2
- package/dist/chain.js.map +1 -1
- package/dist/errors/codes.d.ts +7 -3
- package/dist/errors/codes.d.ts.map +1 -1
- package/dist/errors/codes.js +8 -3
- package/dist/errors/codes.js.map +1 -1
- package/dist/errors/index.d.ts +7 -7
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +7 -7
- package/dist/errors/index.js.map +1 -1
- package/dist/errors/recovery.d.ts.map +1 -1
- package/dist/errors/recovery.js +8 -4
- package/dist/errors/recovery.js.map +1 -1
- package/dist/errors/specialized.d.ts +53 -18
- package/dist/errors/specialized.d.ts.map +1 -1
- package/dist/errors/specialized.js +112 -37
- package/dist/errors/specialized.js.map +1 -1
- package/dist/evm/gas.d.ts +14 -0
- package/dist/evm/gas.d.ts.map +1 -0
- package/dist/evm/gas.js +97 -0
- package/dist/evm/gas.js.map +1 -0
- package/dist/evm/index.d.ts +6 -8
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +36 -23
- package/dist/evm/index.js.map +1 -1
- package/dist/evm/offchain.d.ts.map +1 -1
- package/dist/evm/offchain.js +8 -8
- package/dist/evm/offchain.js.map +1 -1
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +8 -1
- package/dist/execution.js.map +1 -1
- package/dist/gas.d.ts +43 -19
- package/dist/gas.d.ts.map +1 -1
- package/dist/gas.js +48 -68
- package/dist/gas.js.map +1 -1
- package/dist/index.d.ts +15 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -5
- package/dist/index.js.map +1 -1
- package/dist/offchain.d.ts +5 -4
- package/dist/offchain.d.ts.map +1 -1
- package/dist/offchain.js +7 -6
- package/dist/offchain.js.map +1 -1
- package/dist/requests.d.ts +21 -13
- package/dist/requests.d.ts.map +1 -1
- package/dist/requests.js +79 -47
- package/dist/requests.js.map +1 -1
- package/dist/selectors.d.ts +2 -1
- package/dist/selectors.d.ts.map +1 -1
- package/dist/selectors.js +629 -274
- package/dist/selectors.js.map +1 -1
- package/dist/solana/exec.d.ts.map +1 -1
- package/dist/solana/exec.js +2 -1
- package/dist/solana/exec.js.map +1 -1
- package/dist/solana/index.d.ts +10 -10
- package/dist/solana/index.d.ts.map +1 -1
- package/dist/solana/index.js +82 -18
- package/dist/solana/index.js.map +1 -1
- package/dist/solana/offchain.js +2 -2
- package/dist/solana/offchain.js.map +1 -1
- package/dist/solana/send.d.ts.map +1 -1
- package/dist/solana/send.js +6 -9
- package/dist/solana/send.js.map +1 -1
- package/dist/solana/utils.d.ts +29 -1
- package/dist/solana/utils.d.ts.map +1 -1
- package/dist/solana/utils.js +39 -1
- package/dist/solana/utils.js.map +1 -1
- package/dist/sui/discovery.d.ts +7 -4
- package/dist/sui/discovery.d.ts.map +1 -1
- package/dist/sui/discovery.js +66 -19
- package/dist/sui/discovery.js.map +1 -1
- package/dist/sui/events.d.ts +23 -12
- package/dist/sui/events.d.ts.map +1 -1
- package/dist/sui/events.js +267 -128
- package/dist/sui/events.js.map +1 -1
- package/dist/sui/index.d.ts +32 -39
- package/dist/sui/index.d.ts.map +1 -1
- package/dist/sui/index.js +289 -163
- package/dist/sui/index.js.map +1 -1
- package/dist/sui/manuallyExec/encoder.d.ts.map +1 -1
- package/dist/sui/manuallyExec/encoder.js +1 -0
- package/dist/sui/manuallyExec/encoder.js.map +1 -1
- package/dist/sui/manuallyExec/index.d.ts.map +1 -1
- package/dist/sui/manuallyExec/index.js +1 -0
- package/dist/sui/manuallyExec/index.js.map +1 -1
- package/dist/sui/objects.d.ts +14 -4
- package/dist/sui/objects.d.ts.map +1 -1
- package/dist/sui/objects.js +63 -69
- package/dist/sui/objects.js.map +1 -1
- package/dist/sui/types.d.ts +33 -0
- package/dist/sui/types.d.ts.map +1 -1
- package/dist/sui/types.js.map +1 -1
- package/dist/ton/hasher.d.ts.map +1 -1
- package/dist/ton/hasher.js +1 -0
- package/dist/ton/hasher.js.map +1 -1
- package/dist/ton/index.d.ts +4 -4
- package/dist/ton/index.d.ts.map +1 -1
- package/dist/ton/index.js +8 -8
- package/dist/ton/index.js.map +1 -1
- package/dist/ton/utils.d.ts +3 -3
- package/dist/ton/utils.d.ts.map +1 -1
- package/dist/ton/utils.js +6 -5
- package/dist/ton/utils.js.map +1 -1
- package/dist/types.d.ts +34 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +19 -5
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +53 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +109 -12
- package/dist/utils.js.map +1 -1
- package/package.json +17 -11
- package/src/api/index.ts +343 -9
- package/src/api/types.ts +165 -13
- package/src/aptos/index.ts +32 -32
- package/src/aptos/logs.ts +3 -3
- package/src/aptos/send.ts +1 -1
- package/src/chain.ts +165 -12
- package/src/errors/codes.ts +8 -3
- package/src/errors/index.ts +7 -4
- package/src/errors/recovery.ts +16 -5
- package/src/errors/specialized.ts +147 -45
- package/src/evm/gas.ts +149 -0
- package/src/evm/index.ts +66 -33
- package/src/evm/offchain.ts +15 -9
- package/src/execution.ts +8 -1
- package/src/gas.ts +95 -116
- package/src/index.ts +16 -6
- package/src/offchain.ts +12 -6
- package/src/requests.ts +113 -59
- package/src/selectors.ts +636 -276
- package/src/solana/exec.ts +3 -1
- package/src/solana/index.ts +119 -23
- package/src/solana/offchain.ts +2 -2
- package/src/solana/send.ts +5 -23
- package/src/solana/utils.ts +66 -0
- package/src/sui/discovery.ts +92 -31
- package/src/sui/events.ts +346 -239
- package/src/sui/index.ts +381 -224
- package/src/sui/manuallyExec/encoder.ts +2 -0
- package/src/sui/manuallyExec/index.ts +2 -0
- package/src/sui/objects.ts +77 -99
- package/src/sui/types.ts +35 -0
- package/src/ton/hasher.ts +2 -0
- package/src/ton/index.ts +12 -11
- package/src/ton/utils.ts +7 -6
- package/src/types.ts +36 -10
- package/src/utils.ts +153 -16
package/src/utils.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Buffer } from 'buffer'
|
|
2
|
+
|
|
1
3
|
import bs58 from 'bs58'
|
|
2
4
|
import {
|
|
3
5
|
type BigNumberish,
|
|
@@ -10,6 +12,7 @@ import {
|
|
|
10
12
|
toBigInt,
|
|
11
13
|
} from 'ethers'
|
|
12
14
|
import { memoize } from 'micro-memoize'
|
|
15
|
+
import yaml from 'yaml'
|
|
13
16
|
|
|
14
17
|
import type { Chain, ChainStatic } from './chain.ts'
|
|
15
18
|
import {
|
|
@@ -22,6 +25,7 @@ import {
|
|
|
22
25
|
CCIPTypeVersionInvalidError,
|
|
23
26
|
HttpStatus,
|
|
24
27
|
} from './errors/index.ts'
|
|
28
|
+
import { getRetryDelay, shouldRetry } from './errors/utils.ts'
|
|
25
29
|
import SELECTORS from './selectors.ts'
|
|
26
30
|
import { supportedChains } from './supported-chains.ts'
|
|
27
31
|
import { type NetworkInfo, type WithLogger, ChainFamily } from './types.ts'
|
|
@@ -101,6 +105,9 @@ export async function getSomeBlockNumberBefore(
|
|
|
101
105
|
return beforeBlockNumber
|
|
102
106
|
}
|
|
103
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Checks if a chain is a testnet
|
|
110
|
+
*/
|
|
104
111
|
// memoized so we always output the same object for a given chainId
|
|
105
112
|
const networkInfoFromChainId = memoize((chainId: NetworkInfo['chainId']): NetworkInfo => {
|
|
106
113
|
const sel = SELECTORS[chainId]
|
|
@@ -110,7 +117,7 @@ const networkInfoFromChainId = memoize((chainId: NetworkInfo['chainId']): Networ
|
|
|
110
117
|
chainSelector: sel.selector,
|
|
111
118
|
name: sel.name,
|
|
112
119
|
family: sel.family,
|
|
113
|
-
|
|
120
|
+
networkType: sel.network_type,
|
|
114
121
|
} as NetworkInfo
|
|
115
122
|
})
|
|
116
123
|
|
|
@@ -218,13 +225,23 @@ export function bigIntReviver(_key: string, value: unknown): unknown {
|
|
|
218
225
|
return value
|
|
219
226
|
}
|
|
220
227
|
|
|
228
|
+
/**
|
|
229
|
+
* Parses JSON text with BigInt support for large integers.
|
|
230
|
+
* Uses yaml parser which handles integers as BigInt when they exceed safe integer range.
|
|
231
|
+
* @param text - JSON string to parse
|
|
232
|
+
* @returns Parsed object with large integers as BigInt
|
|
233
|
+
*/
|
|
234
|
+
export function parseJson<T = unknown>(text: string): T {
|
|
235
|
+
return yaml.parse(text, { intAsBigInt: true }) as T
|
|
236
|
+
}
|
|
237
|
+
|
|
221
238
|
/**
|
|
222
239
|
* Decode address from a 32-byte hex string
|
|
223
240
|
**/
|
|
224
241
|
export function decodeAddress(address: BytesLike, family: ChainFamily = ChainFamily.EVM): string {
|
|
225
242
|
const chain = supportedChains[family]
|
|
226
243
|
if (!chain) throw new CCIPChainFamilyUnsupportedError(family)
|
|
227
|
-
return chain.getAddress(
|
|
244
|
+
return chain.getAddress(address)
|
|
228
245
|
}
|
|
229
246
|
|
|
230
247
|
/**
|
|
@@ -253,7 +270,7 @@ export function decodeOnRampAddress(
|
|
|
253
270
|
family: ChainFamily = ChainFamily.EVM,
|
|
254
271
|
): string {
|
|
255
272
|
let decoded = decodeAddress(address, family)
|
|
256
|
-
if (family === ChainFamily.Aptos) decoded += '::onramp'
|
|
273
|
+
if (family === ChainFamily.Aptos || family === ChainFamily.Sui) decoded += '::onramp'
|
|
257
274
|
return decoded
|
|
258
275
|
}
|
|
259
276
|
|
|
@@ -297,6 +314,8 @@ export function getDataBytes(data: BytesLike | readonly number[]): Uint8Array {
|
|
|
297
314
|
if (Array.isArray(data)) return new Uint8Array(data)
|
|
298
315
|
if (typeof data === 'string' && data.match(/^[0-9a-f]+[a-f][0-9a-f]+$/i)) data = '0x' + data
|
|
299
316
|
else if (typeof data === 'string' && data.match(/^0X[0-9a-fA-F]+$/)) data = data.toLowerCase()
|
|
317
|
+
if (typeof data === 'string' && data.startsWith('0x') && data.length % 2)
|
|
318
|
+
data = '0x0' + data.slice(2)
|
|
300
319
|
if (isBytesLike(data)) {
|
|
301
320
|
return getBytes(data)
|
|
302
321
|
} else if (isBase64(data)) {
|
|
@@ -320,20 +339,33 @@ export function bytesToBuffer(bytes: BytesLike | readonly number[]): Buffer {
|
|
|
320
339
|
* @param address - Address in hex or Base58 format.
|
|
321
340
|
* @returns Address bytes as Uint8Array.
|
|
322
341
|
*/
|
|
323
|
-
export function getAddressBytes(address: BytesLike): Uint8Array {
|
|
324
|
-
let bytes
|
|
325
|
-
if (
|
|
326
|
-
bytes =
|
|
342
|
+
export function getAddressBytes(address: BytesLike | readonly number[]): Uint8Array {
|
|
343
|
+
let bytes
|
|
344
|
+
if (address instanceof Uint8Array) {
|
|
345
|
+
bytes = address
|
|
346
|
+
} else if (Array.isArray(address)) {
|
|
347
|
+
bytes = new Uint8Array(address)
|
|
348
|
+
} else if (
|
|
349
|
+
typeof address === 'string' &&
|
|
350
|
+
address.match(/^((0x[0-9a-f]*)|[0-9a-f]{40,})(::.*)?$/i)
|
|
351
|
+
) {
|
|
352
|
+
address = address.split('::')[0]! // discard possible Aptos/Sui module suffix
|
|
353
|
+
// supports with or without (long>=20B) 0x-prefix, odd or even length
|
|
354
|
+
bytes = getBytes(
|
|
355
|
+
address.length % 2
|
|
356
|
+
? '0x0' + (address.toLowerCase().startsWith('0x') ? address.slice(2) : address)
|
|
357
|
+
: !address.toLowerCase().startsWith('0x')
|
|
358
|
+
? '0x' + address
|
|
359
|
+
: address,
|
|
360
|
+
)
|
|
327
361
|
} else {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
bytes.slice(-20).some((b) => b !== 0)
|
|
334
|
-
) {
|
|
335
|
-
bytes = bytes.slice(-20)
|
|
362
|
+
try {
|
|
363
|
+
const bytes_ = bs58.decode(address as string)
|
|
364
|
+
if (bytes_.length % 32 === 0) bytes = bytes_
|
|
365
|
+
} catch (_) {
|
|
366
|
+
// pass
|
|
336
367
|
}
|
|
368
|
+
if (!bytes) bytes = decodeBase64(address as string)
|
|
337
369
|
}
|
|
338
370
|
return bytes
|
|
339
371
|
}
|
|
@@ -354,7 +386,9 @@ export function convertKeysToCamelCase(
|
|
|
354
386
|
mapValues?: (value: unknown, key?: string) => unknown,
|
|
355
387
|
key?: string,
|
|
356
388
|
): unknown {
|
|
357
|
-
if (Array.isArray(obj)) {
|
|
389
|
+
if (Array.isArray(obj) && obj.every((v) => typeof v === 'number')) {
|
|
390
|
+
return mapValues ? mapValues(obj, key) : obj
|
|
391
|
+
} else if (Array.isArray(obj)) {
|
|
358
392
|
return obj.map((v) => convertKeysToCamelCase(v, mapValues, key))
|
|
359
393
|
}
|
|
360
394
|
|
|
@@ -377,6 +411,109 @@ export function convertKeysToCamelCase(
|
|
|
377
411
|
*/
|
|
378
412
|
export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms).unref())
|
|
379
413
|
|
|
414
|
+
/**
|
|
415
|
+
* Configuration for the withRetry utility.
|
|
416
|
+
*/
|
|
417
|
+
export type WithRetryConfig = {
|
|
418
|
+
/** Maximum number of retry attempts */
|
|
419
|
+
maxRetries: number
|
|
420
|
+
/** Initial delay in milliseconds before the first retry */
|
|
421
|
+
initialDelayMs: number
|
|
422
|
+
/** Multiplier applied to delay after each retry */
|
|
423
|
+
backoffMultiplier: number
|
|
424
|
+
/** Maximum delay in milliseconds between retries */
|
|
425
|
+
maxDelayMs: number
|
|
426
|
+
/** Whether to respect the error's retryAfterMs hint */
|
|
427
|
+
respectRetryAfterHint: boolean
|
|
428
|
+
/** Optional logger for retry attempts */
|
|
429
|
+
logger?: { debug: (...args: unknown[]) => void; warn: (...args: unknown[]) => void }
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Executes an async operation with retry logic and exponential backoff.
|
|
434
|
+
* Only retries on transient errors (as determined by shouldRetry from errors/utils).
|
|
435
|
+
*
|
|
436
|
+
* @param operation - Async function to execute
|
|
437
|
+
* @param config - Retry configuration
|
|
438
|
+
* @returns Promise resolving to the operation result
|
|
439
|
+
* @throws The last error encountered after all retries are exhausted
|
|
440
|
+
*
|
|
441
|
+
* @example
|
|
442
|
+
* ```typescript
|
|
443
|
+
* const result = await withRetry(
|
|
444
|
+
* () => apiClient.getMessageById(id),
|
|
445
|
+
* {
|
|
446
|
+
* maxRetries: 3,
|
|
447
|
+
* initialDelayMs: 1000,
|
|
448
|
+
* backoffMultiplier: 2,
|
|
449
|
+
* maxDelayMs: 30000,
|
|
450
|
+
* respectRetryAfterHint: true,
|
|
451
|
+
* }
|
|
452
|
+
* )
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
455
|
+
export async function withRetry<T>(
|
|
456
|
+
operation: () => Promise<T>,
|
|
457
|
+
config: WithRetryConfig,
|
|
458
|
+
): Promise<T> {
|
|
459
|
+
const {
|
|
460
|
+
maxRetries,
|
|
461
|
+
initialDelayMs,
|
|
462
|
+
backoffMultiplier,
|
|
463
|
+
maxDelayMs,
|
|
464
|
+
respectRetryAfterHint,
|
|
465
|
+
logger,
|
|
466
|
+
} = config
|
|
467
|
+
|
|
468
|
+
let lastError: CCIPError | undefined
|
|
469
|
+
let delay = initialDelayMs
|
|
470
|
+
|
|
471
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
472
|
+
try {
|
|
473
|
+
return await operation()
|
|
474
|
+
} catch (err) {
|
|
475
|
+
lastError = CCIPError.isCCIPError(err) ? err : CCIPError.from(err, 'UNKNOWN')
|
|
476
|
+
|
|
477
|
+
// Only retry on transient errors
|
|
478
|
+
if (!shouldRetry(lastError)) {
|
|
479
|
+
throw lastError
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Don't sleep after the last attempt
|
|
483
|
+
if (attempt >= maxRetries) {
|
|
484
|
+
logger?.warn(`All ${maxRetries} retries exhausted:`, lastError.message)
|
|
485
|
+
break
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// Calculate delay for next retry
|
|
489
|
+
let nextDelay = delay
|
|
490
|
+
|
|
491
|
+
// Respect error's retryAfterMs hint if configured
|
|
492
|
+
if (respectRetryAfterHint) {
|
|
493
|
+
const hintDelay = getRetryDelay(lastError)
|
|
494
|
+
if (hintDelay !== null) {
|
|
495
|
+
nextDelay = Math.max(delay, hintDelay)
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// Cap at maxDelayMs
|
|
500
|
+
nextDelay = Math.min(nextDelay, maxDelayMs)
|
|
501
|
+
|
|
502
|
+
logger?.debug(
|
|
503
|
+
`Retry attempt ${attempt + 1}/${maxRetries} after ${nextDelay}ms:`,
|
|
504
|
+
lastError.message,
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
await sleep(nextDelay)
|
|
508
|
+
|
|
509
|
+
// Apply exponential backoff for next iteration
|
|
510
|
+
delay = Math.min(delay * backoffMultiplier, maxDelayMs)
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
throw lastError!
|
|
515
|
+
}
|
|
516
|
+
|
|
380
517
|
/**
|
|
381
518
|
* Parses a typeAndVersion string into its components.
|
|
382
519
|
* @param typeAndVersion - String in format "TypeName vX.Y.Z".
|