@chainlink/ccip-sdk 0.92.0 → 0.93.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.
Files changed (223) hide show
  1. package/README.md +20 -18
  2. package/dist/api/index.d.ts +103 -0
  3. package/dist/api/index.d.ts.map +1 -0
  4. package/dist/api/index.js +141 -0
  5. package/dist/api/index.js.map +1 -0
  6. package/dist/api/types.d.ts +38 -0
  7. package/dist/api/types.d.ts.map +1 -0
  8. package/dist/api/types.js +2 -0
  9. package/dist/api/types.js.map +1 -0
  10. package/dist/aptos/index.d.ts +20 -33
  11. package/dist/aptos/index.d.ts.map +1 -1
  12. package/dist/aptos/index.js +34 -26
  13. package/dist/aptos/index.js.map +1 -1
  14. package/dist/aptos/logs.js +1 -1
  15. package/dist/aptos/logs.js.map +1 -1
  16. package/dist/aptos/token.js.map +1 -1
  17. package/dist/chain.d.ts +206 -71
  18. package/dist/chain.d.ts.map +1 -1
  19. package/dist/chain.js +89 -20
  20. package/dist/chain.js.map +1 -1
  21. package/dist/commits.d.ts +2 -2
  22. package/dist/commits.d.ts.map +1 -1
  23. package/dist/commits.js +4 -4
  24. package/dist/commits.js.map +1 -1
  25. package/dist/errors/CCIPError.d.ts.map +1 -1
  26. package/dist/errors/CCIPError.js +3 -2
  27. package/dist/errors/CCIPError.js.map +1 -1
  28. package/dist/errors/codes.d.ts +4 -1
  29. package/dist/errors/codes.d.ts.map +1 -1
  30. package/dist/errors/codes.js +6 -1
  31. package/dist/errors/codes.js.map +1 -1
  32. package/dist/errors/index.d.ts +5 -2
  33. package/dist/errors/index.d.ts.map +1 -1
  34. package/dist/errors/index.js +8 -2
  35. package/dist/errors/index.js.map +1 -1
  36. package/dist/errors/recovery.d.ts.map +1 -1
  37. package/dist/errors/recovery.js +4 -1
  38. package/dist/errors/recovery.js.map +1 -1
  39. package/dist/errors/specialized.d.ts +29 -4
  40. package/dist/errors/specialized.d.ts.map +1 -1
  41. package/dist/errors/specialized.js +48 -6
  42. package/dist/errors/specialized.js.map +1 -1
  43. package/dist/evm/errors.js.map +1 -1
  44. package/dist/evm/index.d.ts +24 -48
  45. package/dist/evm/index.d.ts.map +1 -1
  46. package/dist/evm/index.js +71 -59
  47. package/dist/evm/index.js.map +1 -1
  48. package/dist/evm/logs.js.map +1 -1
  49. package/dist/evm/offchain.js +3 -2
  50. package/dist/evm/offchain.js.map +1 -1
  51. package/dist/evm/viem/client-adapter.d.ts +68 -0
  52. package/dist/evm/viem/client-adapter.d.ts.map +1 -0
  53. package/dist/evm/viem/client-adapter.js +104 -0
  54. package/dist/evm/viem/client-adapter.js.map +1 -0
  55. package/dist/evm/viem/index.d.ts +29 -0
  56. package/dist/evm/viem/index.d.ts.map +1 -0
  57. package/dist/evm/viem/index.js +28 -0
  58. package/dist/evm/viem/index.js.map +1 -0
  59. package/dist/evm/viem/types.d.ts +13 -0
  60. package/dist/evm/viem/types.d.ts.map +1 -0
  61. package/dist/evm/viem/types.js +2 -0
  62. package/dist/evm/viem/types.js.map +1 -0
  63. package/dist/evm/viem/wallet-adapter.d.ts +58 -0
  64. package/dist/evm/viem/wallet-adapter.d.ts.map +1 -0
  65. package/dist/evm/viem/wallet-adapter.js +197 -0
  66. package/dist/evm/viem/wallet-adapter.js.map +1 -0
  67. package/dist/execution.d.ts +1 -1
  68. package/dist/execution.d.ts.map +1 -1
  69. package/dist/execution.js +2 -2
  70. package/dist/execution.js.map +1 -1
  71. package/dist/explorer.d.ts +74 -0
  72. package/dist/explorer.d.ts.map +1 -0
  73. package/dist/explorer.js +67 -0
  74. package/dist/explorer.js.map +1 -0
  75. package/dist/gas.js.map +1 -1
  76. package/dist/hasher/merklemulti.js.map +1 -1
  77. package/dist/http-status.d.ts +20 -0
  78. package/dist/http-status.d.ts.map +1 -0
  79. package/dist/http-status.js +25 -0
  80. package/dist/http-status.js.map +1 -0
  81. package/dist/index.d.ts +11 -4
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +5 -3
  84. package/dist/index.js.map +1 -1
  85. package/dist/offchain.js.map +1 -1
  86. package/dist/requests.d.ts +4 -4
  87. package/dist/requests.d.ts.map +1 -1
  88. package/dist/requests.js +6 -6
  89. package/dist/requests.js.map +1 -1
  90. package/dist/solana/cleanup.js +2 -2
  91. package/dist/solana/cleanup.js.map +1 -1
  92. package/dist/solana/exec.js +1 -5
  93. package/dist/solana/exec.js.map +1 -1
  94. package/dist/solana/index.d.ts +28 -57
  95. package/dist/solana/index.d.ts.map +1 -1
  96. package/dist/solana/index.js +66 -70
  97. package/dist/solana/index.js.map +1 -1
  98. package/dist/solana/logs.js +2 -2
  99. package/dist/solana/logs.js.map +1 -1
  100. package/dist/solana/offchain.js +3 -3
  101. package/dist/solana/offchain.js.map +1 -1
  102. package/dist/solana/send.js +1 -1
  103. package/dist/solana/send.js.map +1 -1
  104. package/dist/solana/utils.js +1 -1
  105. package/dist/solana/utils.js.map +1 -1
  106. package/dist/sui/discovery.d.ts.map +1 -1
  107. package/dist/sui/discovery.js +2 -5
  108. package/dist/sui/discovery.js.map +1 -1
  109. package/dist/sui/events.d.ts.map +1 -1
  110. package/dist/sui/events.js +2 -8
  111. package/dist/sui/events.js.map +1 -1
  112. package/dist/sui/index.d.ts +18 -29
  113. package/dist/sui/index.d.ts.map +1 -1
  114. package/dist/sui/index.js +24 -26
  115. package/dist/sui/index.js.map +1 -1
  116. package/dist/sui/manuallyExec/encoder.d.ts.map +1 -1
  117. package/dist/sui/manuallyExec/encoder.js +0 -3
  118. package/dist/sui/manuallyExec/encoder.js.map +1 -1
  119. package/dist/sui/manuallyExec/index.d.ts.map +1 -1
  120. package/dist/sui/manuallyExec/index.js +1 -2
  121. package/dist/sui/manuallyExec/index.js.map +1 -1
  122. package/dist/sui/objects.js +4 -4
  123. package/dist/sui/objects.js.map +1 -1
  124. package/dist/ton/exec.d.ts +2 -2
  125. package/dist/ton/exec.d.ts.map +1 -1
  126. package/dist/ton/exec.js.map +1 -1
  127. package/dist/ton/hasher.js +5 -5
  128. package/dist/ton/hasher.js.map +1 -1
  129. package/dist/ton/index.d.ts +54 -49
  130. package/dist/ton/index.d.ts.map +1 -1
  131. package/dist/ton/index.js +331 -236
  132. package/dist/ton/index.js.map +1 -1
  133. package/dist/ton/logs.d.ts +11 -22
  134. package/dist/ton/logs.d.ts.map +1 -1
  135. package/dist/ton/logs.js +95 -118
  136. package/dist/ton/logs.js.map +1 -1
  137. package/dist/ton/types.d.ts +9 -9
  138. package/dist/ton/types.d.ts.map +1 -1
  139. package/dist/ton/types.js +5 -9
  140. package/dist/ton/types.js.map +1 -1
  141. package/dist/ton/utils.d.ts +8 -27
  142. package/dist/ton/utils.d.ts.map +1 -1
  143. package/dist/ton/utils.js +31 -111
  144. package/dist/ton/utils.js.map +1 -1
  145. package/dist/types.d.ts +34 -0
  146. package/dist/types.d.ts.map +1 -1
  147. package/dist/types.js +30 -0
  148. package/dist/types.js.map +1 -1
  149. package/dist/utils.d.ts +6 -5
  150. package/dist/utils.d.ts.map +1 -1
  151. package/dist/utils.js +76 -52
  152. package/dist/utils.js.map +1 -1
  153. package/dist/viem.d.ts +6 -0
  154. package/dist/viem.d.ts.map +1 -0
  155. package/dist/viem.js +6 -0
  156. package/dist/viem.js.map +1 -0
  157. package/package.json +18 -3
  158. package/src/api/index.ts +167 -0
  159. package/src/api/types.ts +39 -0
  160. package/src/aptos/index.ts +57 -64
  161. package/src/aptos/logs.ts +10 -10
  162. package/src/aptos/token.ts +1 -1
  163. package/src/chain.ts +274 -97
  164. package/src/commits.ts +5 -5
  165. package/src/errors/CCIPError.ts +5 -2
  166. package/src/errors/codes.ts +8 -1
  167. package/src/errors/index.ts +15 -2
  168. package/src/errors/recovery.ts +9 -1
  169. package/src/errors/specialized.ts +61 -6
  170. package/src/evm/errors.ts +2 -2
  171. package/src/evm/index.ts +107 -120
  172. package/src/evm/logs.ts +4 -4
  173. package/src/evm/offchain.ts +5 -4
  174. package/src/evm/viem/client-adapter.ts +124 -0
  175. package/src/evm/viem/index.ts +29 -0
  176. package/src/evm/viem/types.ts +14 -0
  177. package/src/evm/viem/wallet-adapter.ts +233 -0
  178. package/src/execution.ts +9 -9
  179. package/src/explorer.ts +90 -0
  180. package/src/gas.ts +2 -2
  181. package/src/hasher/merklemulti.ts +7 -7
  182. package/src/http-status.ts +31 -0
  183. package/src/index.ts +19 -1
  184. package/src/offchain.ts +1 -1
  185. package/src/requests.ts +9 -12
  186. package/src/solana/cleanup.ts +4 -4
  187. package/src/solana/exec.ts +13 -18
  188. package/src/solana/index.ts +92 -117
  189. package/src/solana/logs.ts +8 -8
  190. package/src/solana/offchain.ts +3 -3
  191. package/src/solana/send.ts +20 -20
  192. package/src/solana/utils.ts +4 -4
  193. package/src/sui/discovery.ts +4 -10
  194. package/src/sui/events.ts +5 -12
  195. package/src/sui/index.ts +36 -48
  196. package/src/sui/manuallyExec/encoder.ts +0 -4
  197. package/src/sui/manuallyExec/index.ts +1 -3
  198. package/src/sui/objects.ts +14 -14
  199. package/src/ton/exec.ts +2 -5
  200. package/src/ton/hasher.ts +5 -5
  201. package/src/ton/index.ts +392 -316
  202. package/src/ton/logs.ts +122 -143
  203. package/src/ton/types.ts +17 -21
  204. package/src/ton/utils.ts +39 -145
  205. package/src/types.ts +36 -0
  206. package/src/utils.ts +96 -66
  207. package/src/viem.ts +5 -0
  208. package/tsconfig.json +3 -2
  209. package/dist/ton/bindings/offramp.d.ts +0 -48
  210. package/dist/ton/bindings/offramp.d.ts.map +0 -1
  211. package/dist/ton/bindings/offramp.js +0 -63
  212. package/dist/ton/bindings/offramp.js.map +0 -1
  213. package/dist/ton/bindings/onramp.d.ts +0 -40
  214. package/dist/ton/bindings/onramp.d.ts.map +0 -1
  215. package/dist/ton/bindings/onramp.js +0 -51
  216. package/dist/ton/bindings/onramp.js.map +0 -1
  217. package/dist/ton/bindings/router.d.ts +0 -47
  218. package/dist/ton/bindings/router.d.ts.map +0 -1
  219. package/dist/ton/bindings/router.js +0 -51
  220. package/dist/ton/bindings/router.js.map +0 -1
  221. package/src/ton/bindings/offramp.ts +0 -96
  222. package/src/ton/bindings/onramp.ts +0 -72
  223. package/src/ton/bindings/router.ts +0 -65
package/src/utils.ts CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  CCIPError,
21
21
  CCIPHttpError,
22
22
  CCIPTypeVersionInvalidError,
23
+ HttpStatus,
23
24
  } from './errors/index.ts'
24
25
  import SELECTORS from './selectors.ts'
25
26
  import { supportedChains } from './supported-chains.ts'
@@ -132,7 +133,7 @@ export const networkInfo = memoize(function networkInfo_(
132
133
  typeof selectorOrIdOrName === 'string' &&
133
134
  (match = selectorOrIdOrName.match(/^(-?\d+)n?$/))
134
135
  ) {
135
- selectorOrIdOrName = BigInt(match[1])
136
+ selectorOrIdOrName = BigInt(match[1]!)
136
137
  }
137
138
  if (typeof selectorOrIdOrName === 'bigint') {
138
139
  // maybe we got a chainId deserialized as bigint
@@ -140,7 +141,7 @@ export const networkInfo = memoize(function networkInfo_(
140
141
  chainId = Number(selectorOrIdOrName)
141
142
  } else {
142
143
  for (const id in SELECTORS) {
143
- if (SELECTORS[id].selector === selectorOrIdOrName) {
144
+ if (SELECTORS[id]!.selector === selectorOrIdOrName) {
144
145
  chainId = id
145
146
  break
146
147
  }
@@ -150,7 +151,7 @@ export const networkInfo = memoize(function networkInfo_(
150
151
  } else if (typeof selectorOrIdOrName === 'string') {
151
152
  if (selectorOrIdOrName.includes('-', 1)) {
152
153
  for (const id in SELECTORS) {
153
- if (SELECTORS[id].name === selectorOrIdOrName) {
154
+ if (SELECTORS[id]!.name === selectorOrIdOrName) {
154
155
  chainId = id
155
156
  break
156
157
  }
@@ -293,9 +294,9 @@ export function isBase64(data: unknown): data is string {
293
294
  * @returns Uint8Array representation.
294
295
  */
295
296
  export function getDataBytes(data: BytesLike | readonly number[]): Uint8Array {
296
- if (Array.isArray(data)) {
297
- return new Uint8Array(data)
298
- }
297
+ if (Array.isArray(data)) return new Uint8Array(data)
298
+ if (typeof data === 'string' && data.match(/^[0-9a-f]+[a-f][0-9a-f]+$/i)) data = '0x' + data
299
+ else if (typeof data === 'string' && data.match(/^0X[0-9a-fA-F]+$/)) data = data.toLowerCase()
299
300
  if (isBytesLike(data)) {
300
301
  return getBytes(data)
301
302
  } else if (isBase64(data)) {
@@ -388,7 +389,7 @@ export function parseTypeAndVersion(
388
389
  if (!match) throw new CCIPTypeVersionInvalidError(typeAndVersion)
389
390
  const [, typeRaw, version] = match
390
391
  // some string normalization
391
- const type = typeRaw
392
+ const type = typeRaw!
392
393
  .replaceAll(/-(\w)/g, (_, w: string) => w.toUpperCase()) // kebabToPascal
393
394
  .replace(/ccip/gi, 'CCIP')
394
395
  .replace(
@@ -396,59 +397,52 @@ export function parseTypeAndVersion(
396
397
  (_, o: string, n: string, ramp: string) =>
397
398
  `${o.toUpperCase()}${n.toLowerCase()}${ramp.charAt(0).toUpperCase()}${ramp.slice(1).toLowerCase()}`,
398
399
  ) // ccipOfframp -> CCIPOffRamp
399
- if (!match[3]) return [type, version, typeAndVersion]
400
- else return [type, version, typeAndVersion, match[3]]
400
+ if (!match[3]) return [type, version!, typeAndVersion]
401
+ else return [type, version!, typeAndVersion, match[3]]
401
402
  }
402
403
 
403
- /**
404
- * Creates a rate-limited fetch function with retry logic.
405
- * Configurable via maxRequests, windowMs, and maxRetries options.
406
- * @returns Rate-limited fetch function.
407
- */
408
- export function createRateLimitedFetch(
409
- {
410
- maxRequests = 40,
411
- windowMs = 11e3,
412
- maxRetries = 5,
413
- }: { maxRequests?: number; windowMs?: number; maxRetries?: number } = {},
414
- { logger = console }: WithLogger = {},
415
- ): typeof fetch {
416
- // Custom fetch implementation with retry logic and rate limiting
417
- // Per-instance state
418
- const requestQueue: Array<{ timestamp: number }> = []
419
- const methodRateLimits: Record<
404
+ /* eslint-disable jsdoc/require-jsdoc */
405
+ type RateLimitOpts = { maxRequests: number; windowMs: number; maxRetries: number }
406
+
407
+ class RateLimit {
408
+ readonly requestQueue: Array<{ timestamp: number }>
409
+ readonly methodRateLimits: Record<
420
410
  string,
421
411
  { limit: number; remaining: number; queue: Array<{ timestamp: number }> }
422
- > = {}
412
+ >
413
+ constructor() {
414
+ this.requestQueue = []
415
+ this.methodRateLimits = {}
416
+ }
423
417
 
424
- const isRateLimited = (): boolean => {
418
+ isRateLimited({ windowMs, maxRequests }: RateLimitOpts): boolean {
425
419
  const now = Date.now()
426
420
  // Remove old requests outside the window
427
- while (requestQueue.length > 0 && now - requestQueue[0].timestamp > windowMs) {
428
- requestQueue.shift()
421
+ while (this.requestQueue.length > 0 && now - this.requestQueue[0]!.timestamp > windowMs) {
422
+ this.requestQueue.shift()
429
423
  }
430
- return requestQueue.length >= maxRequests
424
+ return this.requestQueue.length >= maxRequests
431
425
  }
432
426
 
433
- const isMethodRateLimited = (method: string): boolean => {
434
- const methodLimit = methodRateLimits[method]
427
+ isMethodRateLimited({ windowMs }: RateLimitOpts, method: string): boolean {
428
+ const methodLimit = this.methodRateLimits[method]
435
429
  if (!methodLimit) return false
436
430
 
437
431
  const now = Date.now()
438
432
  // Remove old requests outside the window
439
- while (methodLimit.queue.length > 0 && now - methodLimit.queue[0].timestamp > windowMs) {
433
+ while (methodLimit.queue.length > 0 && now - methodLimit.queue[0]!.timestamp > windowMs) {
440
434
  methodLimit.queue.shift()
441
435
  }
442
436
  return methodLimit.queue.length >= methodLimit.limit
443
437
  }
444
438
 
445
- const waitForRateLimit = async (method?: string): Promise<void> => {
439
+ async waitForRateLimit(opts: RateLimitOpts, method?: string): Promise<void> {
446
440
  // Wait for method-specific rate limit if applicable
447
- if (method && methodRateLimits[method]) {
448
- while (isMethodRateLimited(method)) {
449
- const oldestRequest = methodRateLimits[method].queue[0]
441
+ if (method && this.methodRateLimits[method]) {
442
+ while (this.isMethodRateLimited(opts, method)) {
443
+ const oldestRequest = this.methodRateLimits[method].queue[0]
450
444
  if (!oldestRequest) break // Queue was cleaned, no longer rate limited
451
- const waitTime = windowMs - (Date.now() - oldestRequest.timestamp)
445
+ const waitTime = opts.windowMs - (Date.now() - oldestRequest.timestamp)
452
446
  if (waitTime > 0) {
453
447
  await sleep(waitTime + 100) // Add small buffer
454
448
  }
@@ -456,51 +450,79 @@ export function createRateLimitedFetch(
456
450
  }
457
451
 
458
452
  // Wait for global rate limit
459
- while (isRateLimited()) {
460
- const oldestRequest = requestQueue[0]
453
+ while (this.isRateLimited(opts)) {
454
+ const oldestRequest = this.requestQueue[0]
461
455
  if (!oldestRequest) break // Queue was cleaned, no longer rate limited
462
- const waitTime = windowMs - (Date.now() - oldestRequest.timestamp)
456
+ const waitTime = opts.windowMs - (Date.now() - oldestRequest.timestamp)
463
457
  if (waitTime > 0) {
464
458
  await sleep(waitTime + 100) // Add small buffer
465
459
  }
466
460
  }
467
461
  }
468
462
 
469
- const recordRequest = (method?: string): void => {
463
+ recordRequest(method?: string): void {
470
464
  const timestamp = Date.now()
471
- requestQueue.push({ timestamp })
472
- if (method && methodRateLimits[method]) {
473
- methodRateLimits[method].queue.push({ timestamp })
465
+ this.requestQueue.push({ timestamp })
466
+ if (method && this.methodRateLimits[method]) {
467
+ this.methodRateLimits[method].queue.push({ timestamp })
474
468
  }
475
469
  }
476
470
 
477
- const updateMethodRateLimits = (response: Response, method?: string): void => {
471
+ updateMethodRateLimits(response: Response, method?: string): void {
478
472
  if (!method) return
479
473
 
480
474
  const limit = Number(response.headers.get('x-ratelimit-method-limit'))
481
475
  const remaining = Number(response.headers.get('x-ratelimit-method-remaining'))
482
476
 
483
477
  if (isNaN(limit) || isNaN(remaining)) return
484
- if (!methodRateLimits[method]) {
485
- methodRateLimits[method] = { limit, remaining, queue: [] }
478
+ if (!this.methodRateLimits[method]) {
479
+ this.methodRateLimits[method] = { limit, remaining, queue: [] }
486
480
  } else {
487
- methodRateLimits[method].limit = limit
488
- methodRateLimits[method].remaining = remaining
481
+ this.methodRateLimits[method].limit = limit
482
+ this.methodRateLimits[method].remaining = remaining
489
483
  }
490
484
  }
485
+ }
486
+ /* eslint-enable jsdoc/require-jsdoc */
487
+
488
+ // global map per hostname
489
+ const perHostnameRateLimits: Record<string, RateLimit> = {}
490
+
491
+ /**
492
+ * Creates a rate-limited fetch function with retry logic.
493
+ * Configurable via maxRequests, windowMs, and maxRetries options.
494
+ * @returns Rate-limited fetch function.
495
+ */
496
+ export function createRateLimitedFetch(
497
+ opts: Partial<RateLimitOpts> = {},
498
+ { logger = console }: WithLogger = {},
499
+ ): typeof fetch {
500
+ opts.maxRequests ??= 40
501
+ opts.maxRetries ??= 5
502
+ opts.windowMs ??= 11e3
503
+ const opts_ = opts as RateLimitOpts
491
504
 
492
505
  const extractMethod = (init?: RequestInit): string | undefined => {
493
506
  if (!init?.body || (typeof init.body !== 'string' && typeof init.body !== 'object')) return
494
507
  try {
495
- const parsed = (typeof init.body === 'string' ? JSON.parse(init.body) : init.body) as {
496
- method?: string
497
- }
508
+ const parsed = (typeof init.body === 'string' ? JSON.parse(init.body) : init.body) as
509
+ | { method?: string }
510
+ | undefined
498
511
  if (parsed && typeof parsed.method === 'string') return parsed.method
499
512
  } catch {
500
513
  // Not JSON or no method field
501
514
  }
502
515
  }
503
516
 
517
+ const extractHostname = (input: Parameters<typeof fetch>[0]): string => {
518
+ if (typeof input === 'string') {
519
+ input = new URL(input)
520
+ } else if (input instanceof Request) {
521
+ input = new URL(input.url)
522
+ }
523
+ return input.hostname
524
+ }
525
+
504
526
  const isRateLimitError = (error: unknown): boolean => {
505
527
  if (error instanceof Error) {
506
528
  return !!error.message.match(/\b(429\b|rate.?limit)/i)
@@ -511,27 +533,37 @@ export function createRateLimitedFetch(
511
533
  return async (input, init?) => {
512
534
  let lastError: Error | null = null
513
535
  const method = extractMethod(init)
536
+ const hostname = extractHostname(input)
537
+ const rl = (perHostnameRateLimits[hostname] ??= new RateLimit())
514
538
 
515
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
539
+ const body = init?.body ?? (input instanceof Request ? await input.clone().json() : undefined)
540
+ for (let attempt = 0; attempt <= opts_.maxRetries; attempt++) {
516
541
  try {
517
542
  // Wait for rate limit before making request
518
- await waitForRateLimit(method)
519
- recordRequest(method)
520
- // logger.debug('__fetching', input, init?.body)
543
+ await rl.waitForRateLimit(opts_, method)
544
+ rl.recordRequest(method)
521
545
 
522
- const response = await globalThis.fetch(input, init)
546
+ const response = await globalThis.fetch(
547
+ input instanceof Request ? input.clone() : input,
548
+ init,
549
+ )
523
550
 
524
551
  // Update method rate limits from response headers
525
- updateMethodRateLimits(response, method)
552
+ rl.updateMethodRateLimits(response, method)
526
553
 
527
554
  // If response is successful, return it
528
555
  if (response.ok) {
529
- logger.debug('fetched', input, response.status, init?.body)
556
+ logger.debug(
557
+ 'fetched',
558
+ response.status,
559
+ body,
560
+ // ((await response.clone().json()) as { result: unknown })?.result,
561
+ )
530
562
  return response
531
563
  }
532
564
 
533
- // For 429 responses, throw an error to trigger retry
534
- if (response.status === 429) {
565
+ // For rate limit responses, throw an error to trigger retry
566
+ if (response.status === HttpStatus.TOO_MANY_REQUESTS) {
535
567
  throw new CCIPHttpError(response.status, response.statusText)
536
568
  }
537
569
 
@@ -548,9 +580,7 @@ export function createRateLimitedFetch(
548
580
  }
549
581
 
550
582
  // Don't retry on the last attempt
551
- if (attempt >= maxRetries) {
552
- break
553
- }
583
+ if (attempt >= opts_.maxRetries) break
554
584
  }
555
585
  }
556
586
 
package/src/viem.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Viem adapters entry point.
3
+ * Import from `\@chainlink/ccip-sdk/viem`
4
+ */
5
+ export * from './evm/viem/index.ts'
package/tsconfig.json CHANGED
@@ -15,6 +15,7 @@
15
15
  "erasableSyntaxOnly": true,
16
16
  "resolveJsonModule": true,
17
17
  "noImplicitOverride": true,
18
- "useUnknownInCatchVariables": true
19
- }
18
+ "useUnknownInCatchVariables": true,
19
+ "noUncheckedIndexedAccess": true,
20
+ },
20
21
  }
@@ -1,48 +0,0 @@
1
- import type { Address, ContractProvider } from '@ton/core';
2
- /**
3
- * Configuration for a source chain on the TON OffRamp contract.
4
- */
5
- export interface SourceChainConfig {
6
- router: Address;
7
- isEnabled: boolean;
8
- minSeqNr: bigint;
9
- isRMNVerificationDisabled: boolean;
10
- onRamp: Buffer;
11
- }
12
- /**
13
- * Dynamic configuration for the OffRamp contract.
14
- * Contains addresses that can be updated without redeploying the contract.
15
- */
16
- export interface DynamicConfig {
17
- router: Address;
18
- feeQuoter: Address;
19
- permissionlessExecutionThresholdSeconds: number;
20
- }
21
- /**
22
- * TON OffRamp contract binding.
23
- * The OffRamp receives and executes cross-chain messages on the destination (TON) chain.
24
- */
25
- export declare class OffRamp {
26
- readonly address: Address;
27
- /**
28
- * Creates a new OffRamp instance.
29
- * @param address - The OffRamp contract address on TON.
30
- */
31
- constructor(address: Address);
32
- /**
33
- * Creates an OffRamp instance from a contract address.
34
- * @param address - The OffRamp contract address on TON.
35
- * @returns A new OffRamp instance.
36
- */
37
- static createFromAddress(address: Address): OffRamp;
38
- /**
39
- * Retrieves the source chain configuration for a given chain selector.
40
- *
41
- * @param provider - TON contract provider for making RPC calls.
42
- * @param sourceChainSelector - The CCIP chain selector of the source chain.
43
- * @returns The source chain configuration.
44
- * @throws Error with exitCode 266 if the source chain is not enabled.
45
- */
46
- getSourceChainConfig(provider: ContractProvider, sourceChainSelector: bigint): Promise<SourceChainConfig>;
47
- }
48
- //# sourceMappingURL=offramp.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"offramp.d.ts","sourceRoot":"","sources":["../../../src/ton/bindings/offramp.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAE1D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,yBAAyB,EAAE,OAAO,CAAA;IAClC,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAA;IACf,SAAS,EAAE,OAAO,CAAA;IAClB,uCAAuC,EAAE,MAAM,CAAA;CAChD;AAED;;;GAGG;AACH,qBAAa,OAAO;IAClB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IAEzB;;;OAGG;gBACS,OAAO,EAAE,OAAO;IAI5B;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;IAInD;;;;;;;OAOG;IACG,oBAAoB,CACxB,QAAQ,EAAE,gBAAgB,EAC1B,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAAC,iBAAiB,CAAC;CAoC9B"}
@@ -1,63 +0,0 @@
1
- /**
2
- * TON OffRamp contract binding.
3
- * The OffRamp receives and executes cross-chain messages on the destination (TON) chain.
4
- */
5
- export class OffRamp {
6
- address;
7
- /**
8
- * Creates a new OffRamp instance.
9
- * @param address - The OffRamp contract address on TON.
10
- */
11
- constructor(address) {
12
- this.address = address;
13
- }
14
- /**
15
- * Creates an OffRamp instance from a contract address.
16
- * @param address - The OffRamp contract address on TON.
17
- * @returns A new OffRamp instance.
18
- */
19
- static createFromAddress(address) {
20
- return new OffRamp(address);
21
- }
22
- /**
23
- * Retrieves the source chain configuration for a given chain selector.
24
- *
25
- * @param provider - TON contract provider for making RPC calls.
26
- * @param sourceChainSelector - The CCIP chain selector of the source chain.
27
- * @returns The source chain configuration.
28
- * @throws Error with exitCode 266 if the source chain is not enabled.
29
- */
30
- async getSourceChainConfig(provider, sourceChainSelector) {
31
- const result = await provider.get('sourceChainConfig', [
32
- { type: 'int', value: sourceChainSelector },
33
- ]);
34
- // Tolk returns struct as tuple
35
- const router = result.stack.readAddress();
36
- const isEnabled = result.stack.readBoolean();
37
- const minSeqNr = result.stack.readBigNumber();
38
- const isRMNVerificationDisabled = result.stack.readBoolean();
39
- // onRamp is stored as CrossChainAddress cell
40
- const onRampCell = result.stack.readCell();
41
- const onRampSlice = onRampCell.beginParse();
42
- // Check if length-prefixed or raw format based on cell bit length
43
- const cellBits = onRampCell.bits.length;
44
- let onRamp;
45
- if (cellBits === 160) {
46
- // Raw 20-byte EVM address (no length prefix)
47
- onRamp = onRampSlice.loadBuffer(20);
48
- }
49
- else {
50
- // Length-prefixed format: 8-bit length + data
51
- const onRampLength = onRampSlice.loadUint(8);
52
- onRamp = onRampSlice.loadBuffer(onRampLength);
53
- }
54
- return {
55
- router,
56
- isEnabled,
57
- minSeqNr,
58
- isRMNVerificationDisabled,
59
- onRamp,
60
- };
61
- }
62
- }
63
- //# sourceMappingURL=offramp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"offramp.js","sourceRoot":"","sources":["../../../src/ton/bindings/offramp.ts"],"names":[],"mappings":"AAwBA;;;GAGG;AACH,MAAM,OAAO,OAAO;IACT,OAAO,CAAS;IAEzB;;;OAGG;IACH,YAAY,OAAgB;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CAAC,OAAgB;QACvC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IAC7B,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,oBAAoB,CACxB,QAA0B,EAC1B,mBAA2B;QAE3B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,mBAAmB,EAAE;YACrD,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE;SAC5C,CAAC,CAAA;QAEF,+BAA+B;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAA;QACzC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAA;QAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,CAAA;QAC7C,MAAM,yBAAyB,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAA;QAE5D,6CAA6C;QAC7C,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAA;QAC1C,MAAM,WAAW,GAAG,UAAU,CAAC,UAAU,EAAE,CAAA;QAE3C,kEAAkE;QAClE,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAA;QACvC,IAAI,MAAc,CAAA;QAElB,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;YACrB,6CAA6C;YAC7C,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;QACrC,CAAC;aAAM,CAAC;YACN,8CAA8C;YAC9C,MAAM,YAAY,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;YAC5C,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;QAC/C,CAAC;QAED,OAAO;YACL,MAAM;YACN,SAAS;YACT,QAAQ;YACR,yBAAyB;YACzB,MAAM;SACP,CAAA;IACH,CAAC;CACF"}
@@ -1,40 +0,0 @@
1
- import { type Address, type ContractProvider, Dictionary } from '@ton/core';
2
- /**
3
- * Configuration for a destination chain on the TON OnRamp contract.
4
- * Contains routing and access control settings for messages going to a specific destination chain.
5
- */
6
- export interface DestChainConfig {
7
- router: Address;
8
- sequenceNumber: bigint;
9
- allowlistEnabled: boolean;
10
- allowedSenders: Dictionary<Address, boolean>;
11
- }
12
- /**
13
- * TON OnRamp contract binding.
14
- * The OnRamp sends cross-chain messages from the source (TON) chain to destination chains.
15
- * It validates messages, assigns sequence numbers, and emits events for the CCIP network.
16
- */
17
- export declare class OnRamp {
18
- readonly address: Address;
19
- /**
20
- * Creates a new OnRamp instance.
21
- * @param address - The OnRamp contract address on TON.
22
- */
23
- constructor(address: Address);
24
- /**
25
- * Creates an OnRamp instance from a contract address.
26
- * @param address - The OnRamp contract address on TON.
27
- * @returns A new OnRamp instance.
28
- */
29
- static createFromAddress(address: Address): OnRamp;
30
- /**
31
- * Retrieves the destination chain configuration for a given chain selector.
32
- * This includes the router, current sequence number, and allowlist settings.
33
- *
34
- * @param provider - TON contract provider for making RPC calls.
35
- * @param destChainSelector - The CCIP chain selector of the destination chain.
36
- * @returns The destination chain configuration.
37
- */
38
- getDestChainConfig(provider: ContractProvider, destChainSelector: bigint): Promise<DestChainConfig>;
39
- }
40
- //# sourceMappingURL=onramp.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"onramp.d.ts","sourceRoot":"","sources":["../../../src/ton/bindings/onramp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,gBAAgB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAE3E;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,gBAAgB,EAAE,OAAO,CAAA;IACzB,cAAc,EAAE,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;CAC7C;AAED;;;;GAIG;AACH,qBAAa,MAAM;IACjB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IAEzB;;;OAGG;gBACS,OAAO,EAAE,OAAO;IAI5B;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAIlD;;;;;;;OAOG;IACG,kBAAkB,CACtB,QAAQ,EAAE,gBAAgB,EAC1B,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,eAAe,CAAC;CAqB5B"}
@@ -1,51 +0,0 @@
1
- // TODO: FIXME: Remove local copies and import when chainlink-ton is published as npm package
2
- import { Dictionary } from '@ton/core';
3
- /**
4
- * TON OnRamp contract binding.
5
- * The OnRamp sends cross-chain messages from the source (TON) chain to destination chains.
6
- * It validates messages, assigns sequence numbers, and emits events for the CCIP network.
7
- */
8
- export class OnRamp {
9
- address;
10
- /**
11
- * Creates a new OnRamp instance.
12
- * @param address - The OnRamp contract address on TON.
13
- */
14
- constructor(address) {
15
- this.address = address;
16
- }
17
- /**
18
- * Creates an OnRamp instance from a contract address.
19
- * @param address - The OnRamp contract address on TON.
20
- * @returns A new OnRamp instance.
21
- */
22
- static createFromAddress(address) {
23
- return new OnRamp(address);
24
- }
25
- /**
26
- * Retrieves the destination chain configuration for a given chain selector.
27
- * This includes the router, current sequence number, and allowlist settings.
28
- *
29
- * @param provider - TON contract provider for making RPC calls.
30
- * @param destChainSelector - The CCIP chain selector of the destination chain.
31
- * @returns The destination chain configuration.
32
- */
33
- async getDestChainConfig(provider, destChainSelector) {
34
- const { stack } = await provider.get('destChainConfig', [
35
- { type: 'int', value: destChainSelector },
36
- ]);
37
- const router = stack.readAddress();
38
- const sequenceNumber = stack.readBigNumber();
39
- const allowlistEnabled = stack.readBoolean();
40
- const allowedSendersCell = stack.readCellOpt();
41
- return {
42
- router,
43
- sequenceNumber,
44
- allowlistEnabled,
45
- allowedSenders: allowedSendersCell
46
- ? Dictionary.loadDirect(Dictionary.Keys.Address(), Dictionary.Values.Bool(), allowedSendersCell)
47
- : Dictionary.empty(),
48
- };
49
- }
50
- }
51
- //# sourceMappingURL=onramp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"onramp.js","sourceRoot":"","sources":["../../../src/ton/bindings/onramp.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,OAAO,EAAuC,UAAU,EAAE,MAAM,WAAW,CAAA;AAa3E;;;;GAIG;AACH,MAAM,OAAO,MAAM;IACR,OAAO,CAAS;IAEzB;;;OAGG;IACH,YAAY,OAAgB;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CAAC,OAAgB;QACvC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,kBAAkB,CACtB,QAA0B,EAC1B,iBAAyB;QAEzB,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,iBAAiB,EAAE;YACtD,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE;SAC1C,CAAC,CAAA;QACF,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;QAClC,MAAM,cAAc,GAAG,KAAK,CAAC,aAAa,EAAE,CAAA;QAC5C,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;QAC5C,MAAM,kBAAkB,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;QAC9C,OAAO;YACL,MAAM;YACN,cAAc;YACd,gBAAgB;YAChB,cAAc,EAAE,kBAAkB;gBAChC,CAAC,CAAC,UAAU,CAAC,UAAU,CACnB,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,EACzB,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,EACxB,kBAAkB,CACnB;gBACH,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE;SACvB,CAAA;IACH,CAAC;CACF"}
@@ -1,47 +0,0 @@
1
- import type { Address, ContractProvider } from '@ton/core';
2
- /**
3
- * Represents a ramp (OnRamp or OffRamp) configuration in the Router.
4
- */
5
- export interface Ramp {
6
- chainSelector: bigint;
7
- address: Address;
8
- }
9
- /**
10
- * TON Router contract binding.
11
- * The Router is the main entry point for CCIP on TON. It routes messages to the appropriate
12
- * OnRamp (for sending) or OffRamp (for receiving) based on the chain selector.
13
- */
14
- export declare class Router {
15
- readonly address: Address;
16
- /**
17
- * Creates a new Router instance.
18
- * @param address - The Router contract address on TON.
19
- */
20
- constructor(address: Address);
21
- /**
22
- * Creates a Router instance from a contract address.
23
- * @param address - The Router contract address on TON.
24
- * @returns A new Router instance.
25
- */
26
- static createFromAddress(address: Address): Router;
27
- /**
28
- * Gets the OffRamp address for a given source chain selector.
29
- * The OffRamp handles incoming messages from the specified source chain.
30
- *
31
- * @param provider - TON contract provider for making RPC calls.
32
- * @param chainSelector - The CCIP chain selector of the source chain.
33
- * @returns The OffRamp contract address.
34
- * @throws Error with exitCode 261 if the source chain is not enabled.
35
- */
36
- getOffRamp(provider: ContractProvider, chainSelector: bigint): Promise<Address>;
37
- /**
38
- * Gets the OnRamp address for a given destination chain selector.
39
- * The OnRamp handles outgoing messages to the specified destination chain.
40
- *
41
- * @param provider - TON contract provider for making RPC calls.
42
- * @param destChainSelector - The CCIP chain selector of the destination chain.
43
- * @returns The OnRamp contract address.
44
- */
45
- getOnRamp(provider: ContractProvider, destChainSelector: bigint): Promise<Address>;
46
- }
47
- //# sourceMappingURL=router.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/ton/bindings/router.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAE1D;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,OAAO,CAAA;CACjB;AAED;;;;GAIG;AACH,qBAAa,MAAM;IACjB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IAEzB;;;OAGG;gBACS,OAAO,EAAE,OAAO;IAI5B;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAIlD;;;;;;;;OAQG;IACG,UAAU,CAAC,QAAQ,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMrF;;;;;;;OAOG;IACG,SAAS,CAAC,QAAQ,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAKzF"}
@@ -1,51 +0,0 @@
1
- /**
2
- * TON Router contract binding.
3
- * The Router is the main entry point for CCIP on TON. It routes messages to the appropriate
4
- * OnRamp (for sending) or OffRamp (for receiving) based on the chain selector.
5
- */
6
- export class Router {
7
- address;
8
- /**
9
- * Creates a new Router instance.
10
- * @param address - The Router contract address on TON.
11
- */
12
- constructor(address) {
13
- this.address = address;
14
- }
15
- /**
16
- * Creates a Router instance from a contract address.
17
- * @param address - The Router contract address on TON.
18
- * @returns A new Router instance.
19
- */
20
- static createFromAddress(address) {
21
- return new Router(address);
22
- }
23
- /**
24
- * Gets the OffRamp address for a given source chain selector.
25
- * The OffRamp handles incoming messages from the specified source chain.
26
- *
27
- * @param provider - TON contract provider for making RPC calls.
28
- * @param chainSelector - The CCIP chain selector of the source chain.
29
- * @returns The OffRamp contract address.
30
- * @throws Error with exitCode 261 if the source chain is not enabled.
31
- */
32
- async getOffRamp(provider, chainSelector) {
33
- return provider
34
- .get('offRamp', [{ type: 'int', value: chainSelector }])
35
- .then((r) => r.stack.readAddress());
36
- }
37
- /**
38
- * Gets the OnRamp address for a given destination chain selector.
39
- * The OnRamp handles outgoing messages to the specified destination chain.
40
- *
41
- * @param provider - TON contract provider for making RPC calls.
42
- * @param destChainSelector - The CCIP chain selector of the destination chain.
43
- * @returns The OnRamp contract address.
44
- */
45
- async getOnRamp(provider, destChainSelector) {
46
- return provider
47
- .get('onRamp', [{ type: 'int', value: destChainSelector }])
48
- .then((r) => r.stack.readAddress());
49
- }
50
- }
51
- //# sourceMappingURL=router.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/ton/bindings/router.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,MAAM,OAAO,MAAM;IACR,OAAO,CAAS;IAEzB;;;OAGG;IACH,YAAY,OAAgB;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CAAC,OAAgB;QACvC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,UAAU,CAAC,QAA0B,EAAE,aAAqB;QAChE,OAAO,QAAQ;aACZ,GAAG,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;aACvD,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAA;IACvC,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,SAAS,CAAC,QAA0B,EAAE,iBAAyB;QACnE,OAAO,QAAQ;aACZ,GAAG,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;aAC1D,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAA;IACvC,CAAC;CACF"}