@chainlink/ccip-sdk 0.0.0 → 0.90.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 (319) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +109 -0
  3. package/dist/aptos/exec.d.ts +18 -0
  4. package/dist/aptos/exec.d.ts.map +1 -0
  5. package/dist/aptos/exec.js +55 -0
  6. package/dist/aptos/exec.js.map +1 -0
  7. package/dist/aptos/hasher.d.ts +11 -0
  8. package/dist/aptos/hasher.d.ts.map +1 -0
  9. package/dist/aptos/hasher.js +62 -0
  10. package/dist/aptos/hasher.js.map +1 -0
  11. package/dist/aptos/index.d.ts +92 -0
  12. package/dist/aptos/index.d.ts.map +1 -0
  13. package/dist/aptos/index.js +482 -0
  14. package/dist/aptos/index.js.map +1 -0
  15. package/dist/aptos/logs.d.ts +9 -0
  16. package/dist/aptos/logs.d.ts.map +1 -0
  17. package/dist/aptos/logs.js +167 -0
  18. package/dist/aptos/logs.js.map +1 -0
  19. package/dist/aptos/send.d.ts +11 -0
  20. package/dist/aptos/send.d.ts.map +1 -0
  21. package/dist/aptos/send.js +78 -0
  22. package/dist/aptos/send.js.map +1 -0
  23. package/dist/aptos/token.d.ts +4 -0
  24. package/dist/aptos/token.d.ts.map +1 -0
  25. package/dist/aptos/token.js +134 -0
  26. package/dist/aptos/token.js.map +1 -0
  27. package/dist/aptos/types.d.ts +78 -0
  28. package/dist/aptos/types.d.ts.map +1 -0
  29. package/dist/aptos/types.js +60 -0
  30. package/dist/aptos/types.js.map +1 -0
  31. package/dist/aptos/utils.d.ts +12 -0
  32. package/dist/aptos/utils.d.ts.map +1 -0
  33. package/dist/aptos/utils.js +15 -0
  34. package/dist/aptos/utils.js.map +1 -0
  35. package/dist/chain.d.ts +344 -0
  36. package/dist/chain.d.ts.map +1 -0
  37. package/dist/chain.js +41 -0
  38. package/dist/chain.js.map +1 -0
  39. package/dist/commits.d.ts +25 -0
  40. package/dist/commits.d.ts.map +1 -0
  41. package/dist/commits.js +29 -0
  42. package/dist/commits.js.map +1 -0
  43. package/dist/evm/abi/BurnMintERC677Token.d.ts +602 -0
  44. package/dist/evm/abi/BurnMintERC677Token.d.ts.map +1 -0
  45. package/dist/evm/abi/BurnMintERC677Token.js +488 -0
  46. package/dist/evm/abi/BurnMintERC677Token.js.map +1 -0
  47. package/dist/evm/abi/CommitStore_1_2.d.ts +688 -0
  48. package/dist/evm/abi/CommitStore_1_2.d.ts.map +1 -0
  49. package/dist/evm/abi/CommitStore_1_2.js +638 -0
  50. package/dist/evm/abi/CommitStore_1_2.js.map +1 -0
  51. package/dist/evm/abi/CommitStore_1_5.d.ts +708 -0
  52. package/dist/evm/abi/CommitStore_1_5.d.ts.map +1 -0
  53. package/dist/evm/abi/CommitStore_1_5.js +675 -0
  54. package/dist/evm/abi/CommitStore_1_5.js.map +1 -0
  55. package/dist/evm/abi/FeeQuoter_1_6.d.ts +1770 -0
  56. package/dist/evm/abi/FeeQuoter_1_6.d.ts.map +1 -0
  57. package/dist/evm/abi/FeeQuoter_1_6.js +1904 -0
  58. package/dist/evm/abi/FeeQuoter_1_6.js.map +1 -0
  59. package/dist/evm/abi/LockReleaseTokenPool_1_5.d.ts +1116 -0
  60. package/dist/evm/abi/LockReleaseTokenPool_1_5.d.ts.map +1 -0
  61. package/dist/evm/abi/LockReleaseTokenPool_1_5.js +1096 -0
  62. package/dist/evm/abi/LockReleaseTokenPool_1_5.js.map +1 -0
  63. package/dist/evm/abi/LockReleaseTokenPool_1_5_1.d.ts +1306 -0
  64. package/dist/evm/abi/LockReleaseTokenPool_1_5_1.d.ts.map +1 -0
  65. package/dist/evm/abi/LockReleaseTokenPool_1_5_1.js +1278 -0
  66. package/dist/evm/abi/LockReleaseTokenPool_1_5_1.js.map +1 -0
  67. package/dist/evm/abi/LockReleaseTokenPool_1_6_1.d.ts +1290 -0
  68. package/dist/evm/abi/LockReleaseTokenPool_1_6_1.d.ts.map +1 -0
  69. package/dist/evm/abi/LockReleaseTokenPool_1_6_1.js +1288 -0
  70. package/dist/evm/abi/LockReleaseTokenPool_1_6_1.js.map +1 -0
  71. package/dist/evm/abi/OffRamp_1_2.d.ts +1217 -0
  72. package/dist/evm/abi/OffRamp_1_2.d.ts.map +1 -0
  73. package/dist/evm/abi/OffRamp_1_2.js +1204 -0
  74. package/dist/evm/abi/OffRamp_1_2.js.map +1 -0
  75. package/dist/evm/abi/OffRamp_1_5.d.ts +1271 -0
  76. package/dist/evm/abi/OffRamp_1_5.d.ts.map +1 -0
  77. package/dist/evm/abi/OffRamp_1_5.js +1273 -0
  78. package/dist/evm/abi/OffRamp_1_5.js.map +1 -0
  79. package/dist/evm/abi/OffRamp_1_6.d.ts +1472 -0
  80. package/dist/evm/abi/OffRamp_1_6.d.ts.map +1 -0
  81. package/dist/evm/abi/OffRamp_1_6.js +1529 -0
  82. package/dist/evm/abi/OffRamp_1_6.js.map +1 -0
  83. package/dist/evm/abi/OnRamp_1_2.d.ts +1391 -0
  84. package/dist/evm/abi/OnRamp_1_2.d.ts.map +1 -0
  85. package/dist/evm/abi/OnRamp_1_2.js +1343 -0
  86. package/dist/evm/abi/OnRamp_1_2.js.map +1 -0
  87. package/dist/evm/abi/OnRamp_1_5.d.ts +1443 -0
  88. package/dist/evm/abi/OnRamp_1_5.d.ts.map +1 -0
  89. package/dist/evm/abi/OnRamp_1_5.js +1427 -0
  90. package/dist/evm/abi/OnRamp_1_5.js.map +1 -0
  91. package/dist/evm/abi/OnRamp_1_6.d.ts +796 -0
  92. package/dist/evm/abi/OnRamp_1_6.d.ts.map +1 -0
  93. package/dist/evm/abi/OnRamp_1_6.js +880 -0
  94. package/dist/evm/abi/OnRamp_1_6.js.map +1 -0
  95. package/dist/evm/abi/Router.d.ts +541 -0
  96. package/dist/evm/abi/Router.d.ts.map +1 -0
  97. package/dist/evm/abi/Router.js +508 -0
  98. package/dist/evm/abi/Router.js.map +1 -0
  99. package/dist/evm/abi/TokenAdminRegistry_1_5.d.ts +373 -0
  100. package/dist/evm/abi/TokenAdminRegistry_1_5.d.ts.map +1 -0
  101. package/dist/evm/abi/TokenAdminRegistry_1_5.js +333 -0
  102. package/dist/evm/abi/TokenAdminRegistry_1_5.js.map +1 -0
  103. package/dist/evm/const.d.ts +27 -0
  104. package/dist/evm/const.d.ts.map +1 -0
  105. package/dist/evm/const.js +63 -0
  106. package/dist/evm/const.js.map +1 -0
  107. package/dist/evm/errors.d.ts +36 -0
  108. package/dist/evm/errors.d.ts.map +1 -0
  109. package/dist/evm/errors.js +192 -0
  110. package/dist/evm/errors.js.map +1 -0
  111. package/dist/evm/hasher.d.ts +5 -0
  112. package/dist/evm/hasher.d.ts.map +1 -0
  113. package/dist/evm/hasher.js +116 -0
  114. package/dist/evm/hasher.js.map +1 -0
  115. package/dist/evm/index.d.ts +121 -0
  116. package/dist/evm/index.d.ts.map +1 -0
  117. package/dist/evm/index.js +904 -0
  118. package/dist/evm/index.js.map +1 -0
  119. package/dist/evm/messages.d.ts +35 -0
  120. package/dist/evm/messages.d.ts.map +1 -0
  121. package/dist/evm/messages.js +11 -0
  122. package/dist/evm/messages.js.map +1 -0
  123. package/dist/evm/offchain.d.ts +16 -0
  124. package/dist/evm/offchain.d.ts.map +1 -0
  125. package/dist/evm/offchain.js +142 -0
  126. package/dist/evm/offchain.js.map +1 -0
  127. package/dist/execution.d.ts +80 -0
  128. package/dist/execution.d.ts.map +1 -0
  129. package/dist/execution.js +91 -0
  130. package/dist/execution.js.map +1 -0
  131. package/dist/extra-args.d.ts +45 -0
  132. package/dist/extra-args.d.ts.map +1 -0
  133. package/dist/extra-args.js +44 -0
  134. package/dist/extra-args.js.map +1 -0
  135. package/dist/gas.d.ts +27 -0
  136. package/dist/gas.d.ts.map +1 -0
  137. package/dist/gas.js +80 -0
  138. package/dist/gas.js.map +1 -0
  139. package/dist/hasher/common.d.ts +12 -0
  140. package/dist/hasher/common.d.ts.map +1 -0
  141. package/dist/hasher/common.js +19 -0
  142. package/dist/hasher/common.js.map +1 -0
  143. package/dist/hasher/hasher.d.ts +4 -0
  144. package/dist/hasher/hasher.d.ts.map +1 -0
  145. package/dist/hasher/hasher.js +11 -0
  146. package/dist/hasher/hasher.js.map +1 -0
  147. package/dist/hasher/index.d.ts +4 -0
  148. package/dist/hasher/index.d.ts.map +1 -0
  149. package/dist/hasher/index.js +4 -0
  150. package/dist/hasher/index.js.map +1 -0
  151. package/dist/hasher/merklemulti.d.ts +58 -0
  152. package/dist/hasher/merklemulti.d.ts.map +1 -0
  153. package/dist/hasher/merklemulti.js +257 -0
  154. package/dist/hasher/merklemulti.js.map +1 -0
  155. package/dist/index.d.ts +13 -0
  156. package/dist/index.d.ts.map +1 -0
  157. package/dist/index.js +13 -0
  158. package/dist/index.js.map +1 -0
  159. package/dist/offchain.d.ts +20 -0
  160. package/dist/offchain.d.ts.map +1 -0
  161. package/dist/offchain.js +59 -0
  162. package/dist/offchain.js.map +1 -0
  163. package/dist/requests.d.ts +48 -0
  164. package/dist/requests.d.ts.map +1 -0
  165. package/dist/requests.js +286 -0
  166. package/dist/requests.js.map +1 -0
  167. package/dist/selectors.d.ts +9 -0
  168. package/dist/selectors.d.ts.map +1 -0
  169. package/dist/selectors.js +1330 -0
  170. package/dist/selectors.js.map +1 -0
  171. package/dist/solana/cleanup.d.ts +15 -0
  172. package/dist/solana/cleanup.d.ts.map +1 -0
  173. package/dist/solana/cleanup.js +159 -0
  174. package/dist/solana/cleanup.js.map +1 -0
  175. package/dist/solana/exec.d.ts +15 -0
  176. package/dist/solana/exec.d.ts.map +1 -0
  177. package/dist/solana/exec.js +417 -0
  178. package/dist/solana/exec.js.map +1 -0
  179. package/dist/solana/hasher.d.ts +4 -0
  180. package/dist/solana/hasher.d.ts.map +1 -0
  181. package/dist/solana/hasher.js +81 -0
  182. package/dist/solana/hasher.js.map +1 -0
  183. package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.d.ts +866 -0
  184. package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.d.ts.map +1 -0
  185. package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.js +866 -0
  186. package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.js.map +1 -0
  187. package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.d.ts +949 -0
  188. package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.d.ts.map +1 -0
  189. package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.js +949 -0
  190. package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.js.map +1 -0
  191. package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.d.ts +1374 -0
  192. package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.d.ts.map +1 -0
  193. package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.js +1374 -0
  194. package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.js.map +1 -0
  195. package/dist/solana/idl/1.6.0/CCIP_COMMON.d.ts +104 -0
  196. package/dist/solana/idl/1.6.0/CCIP_COMMON.d.ts.map +1 -0
  197. package/dist/solana/idl/1.6.0/CCIP_COMMON.js +104 -0
  198. package/dist/solana/idl/1.6.0/CCIP_COMMON.js.map +1 -0
  199. package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.d.ts +2746 -0
  200. package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.d.ts.map +1 -0
  201. package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.js +2746 -0
  202. package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.js.map +1 -0
  203. package/dist/solana/idl/1.6.0/CCIP_ROUTER.d.ts +2332 -0
  204. package/dist/solana/idl/1.6.0/CCIP_ROUTER.d.ts.map +1 -0
  205. package/dist/solana/idl/1.6.0/CCIP_ROUTER.js +2332 -0
  206. package/dist/solana/idl/1.6.0/CCIP_ROUTER.js.map +1 -0
  207. package/dist/solana/index.d.ts +205 -0
  208. package/dist/solana/index.d.ts.map +1 -0
  209. package/dist/solana/index.js +1085 -0
  210. package/dist/solana/index.js.map +1 -0
  211. package/dist/solana/offchain.d.ts +31 -0
  212. package/dist/solana/offchain.d.ts.map +1 -0
  213. package/dist/solana/offchain.js +152 -0
  214. package/dist/solana/offchain.js.map +1 -0
  215. package/dist/solana/patchBorsh.d.ts +2 -0
  216. package/dist/solana/patchBorsh.d.ts.map +1 -0
  217. package/dist/solana/patchBorsh.js +60 -0
  218. package/dist/solana/patchBorsh.js.map +1 -0
  219. package/dist/solana/send.d.ts +14 -0
  220. package/dist/solana/send.d.ts.map +1 -0
  221. package/dist/solana/send.js +272 -0
  222. package/dist/solana/send.js.map +1 -0
  223. package/dist/solana/types.d.ts +4 -0
  224. package/dist/solana/types.d.ts.map +1 -0
  225. package/dist/solana/types.js +2 -0
  226. package/dist/solana/types.js.map +1 -0
  227. package/dist/solana/utils.d.ts +58 -0
  228. package/dist/solana/utils.d.ts.map +1 -0
  229. package/dist/solana/utils.js +211 -0
  230. package/dist/solana/utils.js.map +1 -0
  231. package/dist/sui/hasher.d.ts +12 -0
  232. package/dist/sui/hasher.d.ts.map +1 -0
  233. package/dist/sui/hasher.js +63 -0
  234. package/dist/sui/hasher.js.map +1 -0
  235. package/dist/sui/index.d.ts +72 -0
  236. package/dist/sui/index.d.ts.map +1 -0
  237. package/dist/sui/index.js +128 -0
  238. package/dist/sui/index.js.map +1 -0
  239. package/dist/sui/types.d.ts +17 -0
  240. package/dist/sui/types.d.ts.map +1 -0
  241. package/dist/sui/types.js +17 -0
  242. package/dist/sui/types.js.map +1 -0
  243. package/dist/supported-chains.d.ts +5 -0
  244. package/dist/supported-chains.d.ts.map +1 -0
  245. package/dist/supported-chains.js +3 -0
  246. package/dist/supported-chains.js.map +1 -0
  247. package/dist/types.d.ts +118 -0
  248. package/dist/types.d.ts.map +1 -0
  249. package/dist/types.js +11 -0
  250. package/dist/types.js.map +1 -0
  251. package/dist/utils.d.ts +117 -0
  252. package/dist/utils.d.ts.map +1 -0
  253. package/dist/utils.js +336 -0
  254. package/dist/utils.js.map +1 -0
  255. package/package.json +66 -8
  256. package/src/aptos/exec.ts +69 -0
  257. package/src/aptos/hasher.ts +92 -0
  258. package/src/aptos/index.ts +660 -0
  259. package/src/aptos/logs.ts +210 -0
  260. package/src/aptos/send.ts +120 -0
  261. package/src/aptos/token.ts +150 -0
  262. package/src/aptos/types.ts +85 -0
  263. package/src/aptos/utils.ts +24 -0
  264. package/src/chain.ts +398 -0
  265. package/src/commits.ts +44 -0
  266. package/src/evm/abi/BurnMintERC677Token.ts +487 -0
  267. package/src/evm/abi/CommitStore_1_2.ts +637 -0
  268. package/src/evm/abi/CommitStore_1_5.ts +674 -0
  269. package/src/evm/abi/FeeQuoter_1_6.ts +1903 -0
  270. package/src/evm/abi/LockReleaseTokenPool_1_5.ts +1095 -0
  271. package/src/evm/abi/LockReleaseTokenPool_1_5_1.ts +1277 -0
  272. package/src/evm/abi/LockReleaseTokenPool_1_6_1.ts +1287 -0
  273. package/src/evm/abi/OffRamp_1_2.ts +1203 -0
  274. package/src/evm/abi/OffRamp_1_5.ts +1272 -0
  275. package/src/evm/abi/OffRamp_1_6.ts +1528 -0
  276. package/src/evm/abi/OnRamp_1_2.ts +1342 -0
  277. package/src/evm/abi/OnRamp_1_5.ts +1426 -0
  278. package/src/evm/abi/OnRamp_1_6.ts +879 -0
  279. package/src/evm/abi/Router.ts +507 -0
  280. package/src/evm/abi/TokenAdminRegistry_1_5.ts +332 -0
  281. package/src/evm/const.ts +69 -0
  282. package/src/evm/errors.ts +212 -0
  283. package/src/evm/hasher.ts +166 -0
  284. package/src/evm/index.ts +1262 -0
  285. package/src/evm/messages.ts +73 -0
  286. package/src/evm/offchain.ts +189 -0
  287. package/src/execution.ts +131 -0
  288. package/src/extra-args.ts +71 -0
  289. package/src/gas.ts +135 -0
  290. package/src/hasher/common.ts +23 -0
  291. package/src/hasher/hasher.ts +12 -0
  292. package/src/hasher/index.ts +3 -0
  293. package/src/hasher/merklemulti.ts +309 -0
  294. package/src/index.ts +51 -0
  295. package/src/offchain.ts +86 -0
  296. package/src/requests.ts +339 -0
  297. package/src/selectors.ts +1340 -0
  298. package/src/solana/cleanup.ts +216 -0
  299. package/src/solana/exec.ts +645 -0
  300. package/src/solana/hasher.ts +104 -0
  301. package/src/solana/idl/1.6.0/BASE_TOKEN_POOL.ts +1734 -0
  302. package/src/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.ts +1900 -0
  303. package/src/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.ts +2750 -0
  304. package/src/solana/idl/1.6.0/CCIP_COMMON.ts +210 -0
  305. package/src/solana/idl/1.6.0/CCIP_OFFRAMP.ts +5494 -0
  306. package/src/solana/idl/1.6.0/CCIP_ROUTER.ts +4671 -0
  307. package/src/solana/index.ts +1454 -0
  308. package/src/solana/offchain.ts +209 -0
  309. package/src/solana/patchBorsh.ts +67 -0
  310. package/src/solana/send.ts +436 -0
  311. package/src/solana/types.ts +6 -0
  312. package/src/solana/utils.ts +272 -0
  313. package/src/sui/hasher.ts +90 -0
  314. package/src/sui/index.ts +198 -0
  315. package/src/sui/types.ts +22 -0
  316. package/src/supported-chains.ts +4 -0
  317. package/src/types.ts +153 -0
  318. package/src/utils.ts +405 -0
  319. package/tsconfig.json +18 -0
@@ -0,0 +1,339 @@
1
+ import util from 'util'
2
+
3
+ import { isBytesLike, toBigInt } from 'ethers'
4
+ import yaml from 'yaml'
5
+
6
+ import {
7
+ type Chain,
8
+ type ChainStatic,
9
+ type ChainTransaction,
10
+ type LogFilter,
11
+ ChainFamily,
12
+ } from './chain.ts'
13
+ import type { EVMChain } from './evm/index.ts'
14
+ import { decodeExtraArgs } from './extra-args.ts'
15
+ import { supportedChains } from './supported-chains.ts'
16
+ import type { CCIPMessage, CCIPRequest, CCIPVersion, Log_ } from './types.ts'
17
+ import { convertKeysToCamelCase, decodeAddress, leToBigInt, networkInfo } from './utils.ts'
18
+
19
+ function decodeJsonMessage(data: Record<string, unknown>) {
20
+ if (!data || typeof data != 'object') throw new Error(`invalid msg: ${util.inspect(data)}`)
21
+ if (data.message) data = data.message as Record<string, unknown>
22
+ let data_ = data as Record<string, unknown> & {
23
+ header: {
24
+ dest_chain_selector?: string
25
+ destChainSelector?: string
26
+ sourceChainSelector?: string
27
+ source_chain_selector?: string
28
+ }
29
+ sourceChainSelector?: string
30
+ extraArgs?: string
31
+ tokenAmounts: {
32
+ destExecData: string
33
+ destGasAmount?: bigint
34
+ }[]
35
+ }
36
+ const sourceChainSelector =
37
+ data_.header?.sourceChainSelector ??
38
+ data_.header?.source_chain_selector ??
39
+ data_.sourceChainSelector
40
+ if (!sourceChainSelector) throw new Error(`invalid msg: ${util.inspect(data)}`)
41
+ const sourceNetwork = networkInfo(sourceChainSelector)
42
+ if (!data_.header) {
43
+ const header = {
44
+ sourceChainSelector: data_.sourceChainSelector,
45
+ messageId: data_.messageId,
46
+ nonce: data_.nonce,
47
+ sequenceNumber: data_.sequenceNumber,
48
+ }
49
+ data_.header = header
50
+ }
51
+
52
+ const destChainSelector = data_.header.dest_chain_selector ?? data_.header.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'
59
+ ? decodeAddress(v as string, destFamily)
60
+ : v,
61
+ ) as typeof data_
62
+ }
63
+
64
+ for (const ta of data_.tokenAmounts) {
65
+ if (ta.destGasAmount != null || ta.destExecData == null) continue
66
+ switch (sourceNetwork.family) {
67
+ // EVM & Solana encode destExecData as big-endian
68
+ case ChainFamily.EVM:
69
+ case ChainFamily.Solana:
70
+ ta.destGasAmount = toBigInt(ta.destExecData)
71
+ break
72
+ // Aptos & Sui, as little-endian
73
+ default:
74
+ ta.destGasAmount = leToBigInt(ta.destExecData)
75
+ }
76
+ }
77
+
78
+ if (data_.extraArgs) {
79
+ const extraArgs = decodeExtraArgs(data_.extraArgs ?? '', sourceNetwork.family)
80
+ if (extraArgs) {
81
+ const { _tag, ...rest } = extraArgs
82
+ Object.assign(data_, rest)
83
+ }
84
+ }
85
+ return data_ as unknown as CCIPMessage
86
+ }
87
+
88
+ /**
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
+ **/
92
+ export function decodeMessage(data: string | Uint8Array | Record<string, unknown>): CCIPMessage {
93
+ if (
94
+ (typeof data === 'string' && data.startsWith('{')) ||
95
+ (typeof data === 'object' && data !== null && !isBytesLike(data))
96
+ ) {
97
+ if (typeof data === 'string')
98
+ data = yaml.parse(data, { intAsBigInt: true }) as Record<string, unknown>
99
+ return decodeJsonMessage(data)
100
+ }
101
+
102
+ // try bytearray decoding on each supported chain
103
+ for (const chain of Object.values(supportedChains)) {
104
+ try {
105
+ const decoded = chain.decodeMessage({ data } as unknown as Log_)
106
+ if (decoded) return decoded
107
+ } catch (_) {
108
+ // continue
109
+ }
110
+ }
111
+ throw new Error('Failed to decode message')
112
+ }
113
+
114
+ /**
115
+ * Fetch all CCIP messages in a transaction
116
+ * @param tx - TransactionReceipt to search in
117
+ * @returns CCIP messages in the transaction (at least one)
118
+ **/
119
+ export async function fetchCCIPRequestsInTx(tx: ChainTransaction): Promise<CCIPRequest[]> {
120
+ const source = tx.chain
121
+ const txHash = tx.hash
122
+ const timestamp = tx.timestamp
123
+
124
+ const requests: CCIPRequest[] = []
125
+ for (const log of tx.logs) {
126
+ let lane
127
+ const message = (source.constructor as ChainStatic).decodeMessage(log)
128
+ if (!message) continue
129
+ if ('destChainSelector' in message.header) {
130
+ const [_, version] = await source.typeAndVersion(log.address)
131
+ lane = {
132
+ sourceChainSelector: message.header.sourceChainSelector,
133
+ destChainSelector: message.header.destChainSelector,
134
+ onRamp: log.address,
135
+ version: version as CCIPVersion,
136
+ }
137
+ } else if (source.network.family !== ChainFamily.EVM) {
138
+ throw new Error(`Unsupported network family: ${source.network.family}`)
139
+ } else {
140
+ lane = await (source as EVMChain).getLaneForOnRamp(log.address)
141
+ }
142
+ requests.push({ lane, message, log, tx, timestamp })
143
+ }
144
+ if (!requests.length) {
145
+ throw new Error(`Could not find any CCIPSendRequested message in tx: ${txHash}`)
146
+ }
147
+
148
+ return requests
149
+ }
150
+
151
+ /**
152
+ * Fetch a CCIP message by its messageId
153
+ * Can be slow due to having to paginate backwards through logs
154
+ *
155
+ * @param source - Provider to fetch logs from
156
+ * @param messageId - messageId to search for
157
+ * @param hints - Optional hints for pagination
158
+ * @returns CCIPRequest with given messageId
159
+ **/
160
+ export async function fetchCCIPMessageById(
161
+ source: Chain,
162
+ messageId: string,
163
+ hints?: { page?: number; onRamp?: string },
164
+ ): Promise<CCIPRequest> {
165
+ for await (const log of source.getLogs({
166
+ ...hints,
167
+ ...(hints?.onRamp ? { address: hints.onRamp } : {}),
168
+ topics: ['CCIPSendRequested', 'CCIPMessageSent'],
169
+ })) {
170
+ const message = (source.constructor as ChainStatic).decodeMessage(log)
171
+ if (message?.header.messageId !== messageId) continue
172
+ let destChainSelector, version
173
+ if ('destChainSelector' in message.header) {
174
+ destChainSelector = message.header.destChainSelector
175
+ ;[, version] = await source.typeAndVersion(log.address)
176
+ } else if (source.network.family !== ChainFamily.EVM) {
177
+ throw new Error(`Unsupported network family: ${source.network.family}`)
178
+ } else {
179
+ ;({ destChainSelector, version } = await (source as EVMChain).getLaneForOnRamp(log.address))
180
+ }
181
+ const tx = await source.getTransaction(log.transactionHash)
182
+ return {
183
+ lane: {
184
+ sourceChainSelector: source.network.chainSelector,
185
+ destChainSelector,
186
+ onRamp: log.address,
187
+ version: version as CCIPVersion,
188
+ },
189
+ message,
190
+ log,
191
+ tx,
192
+ timestamp: tx.timestamp,
193
+ }
194
+ }
195
+ throw new Error('Could not find a CCIPSendRequested message with messageId: ' + messageId)
196
+ }
197
+
198
+ // Number of blocks to expand the search window for logs
199
+ const BLOCK_LOG_WINDOW_SIZE = 5000
200
+
201
+ // Helper function to find the sequence number from CCIPSendRequested event logs
202
+ export async function fetchAllMessagesInBatch<R extends Omit<CCIPRequest, 'tx' | 'timestamp'>>(
203
+ source: Chain,
204
+ request: R,
205
+ { minSeqNr, maxSeqNr }: { minSeqNr: bigint; maxSeqNr: bigint },
206
+ { page: eventsBatchSize = BLOCK_LOG_WINDOW_SIZE }: { page?: number } = {},
207
+ ): Promise<R['message'][]> {
208
+ if (minSeqNr === maxSeqNr) return [request.message]
209
+
210
+ const filter: LogFilter = {
211
+ page: eventsBatchSize,
212
+ topics: [request.log.topics[0]],
213
+ address: request.log.address,
214
+ }
215
+ if (request.message.header.sequenceNumber === maxSeqNr) filter.endBlock = request.log.blockNumber
216
+ else
217
+ // start proportionally before send request block, including case when seqNum==min => startBlock
218
+ filter.startBlock =
219
+ request.log.blockNumber -
220
+ Math.ceil(
221
+ (Number(request.message.header.sequenceNumber - minSeqNr) / Number(maxSeqNr - minSeqNr)) *
222
+ eventsBatchSize,
223
+ )
224
+
225
+ const messages: R['message'][] = []
226
+ if (filter.startBlock) {
227
+ // forward
228
+ let backwardsBefore, backwardsEndBlock
229
+ for await (const log of source.getLogs(filter)) {
230
+ backwardsBefore ??= log.transactionHash
231
+ backwardsEndBlock ??= log.blockNumber - 1
232
+ const message = (source.constructor as ChainStatic).decodeMessage(log)
233
+ if (
234
+ !message ||
235
+ ('destChainSelector' in message.header &&
236
+ message.header.destChainSelector !== request.lane.destChainSelector)
237
+ )
238
+ continue
239
+ if (message.header.sequenceNumber < minSeqNr) continue
240
+ messages.push(message)
241
+ if (message.header.sequenceNumber >= maxSeqNr) break
242
+ }
243
+ if (messages.length && messages[0].header.sequenceNumber > minSeqNr) {
244
+ // still work to be done backwards
245
+ delete filter['startBlock']
246
+ filter['endBlock'] = backwardsEndBlock
247
+ filter['endBefore'] = backwardsBefore
248
+ }
249
+ }
250
+ if (filter.endBlock) {
251
+ // backwards
252
+ for await (const log of source.getLogs(filter)) {
253
+ const message = (source.constructor as ChainStatic).decodeMessage(log)
254
+ if (
255
+ !message ||
256
+ ('destChainSelector' in message.header &&
257
+ message.header.destChainSelector !== request.lane.destChainSelector)
258
+ )
259
+ continue
260
+ messages.unshift(message)
261
+ if (message.header.sequenceNumber <= minSeqNr) break
262
+ }
263
+ }
264
+
265
+ if (messages.length != Number(maxSeqNr - minSeqNr) + 1) {
266
+ throw new Error(
267
+ `Could not find all expected request events: from=${request.log.blockNumber}, wanted=[${Number(minSeqNr)}..${Number(maxSeqNr)}:${Number(maxSeqNr - minSeqNr) + 1}], got=[${messages.map((e) => Number(e.header.sequenceNumber)).join(',')}]`,
268
+ )
269
+ }
270
+ return messages
271
+ }
272
+
273
+ export async function* fetchRequestsForSender(
274
+ source: Chain,
275
+ sender: string,
276
+ filter: Pick<LogFilter, 'address' | 'startBlock' | 'startTime' | 'endBlock'>,
277
+ ): AsyncGenerator<Omit<CCIPRequest, 'tx' | 'timestamp'>, void, unknown> {
278
+ const filterWithSender = {
279
+ ...filter,
280
+ sender, // some chain families may use this to look for account lookup/narrow down the search
281
+ topics: ['CCIPSendRequested', 'CCIPMessageSent'],
282
+ }
283
+ for await (const log of source.getLogs(filterWithSender)) {
284
+ const message = (source.constructor as ChainStatic).decodeMessage(log)
285
+ if (message?.sender !== sender) continue
286
+ let destChainSelector, version
287
+ if ('destChainSelector' in message.header) {
288
+ destChainSelector = message.header.destChainSelector
289
+ ;[, version] = await source.typeAndVersion(log.address)
290
+ } else if (source.network.family === ChainFamily.EVM) {
291
+ ;({ destChainSelector, version } = await (source as EVMChain).getLaneForOnRamp(log.address))
292
+ } else {
293
+ throw new Error(`Unsupported network family: ${source.network.family}`)
294
+ }
295
+ yield {
296
+ lane: {
297
+ sourceChainSelector: source.network.chainSelector,
298
+ destChainSelector,
299
+ onRamp: log.address,
300
+ version: version as CCIPVersion,
301
+ },
302
+ message,
303
+ log,
304
+ }
305
+ }
306
+ }
307
+
308
+ /**
309
+ * Map source `token` to `sourcePoolAddress + destTokenAddress`
310
+ * @param source - source chain
311
+ * @param destChainSelector - dest network
312
+ * @param onRamp - contract address
313
+ * @param sourceTokenAmounts - usually `{ token, amount }`
314
+ * @returns - { sourcePoolAddress, destTokenAddress, ...rest } objects
315
+ */
316
+ export async function sourceToDestTokenAmounts<S extends { token: string }>(
317
+ source: Chain,
318
+ destChainSelector: bigint,
319
+ onRamp: string,
320
+ sourceTokenAmounts: readonly S[],
321
+ ): Promise<(Omit<S, 'token'> & { sourcePoolAddress: string; destTokenAddress: string })[]> {
322
+ const tokenAdminRegistry = await source.getTokenAdminRegistryFor(onRamp)
323
+ return Promise.all(
324
+ sourceTokenAmounts.map(async ({ token, ...rest }) => {
325
+ const { tokenPool: sourcePoolAddress } = await source.getRegistryTokenConfig(
326
+ tokenAdminRegistry,
327
+ token,
328
+ )
329
+ if (!sourcePoolAddress)
330
+ throw new Error(`Token=${token} not found in registry=${tokenAdminRegistry}`)
331
+ const remotes = await source.getTokenPoolRemotes(sourcePoolAddress, destChainSelector)
332
+ return {
333
+ ...rest,
334
+ sourcePoolAddress,
335
+ destTokenAddress: remotes[networkInfo(destChainSelector).name].remoteToken,
336
+ }
337
+ }),
338
+ )
339
+ }