@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,272 @@
1
+ import util from 'util';
2
+ import { Program } from '@coral-xyz/anchor';
3
+ import { NATIVE_MINT, createApproveInstruction, getAccount, getAssociatedTokenAddressSync, } from '@solana/spl-token';
4
+ import { ComputeBudgetProgram, PublicKey, TransactionMessage, VersionedTransaction, } from '@solana/web3.js';
5
+ import BN from 'bn.js';
6
+ import { zeroPadValue } from 'ethers';
7
+ import { SolanaChain } from "./index.js";
8
+ import { toLeArray } from "../utils.js";
9
+ import { IDL as CCIP_ROUTER_IDL } from "./idl/1.6.0/CCIP_ROUTER.js";
10
+ import { bytesToBuffer, simulateTransaction, simulationProvider } from "./utils.js";
11
+ function anyToSvmMessage(message) {
12
+ const feeTokenPubkey = message.feeToken ? new PublicKey(message.feeToken) : PublicKey.default;
13
+ const svmMessage = {
14
+ receiver: bytesToBuffer(zeroPadValue(message.receiver, 32)),
15
+ data: bytesToBuffer(message.data || '0x'),
16
+ tokenAmounts: (message.tokenAmounts || []).map((ta) => {
17
+ if (!ta.token || ta.amount < 0n) {
18
+ throw new Error('Invalid token amount: token address and positive amount required');
19
+ }
20
+ return {
21
+ token: new PublicKey(ta.token),
22
+ amount: new BN(ta.amount),
23
+ };
24
+ }),
25
+ feeToken: feeTokenPubkey,
26
+ extraArgs: bytesToBuffer(SolanaChain.encodeExtraArgs(message.extraArgs)),
27
+ };
28
+ return svmMessage;
29
+ }
30
+ export async function getFee(connection, router, destChainSelector, message) {
31
+ const program = new Program(CCIP_ROUTER_IDL, new PublicKey(router), simulationProvider(connection));
32
+ // Get router config to find feeQuoter
33
+ const [configPda] = PublicKey.findProgramAddressSync([Buffer.from('config')], program.programId);
34
+ const configAccount = await connection.getAccountInfo(configPda);
35
+ if (!configAccount)
36
+ throw new Error(`Router config not found at ${configPda.toBase58()}`);
37
+ const { feeQuoter, linkTokenMint } = program.coder.accounts.decode('config', configAccount.data);
38
+ // Derive fee-related PDAs
39
+ const [destChainStatePda] = PublicKey.findProgramAddressSync([Buffer.from('dest_chain_state'), toLeArray(destChainSelector, 8)], program.programId);
40
+ const [feeQuoterConfigPda] = PublicKey.findProgramAddressSync([Buffer.from('config')], feeQuoter);
41
+ const [feeQuoterDestChainPda] = PublicKey.findProgramAddressSync([Buffer.from('dest_chain'), toLeArray(destChainSelector, 8)], feeQuoter);
42
+ if (message.feeToken &&
43
+ message.feeToken !== PublicKey.default.toBase58() &&
44
+ message.feeToken !== linkTokenMint.toBase58()) {
45
+ console.warn('feeToken is not default nor link =', linkTokenMint.toBase58());
46
+ }
47
+ // Convert feeToken to PublicKey (default to native SOL if not specified)
48
+ const feeTokenPubkey = message.feeToken && message.feeToken !== PublicKey.default.toBase58()
49
+ ? new PublicKey(message.feeToken)
50
+ : NATIVE_MINT;
51
+ const [feeQuoterBillingTokenConfigPda] = PublicKey.findProgramAddressSync([Buffer.from('fee_billing_token_config'), feeTokenPubkey.toBuffer()], feeQuoter);
52
+ // LINK token config (assuming default LINK token for now)
53
+ const [feeQuoterLinkTokenConfigPda] = PublicKey.findProgramAddressSync([Buffer.from('fee_billing_token_config'), linkTokenMint.toBuffer()], feeQuoter);
54
+ // Convert AnyMessage to SVM2AnyMessage format
55
+ const svmMessage = anyToSvmMessage(message);
56
+ // 2 feeQuoter PDAs per token
57
+ const remainingAccounts = svmMessage.tokenAmounts
58
+ .map((ta) => [
59
+ PublicKey.findProgramAddressSync([Buffer.from('fee_billing_token_config'), ta.token.toBuffer()], feeQuoter)[0],
60
+ PublicKey.findProgramAddressSync([
61
+ Buffer.from('per_chain_per_token_config'),
62
+ toLeArray(destChainSelector, 8),
63
+ ta.token.toBuffer(),
64
+ ], feeQuoter)[0],
65
+ ])
66
+ .flat()
67
+ .map((pubkey) => ({ pubkey, isWritable: false, isSigner: false }));
68
+ // Call getFee method
69
+ const result = await program.methods
70
+ .getFee(new BN(destChainSelector), svmMessage)
71
+ .accounts({
72
+ config: configPda,
73
+ destChainState: destChainStatePda,
74
+ feeQuoter: feeQuoter,
75
+ feeQuoterConfig: feeQuoterConfigPda,
76
+ feeQuoterDestChain: feeQuoterDestChainPda,
77
+ feeQuoterBillingTokenConfig: feeQuoterBillingTokenConfigPda,
78
+ feeQuoterLinkTokenConfig: feeQuoterLinkTokenConfigPda,
79
+ })
80
+ .remainingAccounts(remainingAccounts)
81
+ .view();
82
+ if (!result?.amount) {
83
+ throw new Error(`Invalid fee result from router: ${util.inspect(result)}`);
84
+ }
85
+ return BigInt(result.amount.toString());
86
+ }
87
+ async function deriveAccountsCcipSend({ router, destChainSelector, message, sender, }) {
88
+ const connection = router.provider.connection;
89
+ const derivedAccounts = [];
90
+ const addressLookupTableAccounts = [];
91
+ const tokenIndices = [];
92
+ let askWith = [];
93
+ let stage = 'Start';
94
+ let tokenIndex = 0;
95
+ const [configPDA] = PublicKey.findProgramAddressSync([Buffer.from('config')], router.programId);
96
+ // read-only copy of router which avoids signing every simulation
97
+ const roProgram = new Program(router.idl, router.programId, simulationProvider(connection, sender));
98
+ do {
99
+ // Create the transaction instruction for the deriveAccountsCcipSend method
100
+ const response = (await roProgram.methods
101
+ .deriveAccountsCcipSend({
102
+ destChainSelector: new BN(destChainSelector.toString()),
103
+ ccipSendCaller: sender,
104
+ message,
105
+ }, stage)
106
+ .accounts({
107
+ config: configPDA,
108
+ })
109
+ .remainingAccounts(askWith)
110
+ .view());
111
+ // Check if it is the start of a token transfer
112
+ const isStartOfToken = /^TokenTransferStaticAccounts\/\d+\/0$/.test(response.currentStage);
113
+ if (isStartOfToken) {
114
+ // From CCIP_ROUTER IDL, ccipSend has 18 static accounts before remaining_accounts
115
+ const numStaticCcipSendAccounts = 18;
116
+ tokenIndices.push(tokenIndex - numStaticCcipSendAccounts);
117
+ }
118
+ // Update token index
119
+ tokenIndex += response.accountsToSave.length;
120
+ // Collect the derived accounts
121
+ for (const meta of response.accountsToSave) {
122
+ derivedAccounts.push({
123
+ pubkey: meta.pubkey,
124
+ isWritable: meta.isWritable,
125
+ isSigner: meta.isSigner,
126
+ });
127
+ }
128
+ // Prepare askWith for next iteration
129
+ askWith = response.askAgainWith.map((meta) => ({
130
+ pubkey: meta.pubkey,
131
+ isWritable: meta.isWritable,
132
+ isSigner: meta.isSigner,
133
+ }));
134
+ const lookupTableAccounts = await Promise.all(response.lookUpTablesToSave.map(async (table) => {
135
+ const lookupTableAccountInfo = await connection.getAddressLookupTable(table);
136
+ if (!lookupTableAccountInfo.value) {
137
+ throw new Error(`Lookup table account not found: ${table.toBase58()}`);
138
+ }
139
+ return lookupTableAccountInfo.value;
140
+ }));
141
+ // Collect lookup tables
142
+ addressLookupTableAccounts.push(...lookupTableAccounts);
143
+ stage = response.nextStage;
144
+ } while (stage?.length);
145
+ return {
146
+ accounts: derivedAccounts,
147
+ addressLookupTableAccounts,
148
+ tokenIndexes: Buffer.from(tokenIndices),
149
+ };
150
+ }
151
+ export async function simulateAndSendTxs(connection, feePayer, instructions, addressLookupTableAccounts) {
152
+ let computeUnitLimit;
153
+ const simulated = (await simulateTransaction({
154
+ connection,
155
+ payerKey: feePayer.publicKey,
156
+ instructions,
157
+ addressLookupTableAccounts,
158
+ })).unitsConsumed || 0;
159
+ if (simulated > 200000)
160
+ computeUnitLimit = Math.ceil(simulated * 1.1);
161
+ const txMsg = new TransactionMessage({
162
+ payerKey: feePayer.publicKey,
163
+ recentBlockhash: (await connection.getLatestBlockhash('confirmed')).blockhash,
164
+ instructions: [
165
+ ...(computeUnitLimit
166
+ ? [ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnitLimit })]
167
+ : []),
168
+ ...instructions,
169
+ ],
170
+ });
171
+ const messageV0 = txMsg.compileToV0Message(addressLookupTableAccounts);
172
+ const tx = new VersionedTransaction(messageV0);
173
+ const signed = await feePayer.signTransaction(tx);
174
+ let hash;
175
+ for (let attempt = 0;; attempt++) {
176
+ try {
177
+ hash = await connection.sendTransaction(signed);
178
+ await connection.confirmTransaction(hash, 'confirmed');
179
+ return hash;
180
+ }
181
+ catch (error) {
182
+ if (attempt >= 3)
183
+ throw error;
184
+ console.error(`sendTransaction failed attempt=${attempt + 1}/3:`, error);
185
+ }
186
+ }
187
+ }
188
+ export async function ccipSend(router, destChainSelector, message, opts) {
189
+ const connection = router.provider.connection;
190
+ let wallet;
191
+ if (!(wallet = router.provider.wallet)) {
192
+ throw new Error('ccipSend called without signer wallet');
193
+ }
194
+ const amountsToApprove = (message.tokenAmounts ?? []).reduce((acc, { token, amount }) => ({ ...acc, [token]: (acc[token] ?? 0n) + amount }), {});
195
+ if (message.feeToken && message.feeToken !== PublicKey.default.toBase58()) {
196
+ amountsToApprove[message.feeToken] = (amountsToApprove[message.feeToken] ?? 0n) + message.fee;
197
+ }
198
+ const approveIxs = [];
199
+ for (const [token, amount] of Object.entries(amountsToApprove)) {
200
+ const approveIx = await approveRouterSpender(connection, wallet.publicKey, new PublicKey(token), router.programId, opts?.approveMax ? undefined : amount);
201
+ if (approveIx)
202
+ approveIxs.push(approveIx);
203
+ }
204
+ const svmMessage = anyToSvmMessage(message);
205
+ const { addressLookupTableAccounts, accounts, tokenIndexes } = await deriveAccountsCcipSend({
206
+ router,
207
+ destChainSelector,
208
+ sender: wallet.publicKey,
209
+ message: svmMessage,
210
+ });
211
+ const sendIx = await router.methods
212
+ .ccipSend(new BN(destChainSelector), svmMessage, tokenIndexes)
213
+ .accountsStrict({
214
+ config: accounts[0].pubkey,
215
+ destChainState: accounts[1].pubkey,
216
+ nonce: accounts[2].pubkey,
217
+ authority: accounts[3].pubkey,
218
+ systemProgram: accounts[4].pubkey,
219
+ feeTokenProgram: accounts[5].pubkey,
220
+ feeTokenMint: accounts[6].pubkey,
221
+ feeTokenUserAssociatedAccount: accounts[7].pubkey,
222
+ feeTokenReceiver: accounts[8].pubkey,
223
+ feeBillingSigner: accounts[9].pubkey,
224
+ feeQuoter: accounts[10].pubkey,
225
+ feeQuoterConfig: accounts[11].pubkey,
226
+ feeQuoterDestChain: accounts[12].pubkey,
227
+ feeQuoterBillingTokenConfig: accounts[13].pubkey,
228
+ feeQuoterLinkTokenConfig: accounts[14].pubkey,
229
+ rmnRemote: accounts[15].pubkey,
230
+ rmnRemoteCurses: accounts[16].pubkey,
231
+ rmnRemoteConfig: accounts[17].pubkey,
232
+ })
233
+ .remainingAccounts(accounts.slice(18))
234
+ .instruction();
235
+ let hash;
236
+ try {
237
+ // first try to serialize and send a single tx containing approve and send ixs
238
+ hash = await simulateAndSendTxs(connection, wallet, [...approveIxs, sendIx], addressLookupTableAccounts);
239
+ }
240
+ catch (err) {
241
+ if (!approveIxs.length ||
242
+ !(err instanceof Error) ||
243
+ !['encoding overruns Uint8Array', 'too large'].some((e) => err.message.includes(e)))
244
+ throw err;
245
+ // if serialization fails, send approve txs separately
246
+ for (const approveIx of approveIxs)
247
+ await simulateAndSendTxs(connection, wallet, [approveIx]);
248
+ hash = await simulateAndSendTxs(connection, wallet, [sendIx], addressLookupTableAccounts);
249
+ }
250
+ return { hash };
251
+ }
252
+ async function approveRouterSpender(connection, owner, token, router, amount) {
253
+ // Get the current account info to check existing delegation (or create if needed)
254
+ const mintInfo = await connection.getAccountInfo(token);
255
+ if (!mintInfo)
256
+ throw new Error(`Mint ${token.toBase58()} not found`);
257
+ const associatedTokenAccount = getAssociatedTokenAddressSync(token, owner, undefined, mintInfo.owner);
258
+ const accountInfo = await getAccount(connection, associatedTokenAccount, undefined, mintInfo.owner);
259
+ // spender is a Router PDA
260
+ const [spender] = PublicKey.findProgramAddressSync([Buffer.from('fee_billing_signer')], router);
261
+ // Check if we need to approve
262
+ const needsApproval = !accountInfo.delegate ||
263
+ !accountInfo.delegate.equals(spender) ||
264
+ (amount != null && accountInfo.delegatedAmount < amount);
265
+ if (!needsApproval)
266
+ return;
267
+ // Approve the spender to use tokens from the user's account
268
+ const approveIx = createApproveInstruction(accountInfo.address, spender, owner, amount ?? BigInt(Number.MAX_SAFE_INTEGER), undefined, mintInfo.owner);
269
+ console.info('Approving', amount ?? BigInt(Number.MAX_SAFE_INTEGER), 'of', token.toBase58(), 'tokens to router', router.toBase58());
270
+ return approveIx;
271
+ }
272
+ //# sourceMappingURL=send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/solana/send.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { SVMExtraArgsV1 } from '../extra-args.ts';
2
+ import type { CCIPMessage_V1_6 } from '../types.ts';
3
+ export type CCIPMessage_V1_6_Solana = CCIPMessage_V1_6 & SVMExtraArgsV1;
4
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/solana/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAInD,MAAM,MAAM,uBAAuB,GAAG,gBAAgB,GAAG,cAAc,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/solana/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,58 @@
1
+ import { type AddressLookupTableAccount, type Connection, type Signer, type Transaction, type TransactionInstruction, PublicKey, VersionedTransaction } from '@solana/web3.js';
2
+ import { type BytesLike } from 'ethers';
3
+ import type { Log_ } from '../types.ts';
4
+ export declare function bytesToBuffer(bytes: BytesLike): Buffer;
5
+ export declare function waitForFinalization(connection: Connection, signature: string, intervalMs?: number, maxAttempts?: number): Promise<void>;
6
+ export declare function camelToSnakeCase(str: string): string;
7
+ type ParsedLog = Pick<Log_, 'topics' | 'index' | 'address' | 'data'> & {
8
+ data: string;
9
+ };
10
+ /**
11
+ * Utility function to parse Solana logs with proper address and topic extraction.
12
+ *
13
+ * Solana logs are structured as a stack-based execution trace:
14
+ * - "Program <address> invoke [<depth>]" - Program call starts
15
+ * - "Program log: <data>" - Program emitted a log message
16
+ * - "Program data: <base64>" - Program emitted structured data (Anchor events)
17
+ * - "Program <address> success/failed" - Program call ends
18
+ *
19
+ * This function:
20
+ * 1. Tracks the program call stack to determine which program emitted each log
21
+ * 2. Extracts the first 8 bytes from base64 "Program data:" logs as topics (event discriminants)
22
+ * 3. Converts logs to EVM-compatible Log_ format for CCIP compatibility
23
+ * 4. Returns ALL logs from the transaction - filtering should be done by the caller
24
+ *
25
+ * @param logs - Array of logMessages from Solana transaction
26
+ * @returns Array of parsed log objects from all programs in the transaction
27
+ */
28
+ export declare function parseSolanaLogs(logs: readonly string[]): ParsedLog[];
29
+ export declare function getErrorFromLogs(logs_: readonly string[] | readonly Pick<Log_, 'address' | 'index' | 'data' | 'topics'>[] | null): {
30
+ program: string;
31
+ [k: string]: string;
32
+ } | undefined;
33
+ export declare function simulateTransaction({ connection, payerKey, computeUnitsOverride, ...rest }: {
34
+ connection: Connection;
35
+ payerKey: PublicKey;
36
+ computeUnitsOverride?: number;
37
+ addressLookupTableAccounts?: AddressLookupTableAccount[];
38
+ } & ({
39
+ instructions: TransactionInstruction[];
40
+ } | {
41
+ tx: Transaction | VersionedTransaction;
42
+ })): Promise<import("@solana/web3.js").SimulatedTransactionResponse>;
43
+ /**
44
+ * Used as `provider` in anchor's `Program` constructor, to support `.view()` simulations
45
+ * without * requiring a full AnchorProvider with wallet
46
+ * @param connection - Connection to the Solana network
47
+ * @param feePayer - Fee payer for the simulated transaction
48
+ * @returns Value returned by the simulated method
49
+ */
50
+ export declare function simulationProvider(connection: Connection, feePayer?: PublicKey): {
51
+ connection: Connection;
52
+ wallet: {
53
+ publicKey: PublicKey;
54
+ };
55
+ simulate: (tx: Transaction | VersionedTransaction, _signers?: Signer[]) => Promise<import("@solana/web3.js").SimulatedTransactionResponse>;
56
+ };
57
+ export {};
58
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/solana/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,UAAU,EACf,KAAK,MAAM,EAEX,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAE3B,SAAS,EAGT,oBAAoB,EACrB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,KAAK,SAAS,EAAkC,MAAM,QAAQ,CAAA;AAEvE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAGvC,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAEtD;AAED,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,UAAU,SAAM,EAChB,WAAW,SAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAWpD;AAED,KAAK,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAAE,CAwCpE;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,IAAI,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC,EAAE,GAAG,IAAI,GAC/F;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,SAAS,CA0DtD;AAED,wBAAsB,mBAAmB,CAAC,EACxC,UAAU,EACV,QAAQ,EACR,oBAAoB,EACpB,GAAG,IAAI,EACR,EAAE;IACD,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,SAAS,CAAA;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,0BAA0B,CAAC,EAAE,yBAAyB,EAAE,CAAA;CACzD,GAAG,CAAC;IAAE,YAAY,EAAE,sBAAsB,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,WAAW,GAAG,oBAAoB,CAAA;CAAE,CAAC,mEA0D5F;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,UAAU,EACtB,QAAQ,GAAE,SAA6D;;;;;mBAOhD,WAAW,GAAG,oBAAoB,aAAa,MAAM,EAAE;EAO/E"}
@@ -0,0 +1,211 @@
1
+ import { ComputeBudgetProgram, PublicKey, SendTransactionError, TransactionMessage, VersionedTransaction, } from '@solana/web3.js';
2
+ import { dataLength, dataSlice, hexlify } from 'ethers';
3
+ import { getDataBytes, sleep } from "../utils.js";
4
+ export function bytesToBuffer(bytes) {
5
+ return Buffer.from(getDataBytes(bytes).buffer);
6
+ }
7
+ export async function waitForFinalization(connection, signature, intervalMs = 500, maxAttempts = 500) {
8
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
9
+ const status = await connection.getSignatureStatuses([signature]);
10
+ const info = status.value[0];
11
+ if (info?.confirmationStatus === 'finalized') {
12
+ return;
13
+ }
14
+ await sleep(intervalMs);
15
+ }
16
+ throw new Error(`Transaction ${signature} not finalized after timeout`);
17
+ }
18
+ export function camelToSnakeCase(str) {
19
+ return str
20
+ .replace(/([A-Z]+)([A-Z][a-z]|$)/g, (_, p1, p2) => {
21
+ if (p2) {
22
+ return `_${p1.slice(0, -1).toLowerCase()}_${p2.toLowerCase()}`;
23
+ }
24
+ return `_${p1.toLowerCase()}`;
25
+ })
26
+ .replace(/([a-z])([A-Z])/g, '$1_$2')
27
+ .toLowerCase()
28
+ .replace(/^_/, '');
29
+ }
30
+ /**
31
+ * Utility function to parse Solana logs with proper address and topic extraction.
32
+ *
33
+ * Solana logs are structured as a stack-based execution trace:
34
+ * - "Program <address> invoke [<depth>]" - Program call starts
35
+ * - "Program log: <data>" - Program emitted a log message
36
+ * - "Program data: <base64>" - Program emitted structured data (Anchor events)
37
+ * - "Program <address> success/failed" - Program call ends
38
+ *
39
+ * This function:
40
+ * 1. Tracks the program call stack to determine which program emitted each log
41
+ * 2. Extracts the first 8 bytes from base64 "Program data:" logs as topics (event discriminants)
42
+ * 3. Converts logs to EVM-compatible Log_ format for CCIP compatibility
43
+ * 4. Returns ALL logs from the transaction - filtering should be done by the caller
44
+ *
45
+ * @param logs - Array of logMessages from Solana transaction
46
+ * @returns Array of parsed log objects from all programs in the transaction
47
+ */
48
+ export function parseSolanaLogs(logs) {
49
+ const results = [];
50
+ const programStack = [];
51
+ for (const [i, log] of logs.entries()) {
52
+ // Track program calls and returns to maintain the address stack
53
+ let match;
54
+ if ((match = log.match(/^Program (\w+) invoke\b/))) {
55
+ programStack.push(match[1]);
56
+ }
57
+ else if ((match = log.match(/^Program (\w+) (success|failed)\b/))) {
58
+ // Pop from stack when program returns
59
+ programStack.pop();
60
+ }
61
+ else if ((match = log.match(/^Program (log|data): /))) {
62
+ // Extract the actual log data
63
+ const logData = log.slice(match[0].length);
64
+ const currentProgram = programStack[programStack.length - 1];
65
+ let topics = [];
66
+ if (log.startsWith('Program data: ')) {
67
+ try {
68
+ // Try to decode base64 and extract first 8 bytes as topic/discriminant
69
+ const buffer = getDataBytes(logData);
70
+ if (dataLength(buffer) >= 8) {
71
+ topics = [dataSlice(buffer, 0, 8)];
72
+ }
73
+ }
74
+ catch {
75
+ // If base64 decoding fails, leave topics empty
76
+ }
77
+ }
78
+ // For regular log messages, use the current program on stack
79
+ results.push({
80
+ topics,
81
+ index: i,
82
+ address: currentProgram,
83
+ data: logData,
84
+ });
85
+ }
86
+ }
87
+ return results;
88
+ }
89
+ export function getErrorFromLogs(logs_) {
90
+ if (!logs_?.length)
91
+ return;
92
+ let logs;
93
+ if (logs_.every((l) => typeof l === 'string'))
94
+ logs = parseSolanaLogs(logs_);
95
+ else
96
+ logs = logs_;
97
+ const lastLog = logs[logs.length - 1];
98
+ // collect all logs from the last program execution (the one which failed)
99
+ const lastProgramLogs = logs
100
+ .reduceRight((acc, l) =>
101
+ // if acc is empty (i.e. on last log), or it is emitted by the same program and not a Program data:
102
+ !acc.length || (l.address === acc[0].address && !l.topics?.length) ? [l, ...acc] : acc, [])
103
+ .map(({ data }) => data)
104
+ .reduceRight((acc, l) => l.endsWith(':') && acc.length
105
+ ? [`${l} ${acc[0]}`, ...acc.slice(1)]
106
+ : l.split(': ').length > 1 && l.split('. ').length > 1
107
+ ? [...l.replace(/\.$/, '').split('. '), ...acc]
108
+ : [l, ...acc], []) // cosmetic: join lines ending in ':' with next
109
+ .map((l) => {
110
+ try {
111
+ // convert number[]s (common in solana logs) into slightly more readable 0x-bytearrays
112
+ return l.replace(/\[(\d{1,3}, ){3,}\d+\]/g, (m) => hexlify(new Uint8Array(m
113
+ .substring(1, m.length - 1)
114
+ .split(', ')
115
+ .map((x) => +x))));
116
+ }
117
+ catch (_) {
118
+ return l;
119
+ }
120
+ });
121
+ if (lastProgramLogs.every((l) => l.indexOf(': ') >= 0)) {
122
+ return {
123
+ program: lastLog.address,
124
+ ...Object.fromEntries(lastProgramLogs.map((l) => [
125
+ l.substring(0, l.indexOf(': ')),
126
+ l.substring(l.indexOf(': ') + 2),
127
+ ])),
128
+ };
129
+ }
130
+ else {
131
+ return {
132
+ program: lastLog.address,
133
+ error: lastProgramLogs.join('\n'),
134
+ };
135
+ }
136
+ }
137
+ export async function simulateTransaction({ connection, payerKey, computeUnitsOverride, ...rest }) {
138
+ // Add max compute units for simulation
139
+ const maxComputeUnits = 1_400_000;
140
+ const recentBlockhash = '11111111111111111111111111111112';
141
+ const computeBudgetIx = ComputeBudgetProgram.setComputeUnitLimit({
142
+ units: computeUnitsOverride || maxComputeUnits,
143
+ });
144
+ let tx;
145
+ if (!('tx' in rest)) {
146
+ // Create message with compute budget instruction
147
+ const message = new TransactionMessage({
148
+ payerKey,
149
+ recentBlockhash,
150
+ instructions: [computeBudgetIx, ...rest.instructions],
151
+ });
152
+ const messageV0 = message.compileToV0Message(rest.addressLookupTableAccounts);
153
+ tx = new VersionedTransaction(messageV0);
154
+ }
155
+ else if (!('version' in rest.tx)) {
156
+ // Create message with compute budget instruction
157
+ const message = new TransactionMessage({
158
+ payerKey,
159
+ recentBlockhash,
160
+ instructions: [computeBudgetIx, ...rest.tx.instructions],
161
+ });
162
+ const messageV0 = message.compileToV0Message(rest.addressLookupTableAccounts);
163
+ tx = new VersionedTransaction(messageV0);
164
+ }
165
+ else {
166
+ tx = rest.tx;
167
+ }
168
+ const config = {
169
+ commitment: 'confirmed',
170
+ replaceRecentBlockhash: true,
171
+ sigVerify: false,
172
+ };
173
+ const result = await connection.simulateTransaction(tx, config);
174
+ if (result.value.err) {
175
+ console.debug('Simulation results:', {
176
+ logs: result.value.logs,
177
+ unitsConsumed: result.value.unitsConsumed,
178
+ returnData: result.value.returnData,
179
+ err: result.value.err,
180
+ });
181
+ // same error sendTransaction sends, to be catched up
182
+ throw new SendTransactionError({
183
+ action: 'simulate',
184
+ signature: '',
185
+ transactionMessage: JSON.stringify(result.value.err),
186
+ logs: result.value.logs,
187
+ });
188
+ }
189
+ return result.value;
190
+ }
191
+ /**
192
+ * Used as `provider` in anchor's `Program` constructor, to support `.view()` simulations
193
+ * without * requiring a full AnchorProvider with wallet
194
+ * @param connection - Connection to the Solana network
195
+ * @param feePayer - Fee payer for the simulated transaction
196
+ * @returns Value returned by the simulated method
197
+ */
198
+ export function simulationProvider(connection, feePayer = new PublicKey('11111111111111111111111111111112')) {
199
+ return {
200
+ connection,
201
+ wallet: {
202
+ publicKey: feePayer,
203
+ },
204
+ simulate: async (tx, _signers) => simulateTransaction({
205
+ connection,
206
+ payerKey: feePayer,
207
+ tx,
208
+ }),
209
+ };
210
+ }
211
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/solana/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type LeafHasher } from '../hasher/common.ts';
2
+ import { type CCIPMessage_V1_6, CCIPVersion } from '../types.ts';
3
+ import type { CCIPMessage_V1_6_Sui } from './types.ts';
4
+ export declare function getSuiLeafHasher<V extends CCIPVersion = CCIPVersion>({ sourceChainSelector, destChainSelector, onRamp, version, }: {
5
+ sourceChainSelector: bigint;
6
+ destChainSelector: bigint;
7
+ onRamp: string;
8
+ version: V;
9
+ }): LeafHasher<V>;
10
+ export declare function hashV16SuiMessage(message: CCIPMessage_V1_6 | CCIPMessage_V1_6_Sui, metadataHash: string): string;
11
+ export declare const hashSuiMetadata: (sourceChainSelector: bigint, destChainSelector: bigint, onRamp: string) => string;
12
+ //# sourceMappingURL=hasher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasher.d.ts","sourceRoot":"","sources":["../../src/sui/hasher.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAAyB,MAAM,qBAAqB,CAAA;AAC5E,OAAO,EAAoB,KAAK,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAClF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAEtD,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAAE,EACpE,mBAAmB,EACnB,iBAAiB,EACjB,MAAM,EACN,OAAO,GACR,EAAE;IACD,mBAAmB,EAAE,MAAM,CAAA;IAC3B,iBAAiB,EAAE,MAAM,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,CAAC,CAAA;CACX,GAAG,UAAU,CAAC,CAAC,CAAC,CAUhB;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,gBAAgB,GAAG,oBAAoB,EAChD,YAAY,EAAE,MAAM,GACnB,MAAM,CA2CR;AAED,eAAO,MAAM,eAAe,GAC1B,qBAAqB,MAAM,EAC3B,mBAAmB,MAAM,EACzB,QAAQ,MAAM,KACb,MAOF,CAAA"}