@chainlink/ccip-sdk 0.94.0 → 0.96.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 (170) hide show
  1. package/README.md +2 -2
  2. package/dist/all-chains.d.ts +23 -0
  3. package/dist/all-chains.d.ts.map +1 -0
  4. package/dist/all-chains.js +24 -0
  5. package/dist/all-chains.js.map +1 -0
  6. package/dist/api/index.d.ts +86 -7
  7. package/dist/api/index.d.ts.map +1 -1
  8. package/dist/api/index.js +270 -10
  9. package/dist/api/index.js.map +1 -1
  10. package/dist/api/types.d.ts +134 -13
  11. package/dist/api/types.d.ts.map +1 -1
  12. package/dist/aptos/index.d.ts +38 -17
  13. package/dist/aptos/index.d.ts.map +1 -1
  14. package/dist/aptos/index.js +91 -61
  15. package/dist/aptos/index.js.map +1 -1
  16. package/dist/aptos/logs.js +3 -3
  17. package/dist/aptos/logs.js.map +1 -1
  18. package/dist/chain.d.ts +300 -42
  19. package/dist/chain.d.ts.map +1 -1
  20. package/dist/chain.js +160 -9
  21. package/dist/chain.js.map +1 -1
  22. package/dist/errors/codes.d.ts +9 -3
  23. package/dist/errors/codes.d.ts.map +1 -1
  24. package/dist/errors/codes.js +10 -3
  25. package/dist/errors/codes.js.map +1 -1
  26. package/dist/errors/index.d.ts +8 -8
  27. package/dist/errors/index.d.ts.map +1 -1
  28. package/dist/errors/index.js +8 -8
  29. package/dist/errors/index.js.map +1 -1
  30. package/dist/errors/recovery.d.ts.map +1 -1
  31. package/dist/errors/recovery.js +10 -4
  32. package/dist/errors/recovery.js.map +1 -1
  33. package/dist/errors/specialized.d.ts +62 -21
  34. package/dist/errors/specialized.d.ts.map +1 -1
  35. package/dist/errors/specialized.js +128 -41
  36. package/dist/errors/specialized.js.map +1 -1
  37. package/dist/evm/extra-args.d.ts +25 -0
  38. package/dist/evm/extra-args.d.ts.map +1 -0
  39. package/dist/evm/extra-args.js +328 -0
  40. package/dist/evm/extra-args.js.map +1 -0
  41. package/dist/evm/gas.d.ts +14 -0
  42. package/dist/evm/gas.d.ts.map +1 -0
  43. package/dist/evm/gas.js +92 -0
  44. package/dist/evm/gas.js.map +1 -0
  45. package/dist/evm/index.d.ts +76 -32
  46. package/dist/evm/index.d.ts.map +1 -1
  47. package/dist/evm/index.js +94 -104
  48. package/dist/evm/index.js.map +1 -1
  49. package/dist/evm/offchain.d.ts.map +1 -1
  50. package/dist/evm/offchain.js +8 -8
  51. package/dist/evm/offchain.js.map +1 -1
  52. package/dist/execution.d.ts.map +1 -1
  53. package/dist/execution.js +24 -3
  54. package/dist/execution.js.map +1 -1
  55. package/dist/extra-args.d.ts +103 -4
  56. package/dist/extra-args.d.ts.map +1 -1
  57. package/dist/extra-args.js +28 -3
  58. package/dist/extra-args.js.map +1 -1
  59. package/dist/gas.d.ts +46 -19
  60. package/dist/gas.d.ts.map +1 -1
  61. package/dist/gas.js +56 -68
  62. package/dist/gas.js.map +1 -1
  63. package/dist/index.d.ts +18 -15
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +14 -13
  66. package/dist/index.js.map +1 -1
  67. package/dist/offchain.d.ts +5 -4
  68. package/dist/offchain.d.ts.map +1 -1
  69. package/dist/offchain.js +7 -6
  70. package/dist/offchain.js.map +1 -1
  71. package/dist/requests.d.ts +30 -20
  72. package/dist/requests.d.ts.map +1 -1
  73. package/dist/requests.js +86 -56
  74. package/dist/requests.js.map +1 -1
  75. package/dist/selectors.d.ts +2 -1
  76. package/dist/selectors.d.ts.map +1 -1
  77. package/dist/selectors.js +625 -278
  78. package/dist/selectors.js.map +1 -1
  79. package/dist/solana/exec.d.ts.map +1 -1
  80. package/dist/solana/exec.js +2 -1
  81. package/dist/solana/exec.js.map +1 -1
  82. package/dist/solana/index.d.ts +73 -22
  83. package/dist/solana/index.d.ts.map +1 -1
  84. package/dist/solana/index.js +91 -28
  85. package/dist/solana/index.js.map +1 -1
  86. package/dist/solana/offchain.js +2 -2
  87. package/dist/solana/offchain.js.map +1 -1
  88. package/dist/solana/send.d.ts.map +1 -1
  89. package/dist/solana/send.js +6 -9
  90. package/dist/solana/send.js.map +1 -1
  91. package/dist/solana/utils.d.ts +29 -1
  92. package/dist/solana/utils.d.ts.map +1 -1
  93. package/dist/solana/utils.js +39 -1
  94. package/dist/solana/utils.js.map +1 -1
  95. package/dist/sui/discovery.d.ts +7 -4
  96. package/dist/sui/discovery.d.ts.map +1 -1
  97. package/dist/sui/discovery.js +66 -19
  98. package/dist/sui/discovery.js.map +1 -1
  99. package/dist/sui/events.d.ts +23 -12
  100. package/dist/sui/events.d.ts.map +1 -1
  101. package/dist/sui/events.js +267 -128
  102. package/dist/sui/events.js.map +1 -1
  103. package/dist/sui/index.d.ts +57 -41
  104. package/dist/sui/index.d.ts.map +1 -1
  105. package/dist/sui/index.js +286 -159
  106. package/dist/sui/index.js.map +1 -1
  107. package/dist/sui/objects.d.ts +14 -4
  108. package/dist/sui/objects.d.ts.map +1 -1
  109. package/dist/sui/objects.js +61 -68
  110. package/dist/sui/objects.js.map +1 -1
  111. package/dist/sui/types.d.ts +33 -0
  112. package/dist/sui/types.d.ts.map +1 -1
  113. package/dist/sui/types.js.map +1 -1
  114. package/dist/ton/index.d.ts +67 -21
  115. package/dist/ton/index.d.ts.map +1 -1
  116. package/dist/ton/index.js +159 -30
  117. package/dist/ton/index.js.map +1 -1
  118. package/dist/ton/send.d.ts +52 -0
  119. package/dist/ton/send.d.ts.map +1 -0
  120. package/dist/ton/send.js +166 -0
  121. package/dist/ton/send.js.map +1 -0
  122. package/dist/ton/utils.d.ts +3 -3
  123. package/dist/ton/utils.d.ts.map +1 -1
  124. package/dist/ton/utils.js +6 -5
  125. package/dist/ton/utils.js.map +1 -1
  126. package/dist/types.d.ts +126 -9
  127. package/dist/types.d.ts.map +1 -1
  128. package/dist/types.js +19 -5
  129. package/dist/types.js.map +1 -1
  130. package/dist/utils.d.ts +67 -4
  131. package/dist/utils.d.ts.map +1 -1
  132. package/dist/utils.js +126 -17
  133. package/dist/utils.js.map +1 -1
  134. package/package.json +14 -9
  135. package/src/all-chains.ts +26 -0
  136. package/src/api/index.ts +348 -13
  137. package/src/api/types.ts +160 -13
  138. package/src/aptos/index.ts +98 -76
  139. package/src/aptos/logs.ts +3 -3
  140. package/src/chain.ts +408 -51
  141. package/src/errors/codes.ts +10 -3
  142. package/src/errors/index.ts +8 -5
  143. package/src/errors/recovery.ts +18 -5
  144. package/src/errors/specialized.ts +168 -49
  145. package/src/evm/extra-args.ts +377 -0
  146. package/src/evm/gas.ts +150 -0
  147. package/src/evm/index.ts +123 -155
  148. package/src/evm/offchain.ts +15 -9
  149. package/src/execution.ts +26 -3
  150. package/src/extra-args.ts +108 -4
  151. package/src/gas.ts +101 -115
  152. package/src/index.ts +27 -14
  153. package/src/offchain.ts +12 -6
  154. package/src/requests.ts +117 -67
  155. package/src/selectors.ts +632 -280
  156. package/src/solana/exec.ts +3 -1
  157. package/src/solana/index.ts +97 -37
  158. package/src/solana/offchain.ts +2 -2
  159. package/src/solana/send.ts +5 -23
  160. package/src/solana/utils.ts +66 -0
  161. package/src/sui/discovery.ts +92 -31
  162. package/src/sui/events.ts +346 -239
  163. package/src/sui/index.ts +365 -212
  164. package/src/sui/objects.ts +74 -98
  165. package/src/sui/types.ts +35 -0
  166. package/src/ton/index.ts +199 -35
  167. package/src/ton/send.ts +222 -0
  168. package/src/ton/utils.ts +7 -6
  169. package/src/types.ts +128 -9
  170. package/src/utils.ts +169 -21
package/src/requests.ts CHANGED
@@ -1,15 +1,14 @@
1
- import { isBytesLike, toBigInt } from 'ethers'
1
+ import { type BytesLike, hexlify, isBytesLike, toBigInt } from 'ethers'
2
2
  import type { PickDeep } from 'type-fest'
3
- import yaml from 'yaml'
4
3
 
5
4
  import { type ChainStatic, type LogFilter, Chain } from './chain.ts'
6
5
  import {
6
+ CCIPChainFamilyUnsupportedError,
7
7
  CCIPMessageBatchIncompleteError,
8
8
  CCIPMessageDecodeError,
9
9
  CCIPMessageIdNotFoundError,
10
10
  CCIPMessageInvalidError,
11
11
  CCIPMessageNotFoundInTxError,
12
- CCIPNetworkFamilyUnsupportedError,
13
12
  CCIPTokenNotInRegistryError,
14
13
  } from './errors/index.ts'
15
14
  import type { EVMChain } from './evm/index.ts'
@@ -25,7 +24,14 @@ import {
25
24
  type MessageInput,
26
25
  ChainFamily,
27
26
  } from './types.ts'
28
- import { convertKeysToCamelCase, decodeAddress, leToBigInt, networkInfo } from './utils.ts'
27
+ import {
28
+ convertKeysToCamelCase,
29
+ decodeAddress,
30
+ getDataBytes,
31
+ leToBigInt,
32
+ networkInfo,
33
+ parseJson,
34
+ } from './utils.ts'
29
35
 
30
36
  function decodeJsonMessage(data: Record<string, unknown> | undefined) {
31
37
  if (!data || typeof data != 'object') throw new CCIPMessageInvalidError(data)
@@ -39,63 +45,99 @@ function decodeJsonMessage(data: Record<string, unknown> | undefined) {
39
45
  destChainSelector?: string
40
46
  source_chain_selector?: string
41
47
  sourceChainSelector?: string
42
- extraArgs?: string
48
+ extraArgs?: string | Record<string, unknown>
43
49
  tokenAmounts: {
44
50
  destExecData: string
45
51
  destGasAmount?: bigint
52
+ token?: string
53
+ sourceTokenAddress?: string
46
54
  }[]
55
+ feeToken?: string
56
+ feeTokenAmount?: bigint
57
+ fees?: {
58
+ fixedFeesDetails: {
59
+ tokenAddress: string
60
+ totalAmount: bigint
61
+ }
62
+ }
63
+ sourceNetworkInfo?: { chainSelector: string }
64
+ destNetworkInfo?: { chainSelector: string }
47
65
  }
48
- const sourceChainSelector = data_.source_chain_selector ?? data_.sourceChainSelector
66
+ const sourceChainSelector =
67
+ data_.source_chain_selector ??
68
+ data_.sourceChainSelector ??
69
+ data_.sourceNetworkInfo?.chainSelector
49
70
  if (!sourceChainSelector) throw new CCIPMessageInvalidError(data)
50
- const sourceNetwork = networkInfo(sourceChainSelector)
71
+ data_.sourceChainSelector ??= sourceChainSelector
72
+ data_.nonce ??= 0n
73
+ const sourceFamily = networkInfo(sourceChainSelector).family
51
74
 
52
- const destChainSelector = data_.dest_chain_selector ?? data_.destChainSelector
53
- if (destChainSelector) {
54
- const destFamily = networkInfo(destChainSelector).family
55
- data_ = convertKeysToCamelCase(data_, (v, k) =>
56
- typeof v === 'string' && v.match(/^\d+$/)
57
- ? BigInt(v)
58
- : k === 'receiver' || k === 'destTokenAddress' || k === 'tokenReceiver'
59
- ? decodeAddress(v as string, destFamily)
60
- : v,
61
- ) as typeof data_
62
- }
75
+ const destChainSelector =
76
+ data_.dest_chain_selector ?? data_.destChainSelector ?? data_.destNetworkInfo?.chainSelector
77
+ if (destChainSelector) data_.destChainSelector ??= destChainSelector
78
+ const destFamily = destChainSelector ? networkInfo(destChainSelector).family : ChainFamily.EVM
79
+ // transform type, normalize keys case, source/dest addresses, and ensure known bigints
80
+ data_ = convertKeysToCamelCase(data_, (v, k) =>
81
+ k?.match(/(selector|amount|nonce|number|limit|bitmap|juels)$/i)
82
+ ? BigInt(v as string | number | bigint)
83
+ : k?.match(/(^dest.*address)|(receiver|offramp|accounts)/i)
84
+ ? decodeAddress(v as BytesLike, destFamily)
85
+ : k?.match(/((source.*address)|sender|origin|onramp|(feetoken$)|(token.*address$))/i)
86
+ ? decodeAddress(v as BytesLike, sourceFamily)
87
+ : v instanceof Uint8Array ||
88
+ (Array.isArray(v) && v.length >= 4 && v.every((e) => typeof e === 'number'))
89
+ ? hexlify(getDataBytes(v as readonly number[]))
90
+ : v,
91
+ ) as typeof data_
63
92
 
64
93
  for (const ta of data_.tokenAmounts) {
94
+ if (ta.token && !ta.sourceTokenAddress) ta.sourceTokenAddress = ta.token
95
+ if (!ta.token && ta.sourceTokenAddress) ta.token = ta.sourceTokenAddress
65
96
  if (ta.destGasAmount != null || !ta.destExecData) continue
66
- switch (sourceNetwork.family) {
97
+ switch (sourceFamily) {
67
98
  // EVM & Solana encode destExecData as big-endian
68
99
  case ChainFamily.EVM:
69
100
  case ChainFamily.Solana:
70
- ta.destGasAmount = toBigInt(ta.destExecData)
101
+ ta.destGasAmount = toBigInt(getDataBytes(ta.destExecData))
71
102
  break
72
103
  // Aptos & Sui, as little-endian
73
104
  default:
74
- ta.destGasAmount = leToBigInt(ta.destExecData)
105
+ ta.destGasAmount = leToBigInt(getDataBytes(ta.destExecData))
75
106
  }
76
107
  }
77
108
 
78
- if (data_.extraArgs) {
79
- const extraArgs = decodeExtraArgs(data_.extraArgs ?? '', sourceNetwork.family)
109
+ if (data_.extraArgs && typeof data_.extraArgs === 'string') {
110
+ const extraArgs = decodeExtraArgs(data_.extraArgs, sourceFamily)
80
111
  if (extraArgs) {
81
112
  const { _tag, ...rest } = extraArgs
82
113
  Object.assign(data_, rest)
83
114
  }
115
+ } else if (data_.extraArgs) {
116
+ Object.assign(data_, data_.extraArgs)
117
+ delete data_.extraArgs
84
118
  }
119
+
120
+ if (data_.fees && !data_.feeToken) {
121
+ data_.feeToken = data_.fees.fixedFeesDetails.tokenAddress
122
+ data_.feeTokenAmount = data_.fees.fixedFeesDetails.totalAmount
123
+ }
124
+
85
125
  return data_ as unknown as CCIPMessage
86
126
  }
87
127
 
88
128
  /**
89
- * Decodes hex strings, bytearrays, JSON strings and raw objects as CCIPMessages
90
- * Does minimal validation, but converts objects in the format expected by ccip-tools-ts
91
- **/
129
+ * Decodes hex strings, bytearrays, JSON strings and raw objects as CCIPMessages.
130
+ * Does minimal validation, but converts objects in the format expected by ccip-tools-ts.
131
+ * @param data - Data to decode (hex string, Uint8Array, JSON string, or object)
132
+ * @returns Decoded CCIPMessage
133
+ * @throws {@link CCIPMessageDecodeError} if data cannot be decoded as a valid message
134
+ */
92
135
  export function decodeMessage(data: string | Uint8Array | Record<string, unknown>): CCIPMessage {
93
136
  if (
94
137
  (typeof data === 'string' && data.startsWith('{')) ||
95
138
  (typeof data === 'object' && !isBytesLike(data))
96
139
  ) {
97
- if (typeof data === 'string')
98
- data = yaml.parse(data, { intAsBigInt: true }) as Record<string, unknown>
140
+ if (typeof data === 'string') data = parseJson<Record<string, unknown>>(data)
99
141
  return decodeJsonMessage(data)
100
142
  }
101
143
 
@@ -112,24 +154,26 @@ export function decodeMessage(data: string | Uint8Array | Record<string, unknown
112
154
  }
113
155
 
114
156
  /**
115
- * Populates missing required fields (e.g. `extraArgs`) from AnyMessage
116
- * @param message - partial AnyMessage
117
- * @returns original message or shallow copy with defaults for required fields
118
- **/
157
+ * Populates missing required fields (e.g. `extraArgs`) from AnyMessage.
158
+ * @param message - Partial AnyMessage with at least receiver
159
+ * @param dest - Destination chain family to build message for
160
+ * @returns Original message or shallow copy with defaults for required fields
161
+ */
119
162
  export function buildMessageForDest(message: MessageInput, dest: ChainFamily): AnyMessage {
120
163
  const chain = supportedChains[dest] ?? Chain
121
164
  return chain.buildMessageForDest(message)
122
165
  }
123
166
 
124
167
  /**
125
- * Fetch all CCIP messages in a transaction
126
- * @param source - Chain
168
+ * Fetch all CCIP messages in a transaction.
169
+ * @param source - Source chain instance
127
170
  * @param tx - ChainTransaction to search in
128
171
  * @returns CCIP requests (messages) in the transaction (at least one)
129
- **/
172
+ * @throws {@link CCIPChainFamilyUnsupportedError} if chain family not supported for legacy messages
173
+ * @throws {@link CCIPMessageNotFoundInTxError} if no CCIP messages found in transaction
174
+ */
130
175
  export async function getMessagesInTx(source: Chain, tx: ChainTransaction): Promise<CCIPRequest[]> {
131
- const txHash = tx.hash
132
-
176
+ // RPC fallback
133
177
  const requests: CCIPRequest[] = []
134
178
  for (const log of tx.logs) {
135
179
  let lane
@@ -144,35 +188,34 @@ export async function getMessagesInTx(source: Chain, tx: ChainTransaction): Prom
144
188
  version: version as CCIPVersion,
145
189
  }
146
190
  } else if (source.network.family !== ChainFamily.EVM) {
147
- throw new CCIPNetworkFamilyUnsupportedError(source.network.family)
191
+ throw new CCIPChainFamilyUnsupportedError(source.network.family)
148
192
  } else {
149
193
  lane = await (source as EVMChain).getLaneForOnRamp(log.address)
150
194
  }
151
195
  requests.push({ lane, message, log, tx })
152
196
  }
153
- if (!requests.length) {
154
- throw new CCIPMessageNotFoundInTxError(txHash)
155
- }
156
-
197
+ if (!requests.length) throw new CCIPMessageNotFoundInTxError(tx.hash)
157
198
  return requests
158
199
  }
159
200
 
160
201
  /**
161
- * Fetch a CCIP message by its messageId.
162
- * Can be slow due to having to paginate backwards through logs.
202
+ * Fetch a CCIP message by its messageId from RPC (slow).
203
+ * Should be called *after* generic Chain implementation, which fetches from API if available.
163
204
  * @param source - Provider to fetch logs from.
164
205
  * @param messageId - MessageId to search for.
165
- * @param hints - Optional hints for pagination (e.g., `address` for onRamp, `page` for pagination size).
206
+ * @param opts - Optional hints for pagination (e.g., `address` for onRamp, `page` for pagination size).
166
207
  * @returns CCIPRequest with given messageId.
208
+ * @internal
167
209
  */
168
210
  export async function getMessageById(
169
211
  source: Chain,
170
212
  messageId: string,
171
- hints?: { page?: number; address?: string },
213
+ opts?: { page?: number; onRamp?: string },
172
214
  ): Promise<CCIPRequest> {
173
215
  for await (const log of source.getLogs({
174
216
  topics: ['CCIPSendRequested', 'CCIPMessageSent'],
175
- ...hints,
217
+ address: opts?.onRamp,
218
+ ...opts,
176
219
  })) {
177
220
  const message = (source.constructor as ChainStatic).decodeMessage(log)
178
221
  if (message?.messageId !== messageId) continue
@@ -295,6 +338,7 @@ export async function getMessagesInBatch<
295
338
  * @param sender - Sender address.
296
339
  * @param filter - Log filter options.
297
340
  * @returns Async generator of CCIP requests.
341
+ * @throws {@link CCIPChainFamilyUnsupportedError} if chain family not supported for legacy messages
298
342
  */
299
343
  export async function* getMessagesForSender(
300
344
  source: Chain,
@@ -316,7 +360,7 @@ export async function* getMessagesForSender(
316
360
  } else if (source.network.family === ChainFamily.EVM) {
317
361
  ;({ destChainSelector, version } = await (source as EVMChain).getLaneForOnRamp(log.address))
318
362
  } else {
319
- throw new CCIPNetworkFamilyUnsupportedError(source.network.family)
363
+ throw new CCIPChainFamilyUnsupportedError(source.network.family)
320
364
  }
321
365
  yield {
322
366
  lane: {
@@ -336,29 +380,35 @@ export async function* getMessagesForSender(
336
380
  * @param source - Source chain.
337
381
  * @param destChainSelector - Destination network selector.
338
382
  * @param onRamp - Contract address.
339
- * @param sourceTokenAmounts - Array of token amounts, usually containing `token` and `amount` properties.
340
- * @returns Array of objects with `sourcePoolAddress`, `destTokenAddress`, and remaining properties.
383
+ * @param sourceTokenAmount - tokenAmount object, usually containing `token` and `amount` properties.
384
+ * @returns tokenAmount object with `sourcePoolAddress`, `sourceTokenAddress`, `destTokenAddress`, and remaining properties.
385
+ * @throws {@link CCIPTokenNotInRegistryError} if token not found in registry
341
386
  */
342
- export async function sourceToDestTokenAmounts<S extends { token: string }>(
387
+ export async function sourceToDestTokenAddresses<S extends { token: string }>(
343
388
  source: Chain,
344
389
  destChainSelector: bigint,
345
390
  onRamp: string,
346
- sourceTokenAmounts: readonly S[],
347
- ): Promise<(Omit<S, 'token'> & { sourcePoolAddress: string; destTokenAddress: string })[]> {
391
+ sourceTokenAmount: S,
392
+ ): Promise<
393
+ S & {
394
+ sourcePoolAddress: string
395
+ sourceTokenAddress: string
396
+ destTokenAddress: string
397
+ }
398
+ > {
348
399
  const tokenAdminRegistry = await source.getTokenAdminRegistryFor(onRamp)
349
- return Promise.all(
350
- sourceTokenAmounts.map(async ({ token, ...rest }) => {
351
- const { tokenPool: sourcePoolAddress } = await source.getRegistryTokenConfig(
352
- tokenAdminRegistry,
353
- token,
354
- )
355
- if (!sourcePoolAddress) throw new CCIPTokenNotInRegistryError(token, tokenAdminRegistry)
356
- const remotes = await source.getTokenPoolRemotes(sourcePoolAddress, destChainSelector)
357
- return {
358
- ...rest,
359
- sourcePoolAddress,
360
- destTokenAddress: remotes[networkInfo(destChainSelector).name]!.remoteToken,
361
- }
362
- }),
400
+ const sourceTokenAddress = sourceTokenAmount.token
401
+ const { tokenPool: sourcePoolAddress } = await source.getRegistryTokenConfig(
402
+ tokenAdminRegistry,
403
+ sourceTokenAddress,
363
404
  )
405
+ if (!sourcePoolAddress)
406
+ throw new CCIPTokenNotInRegistryError(sourceTokenAddress, tokenAdminRegistry)
407
+ const remotes = await source.getTokenPoolRemotes(sourcePoolAddress, destChainSelector)
408
+ return {
409
+ ...sourceTokenAmount,
410
+ sourcePoolAddress,
411
+ sourceTokenAddress,
412
+ destTokenAddress: remotes[networkInfo(destChainSelector).name]!.remoteToken,
413
+ }
364
414
  }