@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.
- package/LICENSE +21 -0
- package/README.md +109 -0
- package/dist/aptos/exec.d.ts +18 -0
- package/dist/aptos/exec.d.ts.map +1 -0
- package/dist/aptos/exec.js +55 -0
- package/dist/aptos/exec.js.map +1 -0
- package/dist/aptos/hasher.d.ts +11 -0
- package/dist/aptos/hasher.d.ts.map +1 -0
- package/dist/aptos/hasher.js +62 -0
- package/dist/aptos/hasher.js.map +1 -0
- package/dist/aptos/index.d.ts +92 -0
- package/dist/aptos/index.d.ts.map +1 -0
- package/dist/aptos/index.js +482 -0
- package/dist/aptos/index.js.map +1 -0
- package/dist/aptos/logs.d.ts +9 -0
- package/dist/aptos/logs.d.ts.map +1 -0
- package/dist/aptos/logs.js +167 -0
- package/dist/aptos/logs.js.map +1 -0
- package/dist/aptos/send.d.ts +11 -0
- package/dist/aptos/send.d.ts.map +1 -0
- package/dist/aptos/send.js +78 -0
- package/dist/aptos/send.js.map +1 -0
- package/dist/aptos/token.d.ts +4 -0
- package/dist/aptos/token.d.ts.map +1 -0
- package/dist/aptos/token.js +134 -0
- package/dist/aptos/token.js.map +1 -0
- package/dist/aptos/types.d.ts +78 -0
- package/dist/aptos/types.d.ts.map +1 -0
- package/dist/aptos/types.js +60 -0
- package/dist/aptos/types.js.map +1 -0
- package/dist/aptos/utils.d.ts +12 -0
- package/dist/aptos/utils.d.ts.map +1 -0
- package/dist/aptos/utils.js +15 -0
- package/dist/aptos/utils.js.map +1 -0
- package/dist/chain.d.ts +344 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +41 -0
- package/dist/chain.js.map +1 -0
- package/dist/commits.d.ts +25 -0
- package/dist/commits.d.ts.map +1 -0
- package/dist/commits.js +29 -0
- package/dist/commits.js.map +1 -0
- package/dist/evm/abi/BurnMintERC677Token.d.ts +602 -0
- package/dist/evm/abi/BurnMintERC677Token.d.ts.map +1 -0
- package/dist/evm/abi/BurnMintERC677Token.js +488 -0
- package/dist/evm/abi/BurnMintERC677Token.js.map +1 -0
- package/dist/evm/abi/CommitStore_1_2.d.ts +688 -0
- package/dist/evm/abi/CommitStore_1_2.d.ts.map +1 -0
- package/dist/evm/abi/CommitStore_1_2.js +638 -0
- package/dist/evm/abi/CommitStore_1_2.js.map +1 -0
- package/dist/evm/abi/CommitStore_1_5.d.ts +708 -0
- package/dist/evm/abi/CommitStore_1_5.d.ts.map +1 -0
- package/dist/evm/abi/CommitStore_1_5.js +675 -0
- package/dist/evm/abi/CommitStore_1_5.js.map +1 -0
- package/dist/evm/abi/FeeQuoter_1_6.d.ts +1770 -0
- package/dist/evm/abi/FeeQuoter_1_6.d.ts.map +1 -0
- package/dist/evm/abi/FeeQuoter_1_6.js +1904 -0
- package/dist/evm/abi/FeeQuoter_1_6.js.map +1 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5.d.ts +1116 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5.d.ts.map +1 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5.js +1096 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5.js.map +1 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5_1.d.ts +1306 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5_1.d.ts.map +1 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5_1.js +1278 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_5_1.js.map +1 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_6_1.d.ts +1290 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_6_1.d.ts.map +1 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_6_1.js +1288 -0
- package/dist/evm/abi/LockReleaseTokenPool_1_6_1.js.map +1 -0
- package/dist/evm/abi/OffRamp_1_2.d.ts +1217 -0
- package/dist/evm/abi/OffRamp_1_2.d.ts.map +1 -0
- package/dist/evm/abi/OffRamp_1_2.js +1204 -0
- package/dist/evm/abi/OffRamp_1_2.js.map +1 -0
- package/dist/evm/abi/OffRamp_1_5.d.ts +1271 -0
- package/dist/evm/abi/OffRamp_1_5.d.ts.map +1 -0
- package/dist/evm/abi/OffRamp_1_5.js +1273 -0
- package/dist/evm/abi/OffRamp_1_5.js.map +1 -0
- package/dist/evm/abi/OffRamp_1_6.d.ts +1472 -0
- package/dist/evm/abi/OffRamp_1_6.d.ts.map +1 -0
- package/dist/evm/abi/OffRamp_1_6.js +1529 -0
- package/dist/evm/abi/OffRamp_1_6.js.map +1 -0
- package/dist/evm/abi/OnRamp_1_2.d.ts +1391 -0
- package/dist/evm/abi/OnRamp_1_2.d.ts.map +1 -0
- package/dist/evm/abi/OnRamp_1_2.js +1343 -0
- package/dist/evm/abi/OnRamp_1_2.js.map +1 -0
- package/dist/evm/abi/OnRamp_1_5.d.ts +1443 -0
- package/dist/evm/abi/OnRamp_1_5.d.ts.map +1 -0
- package/dist/evm/abi/OnRamp_1_5.js +1427 -0
- package/dist/evm/abi/OnRamp_1_5.js.map +1 -0
- package/dist/evm/abi/OnRamp_1_6.d.ts +796 -0
- package/dist/evm/abi/OnRamp_1_6.d.ts.map +1 -0
- package/dist/evm/abi/OnRamp_1_6.js +880 -0
- package/dist/evm/abi/OnRamp_1_6.js.map +1 -0
- package/dist/evm/abi/Router.d.ts +541 -0
- package/dist/evm/abi/Router.d.ts.map +1 -0
- package/dist/evm/abi/Router.js +508 -0
- package/dist/evm/abi/Router.js.map +1 -0
- package/dist/evm/abi/TokenAdminRegistry_1_5.d.ts +373 -0
- package/dist/evm/abi/TokenAdminRegistry_1_5.d.ts.map +1 -0
- package/dist/evm/abi/TokenAdminRegistry_1_5.js +333 -0
- package/dist/evm/abi/TokenAdminRegistry_1_5.js.map +1 -0
- package/dist/evm/const.d.ts +27 -0
- package/dist/evm/const.d.ts.map +1 -0
- package/dist/evm/const.js +63 -0
- package/dist/evm/const.js.map +1 -0
- package/dist/evm/errors.d.ts +36 -0
- package/dist/evm/errors.d.ts.map +1 -0
- package/dist/evm/errors.js +192 -0
- package/dist/evm/errors.js.map +1 -0
- package/dist/evm/hasher.d.ts +5 -0
- package/dist/evm/hasher.d.ts.map +1 -0
- package/dist/evm/hasher.js +116 -0
- package/dist/evm/hasher.js.map +1 -0
- package/dist/evm/index.d.ts +121 -0
- package/dist/evm/index.d.ts.map +1 -0
- package/dist/evm/index.js +904 -0
- package/dist/evm/index.js.map +1 -0
- package/dist/evm/messages.d.ts +35 -0
- package/dist/evm/messages.d.ts.map +1 -0
- package/dist/evm/messages.js +11 -0
- package/dist/evm/messages.js.map +1 -0
- package/dist/evm/offchain.d.ts +16 -0
- package/dist/evm/offchain.d.ts.map +1 -0
- package/dist/evm/offchain.js +142 -0
- package/dist/evm/offchain.js.map +1 -0
- package/dist/execution.d.ts +80 -0
- package/dist/execution.d.ts.map +1 -0
- package/dist/execution.js +91 -0
- package/dist/execution.js.map +1 -0
- package/dist/extra-args.d.ts +45 -0
- package/dist/extra-args.d.ts.map +1 -0
- package/dist/extra-args.js +44 -0
- package/dist/extra-args.js.map +1 -0
- package/dist/gas.d.ts +27 -0
- package/dist/gas.d.ts.map +1 -0
- package/dist/gas.js +80 -0
- package/dist/gas.js.map +1 -0
- package/dist/hasher/common.d.ts +12 -0
- package/dist/hasher/common.d.ts.map +1 -0
- package/dist/hasher/common.js +19 -0
- package/dist/hasher/common.js.map +1 -0
- package/dist/hasher/hasher.d.ts +4 -0
- package/dist/hasher/hasher.d.ts.map +1 -0
- package/dist/hasher/hasher.js +11 -0
- package/dist/hasher/hasher.js.map +1 -0
- package/dist/hasher/index.d.ts +4 -0
- package/dist/hasher/index.d.ts.map +1 -0
- package/dist/hasher/index.js +4 -0
- package/dist/hasher/index.js.map +1 -0
- package/dist/hasher/merklemulti.d.ts +58 -0
- package/dist/hasher/merklemulti.d.ts.map +1 -0
- package/dist/hasher/merklemulti.js +257 -0
- package/dist/hasher/merklemulti.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/offchain.d.ts +20 -0
- package/dist/offchain.d.ts.map +1 -0
- package/dist/offchain.js +59 -0
- package/dist/offchain.js.map +1 -0
- package/dist/requests.d.ts +48 -0
- package/dist/requests.d.ts.map +1 -0
- package/dist/requests.js +286 -0
- package/dist/requests.js.map +1 -0
- package/dist/selectors.d.ts +9 -0
- package/dist/selectors.d.ts.map +1 -0
- package/dist/selectors.js +1330 -0
- package/dist/selectors.js.map +1 -0
- package/dist/solana/cleanup.d.ts +15 -0
- package/dist/solana/cleanup.d.ts.map +1 -0
- package/dist/solana/cleanup.js +159 -0
- package/dist/solana/cleanup.js.map +1 -0
- package/dist/solana/exec.d.ts +15 -0
- package/dist/solana/exec.d.ts.map +1 -0
- package/dist/solana/exec.js +417 -0
- package/dist/solana/exec.js.map +1 -0
- package/dist/solana/hasher.d.ts +4 -0
- package/dist/solana/hasher.d.ts.map +1 -0
- package/dist/solana/hasher.js +81 -0
- package/dist/solana/hasher.js.map +1 -0
- package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.d.ts +866 -0
- package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.js +866 -0
- package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.js.map +1 -0
- package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.d.ts +949 -0
- package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.js +949 -0
- package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.js.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.d.ts +1374 -0
- package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.js +1374 -0
- package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.js.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_COMMON.d.ts +104 -0
- package/dist/solana/idl/1.6.0/CCIP_COMMON.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_COMMON.js +104 -0
- package/dist/solana/idl/1.6.0/CCIP_COMMON.js.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.d.ts +2746 -0
- package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.js +2746 -0
- package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.js.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_ROUTER.d.ts +2332 -0
- package/dist/solana/idl/1.6.0/CCIP_ROUTER.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/CCIP_ROUTER.js +2332 -0
- package/dist/solana/idl/1.6.0/CCIP_ROUTER.js.map +1 -0
- package/dist/solana/index.d.ts +205 -0
- package/dist/solana/index.d.ts.map +1 -0
- package/dist/solana/index.js +1085 -0
- package/dist/solana/index.js.map +1 -0
- package/dist/solana/offchain.d.ts +31 -0
- package/dist/solana/offchain.d.ts.map +1 -0
- package/dist/solana/offchain.js +152 -0
- package/dist/solana/offchain.js.map +1 -0
- package/dist/solana/patchBorsh.d.ts +2 -0
- package/dist/solana/patchBorsh.d.ts.map +1 -0
- package/dist/solana/patchBorsh.js +60 -0
- package/dist/solana/patchBorsh.js.map +1 -0
- package/dist/solana/send.d.ts +14 -0
- package/dist/solana/send.d.ts.map +1 -0
- package/dist/solana/send.js +272 -0
- package/dist/solana/send.js.map +1 -0
- package/dist/solana/types.d.ts +4 -0
- package/dist/solana/types.d.ts.map +1 -0
- package/dist/solana/types.js +2 -0
- package/dist/solana/types.js.map +1 -0
- package/dist/solana/utils.d.ts +58 -0
- package/dist/solana/utils.d.ts.map +1 -0
- package/dist/solana/utils.js +211 -0
- package/dist/solana/utils.js.map +1 -0
- package/dist/sui/hasher.d.ts +12 -0
- package/dist/sui/hasher.d.ts.map +1 -0
- package/dist/sui/hasher.js +63 -0
- package/dist/sui/hasher.js.map +1 -0
- package/dist/sui/index.d.ts +72 -0
- package/dist/sui/index.d.ts.map +1 -0
- package/dist/sui/index.js +128 -0
- package/dist/sui/index.js.map +1 -0
- package/dist/sui/types.d.ts +17 -0
- package/dist/sui/types.d.ts.map +1 -0
- package/dist/sui/types.js +17 -0
- package/dist/sui/types.js.map +1 -0
- package/dist/supported-chains.d.ts +5 -0
- package/dist/supported-chains.d.ts.map +1 -0
- package/dist/supported-chains.js +3 -0
- package/dist/supported-chains.js.map +1 -0
- package/dist/types.d.ts +118 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +117 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +336 -0
- package/dist/utils.js.map +1 -0
- package/package.json +66 -8
- package/src/aptos/exec.ts +69 -0
- package/src/aptos/hasher.ts +92 -0
- package/src/aptos/index.ts +660 -0
- package/src/aptos/logs.ts +210 -0
- package/src/aptos/send.ts +120 -0
- package/src/aptos/token.ts +150 -0
- package/src/aptos/types.ts +85 -0
- package/src/aptos/utils.ts +24 -0
- package/src/chain.ts +398 -0
- package/src/commits.ts +44 -0
- package/src/evm/abi/BurnMintERC677Token.ts +487 -0
- package/src/evm/abi/CommitStore_1_2.ts +637 -0
- package/src/evm/abi/CommitStore_1_5.ts +674 -0
- package/src/evm/abi/FeeQuoter_1_6.ts +1903 -0
- package/src/evm/abi/LockReleaseTokenPool_1_5.ts +1095 -0
- package/src/evm/abi/LockReleaseTokenPool_1_5_1.ts +1277 -0
- package/src/evm/abi/LockReleaseTokenPool_1_6_1.ts +1287 -0
- package/src/evm/abi/OffRamp_1_2.ts +1203 -0
- package/src/evm/abi/OffRamp_1_5.ts +1272 -0
- package/src/evm/abi/OffRamp_1_6.ts +1528 -0
- package/src/evm/abi/OnRamp_1_2.ts +1342 -0
- package/src/evm/abi/OnRamp_1_5.ts +1426 -0
- package/src/evm/abi/OnRamp_1_6.ts +879 -0
- package/src/evm/abi/Router.ts +507 -0
- package/src/evm/abi/TokenAdminRegistry_1_5.ts +332 -0
- package/src/evm/const.ts +69 -0
- package/src/evm/errors.ts +212 -0
- package/src/evm/hasher.ts +166 -0
- package/src/evm/index.ts +1262 -0
- package/src/evm/messages.ts +73 -0
- package/src/evm/offchain.ts +189 -0
- package/src/execution.ts +131 -0
- package/src/extra-args.ts +71 -0
- package/src/gas.ts +135 -0
- package/src/hasher/common.ts +23 -0
- package/src/hasher/hasher.ts +12 -0
- package/src/hasher/index.ts +3 -0
- package/src/hasher/merklemulti.ts +309 -0
- package/src/index.ts +51 -0
- package/src/offchain.ts +86 -0
- package/src/requests.ts +339 -0
- package/src/selectors.ts +1340 -0
- package/src/solana/cleanup.ts +216 -0
- package/src/solana/exec.ts +645 -0
- package/src/solana/hasher.ts +104 -0
- package/src/solana/idl/1.6.0/BASE_TOKEN_POOL.ts +1734 -0
- package/src/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.ts +1900 -0
- package/src/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.ts +2750 -0
- package/src/solana/idl/1.6.0/CCIP_COMMON.ts +210 -0
- package/src/solana/idl/1.6.0/CCIP_OFFRAMP.ts +5494 -0
- package/src/solana/idl/1.6.0/CCIP_ROUTER.ts +4671 -0
- package/src/solana/index.ts +1454 -0
- package/src/solana/offchain.ts +209 -0
- package/src/solana/patchBorsh.ts +67 -0
- package/src/solana/send.ts +436 -0
- package/src/solana/types.ts +6 -0
- package/src/solana/utils.ts +272 -0
- package/src/sui/hasher.ts +90 -0
- package/src/sui/index.ts +198 -0
- package/src/sui/types.ts +22 -0
- package/src/supported-chains.ts +4 -0
- package/src/types.ts +153 -0
- package/src/utils.ts +405 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SVMExtraArgsV1 } from '../extra-args.ts'
|
|
2
|
+
import type { CCIPMessage_V1_6 } from '../types.ts'
|
|
3
|
+
|
|
4
|
+
// SourceTokenData adds `destGasAmount` (decoded from source's `destExecData`);
|
|
5
|
+
// not sure why they kept the "gas" name in Solana, but let's just be keep consistent
|
|
6
|
+
export type CCIPMessage_V1_6_Solana = CCIPMessage_V1_6 & SVMExtraArgsV1
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type AddressLookupTableAccount,
|
|
3
|
+
type Connection,
|
|
4
|
+
type Signer,
|
|
5
|
+
type SimulateTransactionConfig,
|
|
6
|
+
type Transaction,
|
|
7
|
+
type TransactionInstruction,
|
|
8
|
+
ComputeBudgetProgram,
|
|
9
|
+
PublicKey,
|
|
10
|
+
SendTransactionError,
|
|
11
|
+
TransactionMessage,
|
|
12
|
+
VersionedTransaction,
|
|
13
|
+
} from '@solana/web3.js'
|
|
14
|
+
import { type BytesLike, dataLength, dataSlice, hexlify } from 'ethers'
|
|
15
|
+
|
|
16
|
+
import type { Log_ } from '../types.ts'
|
|
17
|
+
import { getDataBytes, sleep } from '../utils.ts'
|
|
18
|
+
|
|
19
|
+
export function bytesToBuffer(bytes: BytesLike): Buffer {
|
|
20
|
+
return Buffer.from(getDataBytes(bytes).buffer)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function waitForFinalization(
|
|
24
|
+
connection: Connection,
|
|
25
|
+
signature: string,
|
|
26
|
+
intervalMs = 500,
|
|
27
|
+
maxAttempts = 500,
|
|
28
|
+
): Promise<void> {
|
|
29
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
30
|
+
const status = await connection.getSignatureStatuses([signature])
|
|
31
|
+
const info = status.value[0]
|
|
32
|
+
|
|
33
|
+
if (info?.confirmationStatus === 'finalized') {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
await sleep(intervalMs)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
throw new Error(`Transaction ${signature} not finalized after timeout`)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function camelToSnakeCase(str: string): string {
|
|
43
|
+
return str
|
|
44
|
+
.replace(/([A-Z]+)([A-Z][a-z]|$)/g, (_, p1: string, p2: string) => {
|
|
45
|
+
if (p2) {
|
|
46
|
+
return `_${p1.slice(0, -1).toLowerCase()}_${p2.toLowerCase()}`
|
|
47
|
+
}
|
|
48
|
+
return `_${p1.toLowerCase()}`
|
|
49
|
+
})
|
|
50
|
+
.replace(/([a-z])([A-Z])/g, '$1_$2')
|
|
51
|
+
.toLowerCase()
|
|
52
|
+
.replace(/^_/, '')
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
type ParsedLog = Pick<Log_, 'topics' | 'index' | 'address' | 'data'> & { data: string }
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Utility function to parse Solana logs with proper address and topic extraction.
|
|
59
|
+
*
|
|
60
|
+
* Solana logs are structured as a stack-based execution trace:
|
|
61
|
+
* - "Program <address> invoke [<depth>]" - Program call starts
|
|
62
|
+
* - "Program log: <data>" - Program emitted a log message
|
|
63
|
+
* - "Program data: <base64>" - Program emitted structured data (Anchor events)
|
|
64
|
+
* - "Program <address> success/failed" - Program call ends
|
|
65
|
+
*
|
|
66
|
+
* This function:
|
|
67
|
+
* 1. Tracks the program call stack to determine which program emitted each log
|
|
68
|
+
* 2. Extracts the first 8 bytes from base64 "Program data:" logs as topics (event discriminants)
|
|
69
|
+
* 3. Converts logs to EVM-compatible Log_ format for CCIP compatibility
|
|
70
|
+
* 4. Returns ALL logs from the transaction - filtering should be done by the caller
|
|
71
|
+
*
|
|
72
|
+
* @param logs - Array of logMessages from Solana transaction
|
|
73
|
+
* @returns Array of parsed log objects from all programs in the transaction
|
|
74
|
+
*/
|
|
75
|
+
export function parseSolanaLogs(logs: readonly string[]): ParsedLog[] {
|
|
76
|
+
const results: ReturnType<typeof parseSolanaLogs> = []
|
|
77
|
+
const programStack: string[] = []
|
|
78
|
+
|
|
79
|
+
for (const [i, log] of logs.entries()) {
|
|
80
|
+
// Track program calls and returns to maintain the address stack
|
|
81
|
+
let match
|
|
82
|
+
if ((match = log.match(/^Program (\w+) invoke\b/))) {
|
|
83
|
+
programStack.push(match[1])
|
|
84
|
+
} else if ((match = log.match(/^Program (\w+) (success|failed)\b/))) {
|
|
85
|
+
// Pop from stack when program returns
|
|
86
|
+
programStack.pop()
|
|
87
|
+
} else if ((match = log.match(/^Program (log|data): /))) {
|
|
88
|
+
// Extract the actual log data
|
|
89
|
+
const logData = log.slice(match[0].length)
|
|
90
|
+
const currentProgram = programStack[programStack.length - 1]
|
|
91
|
+
let topics: string[] = []
|
|
92
|
+
|
|
93
|
+
if (log.startsWith('Program data: ')) {
|
|
94
|
+
try {
|
|
95
|
+
// Try to decode base64 and extract first 8 bytes as topic/discriminant
|
|
96
|
+
const buffer = getDataBytes(logData)
|
|
97
|
+
if (dataLength(buffer) >= 8) {
|
|
98
|
+
topics = [dataSlice(buffer, 0, 8)]
|
|
99
|
+
}
|
|
100
|
+
} catch {
|
|
101
|
+
// If base64 decoding fails, leave topics empty
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// For regular log messages, use the current program on stack
|
|
105
|
+
results.push({
|
|
106
|
+
topics,
|
|
107
|
+
index: i,
|
|
108
|
+
address: currentProgram,
|
|
109
|
+
data: logData,
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return results
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function getErrorFromLogs(
|
|
118
|
+
logs_: readonly string[] | readonly Pick<Log_, 'address' | 'index' | 'data' | 'topics'>[] | null,
|
|
119
|
+
): { program: string; [k: string]: string } | undefined {
|
|
120
|
+
if (!logs_?.length) return
|
|
121
|
+
let logs
|
|
122
|
+
if (logs_.every((l) => typeof l === 'string')) logs = parseSolanaLogs(logs_)
|
|
123
|
+
else logs = logs_
|
|
124
|
+
|
|
125
|
+
const lastLog = logs[logs.length - 1]
|
|
126
|
+
// collect all logs from the last program execution (the one which failed)
|
|
127
|
+
const lastProgramLogs = logs
|
|
128
|
+
.reduceRight(
|
|
129
|
+
(acc, l) =>
|
|
130
|
+
// if acc is empty (i.e. on last log), or it is emitted by the same program and not a Program data:
|
|
131
|
+
!acc.length || (l.address === acc[0].address && !l.topics?.length) ? [l, ...acc] : acc,
|
|
132
|
+
[] as Pick<Log_, 'address' | 'index' | 'data'>[],
|
|
133
|
+
)
|
|
134
|
+
.map(({ data }) => data as string)
|
|
135
|
+
.reduceRight(
|
|
136
|
+
(acc, l) =>
|
|
137
|
+
l.endsWith(':') && acc.length
|
|
138
|
+
? [`${l} ${acc[0]}`, ...acc.slice(1)]
|
|
139
|
+
: l.split(': ').length > 1 && l.split('. ').length > 1
|
|
140
|
+
? [...l.replace(/\.$/, '').split('. '), ...acc]
|
|
141
|
+
: [l, ...acc],
|
|
142
|
+
[] as string[],
|
|
143
|
+
) // cosmetic: join lines ending in ':' with next
|
|
144
|
+
.map((l) => {
|
|
145
|
+
try {
|
|
146
|
+
// convert number[]s (common in solana logs) into slightly more readable 0x-bytearrays
|
|
147
|
+
return l.replace(/\[(\d{1,3}, ){3,}\d+\]/g, (m) =>
|
|
148
|
+
hexlify(
|
|
149
|
+
new Uint8Array(
|
|
150
|
+
m
|
|
151
|
+
.substring(1, m.length - 1)
|
|
152
|
+
.split(', ')
|
|
153
|
+
.map((x) => +x),
|
|
154
|
+
),
|
|
155
|
+
),
|
|
156
|
+
)
|
|
157
|
+
} catch (_) {
|
|
158
|
+
return l
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
if (lastProgramLogs.every((l) => l.indexOf(': ') >= 0)) {
|
|
162
|
+
return {
|
|
163
|
+
program: lastLog.address,
|
|
164
|
+
...Object.fromEntries(
|
|
165
|
+
lastProgramLogs.map((l) => [
|
|
166
|
+
l.substring(0, l.indexOf(': ')),
|
|
167
|
+
l.substring(l.indexOf(': ') + 2),
|
|
168
|
+
]),
|
|
169
|
+
),
|
|
170
|
+
}
|
|
171
|
+
} else {
|
|
172
|
+
return {
|
|
173
|
+
program: lastLog.address,
|
|
174
|
+
error: lastProgramLogs.join('\n'),
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export async function simulateTransaction({
|
|
180
|
+
connection,
|
|
181
|
+
payerKey,
|
|
182
|
+
computeUnitsOverride,
|
|
183
|
+
...rest
|
|
184
|
+
}: {
|
|
185
|
+
connection: Connection
|
|
186
|
+
payerKey: PublicKey
|
|
187
|
+
computeUnitsOverride?: number
|
|
188
|
+
addressLookupTableAccounts?: AddressLookupTableAccount[]
|
|
189
|
+
} & ({ instructions: TransactionInstruction[] } | { tx: Transaction | VersionedTransaction })) {
|
|
190
|
+
// Add max compute units for simulation
|
|
191
|
+
const maxComputeUnits = 1_400_000
|
|
192
|
+
const recentBlockhash = '11111111111111111111111111111112'
|
|
193
|
+
const computeBudgetIx = ComputeBudgetProgram.setComputeUnitLimit({
|
|
194
|
+
units: computeUnitsOverride || maxComputeUnits,
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
let tx: VersionedTransaction
|
|
198
|
+
if (!('tx' in rest)) {
|
|
199
|
+
// Create message with compute budget instruction
|
|
200
|
+
const message = new TransactionMessage({
|
|
201
|
+
payerKey,
|
|
202
|
+
recentBlockhash,
|
|
203
|
+
instructions: [computeBudgetIx, ...rest.instructions],
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
const messageV0 = message.compileToV0Message(rest.addressLookupTableAccounts)
|
|
207
|
+
tx = new VersionedTransaction(messageV0)
|
|
208
|
+
} else if (!('version' in rest.tx)) {
|
|
209
|
+
// Create message with compute budget instruction
|
|
210
|
+
const message = new TransactionMessage({
|
|
211
|
+
payerKey,
|
|
212
|
+
recentBlockhash,
|
|
213
|
+
instructions: [computeBudgetIx, ...rest.tx.instructions],
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
const messageV0 = message.compileToV0Message(rest.addressLookupTableAccounts)
|
|
217
|
+
tx = new VersionedTransaction(messageV0)
|
|
218
|
+
} else {
|
|
219
|
+
tx = rest.tx
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const config: SimulateTransactionConfig = {
|
|
223
|
+
commitment: 'confirmed',
|
|
224
|
+
replaceRecentBlockhash: true,
|
|
225
|
+
sigVerify: false,
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const result = await connection.simulateTransaction(tx, config)
|
|
229
|
+
|
|
230
|
+
if (result.value.err) {
|
|
231
|
+
console.debug('Simulation results:', {
|
|
232
|
+
logs: result.value.logs,
|
|
233
|
+
unitsConsumed: result.value.unitsConsumed,
|
|
234
|
+
returnData: result.value.returnData,
|
|
235
|
+
err: result.value.err,
|
|
236
|
+
})
|
|
237
|
+
// same error sendTransaction sends, to be catched up
|
|
238
|
+
throw new SendTransactionError({
|
|
239
|
+
action: 'simulate',
|
|
240
|
+
signature: '',
|
|
241
|
+
transactionMessage: JSON.stringify(result.value.err),
|
|
242
|
+
logs: result.value.logs!,
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return result.value
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Used as `provider` in anchor's `Program` constructor, to support `.view()` simulations
|
|
251
|
+
* without * requiring a full AnchorProvider with wallet
|
|
252
|
+
* @param connection - Connection to the Solana network
|
|
253
|
+
* @param feePayer - Fee payer for the simulated transaction
|
|
254
|
+
* @returns Value returned by the simulated method
|
|
255
|
+
*/
|
|
256
|
+
export function simulationProvider(
|
|
257
|
+
connection: Connection,
|
|
258
|
+
feePayer: PublicKey = new PublicKey('11111111111111111111111111111112'),
|
|
259
|
+
) {
|
|
260
|
+
return {
|
|
261
|
+
connection,
|
|
262
|
+
wallet: {
|
|
263
|
+
publicKey: feePayer,
|
|
264
|
+
},
|
|
265
|
+
simulate: async (tx: Transaction | VersionedTransaction, _signers?: Signer[]) =>
|
|
266
|
+
simulateTransaction({
|
|
267
|
+
connection,
|
|
268
|
+
payerKey: feePayer,
|
|
269
|
+
tx,
|
|
270
|
+
}),
|
|
271
|
+
}
|
|
272
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { concat, id, keccak256, zeroPadValue } from 'ethers'
|
|
2
|
+
|
|
3
|
+
import { encodeNumber, encodeRawBytes } from '../aptos/utils.ts'
|
|
4
|
+
import { decodeExtraArgs } from '../extra-args.ts'
|
|
5
|
+
import { type LeafHasher, LEAF_DOMAIN_SEPARATOR } from '../hasher/common.ts'
|
|
6
|
+
import { type CCIPMessage, type CCIPMessage_V1_6, CCIPVersion } from '../types.ts'
|
|
7
|
+
import type { CCIPMessage_V1_6_Sui } from './types.ts'
|
|
8
|
+
|
|
9
|
+
export function getSuiLeafHasher<V extends CCIPVersion = CCIPVersion>({
|
|
10
|
+
sourceChainSelector,
|
|
11
|
+
destChainSelector,
|
|
12
|
+
onRamp,
|
|
13
|
+
version,
|
|
14
|
+
}: {
|
|
15
|
+
sourceChainSelector: bigint
|
|
16
|
+
destChainSelector: bigint
|
|
17
|
+
onRamp: string
|
|
18
|
+
version: V
|
|
19
|
+
}): LeafHasher<V> {
|
|
20
|
+
let metadataHash: string
|
|
21
|
+
switch (version) {
|
|
22
|
+
case CCIPVersion.V1_6:
|
|
23
|
+
metadataHash = hashSuiMetadata(sourceChainSelector, destChainSelector, onRamp)
|
|
24
|
+
return ((message: CCIPMessage<typeof CCIPVersion.V1_6>): string =>
|
|
25
|
+
hashV16SuiMessage(message, metadataHash)) as LeafHasher<V>
|
|
26
|
+
default:
|
|
27
|
+
throw new Error(`Unsupported hasher version for Sui: ${version as string}`)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function hashV16SuiMessage(
|
|
32
|
+
message: CCIPMessage_V1_6 | CCIPMessage_V1_6_Sui,
|
|
33
|
+
metadataHash: string,
|
|
34
|
+
): string {
|
|
35
|
+
let tokenReceiver, gasLimit
|
|
36
|
+
if ('tokenReceiver' in message) {
|
|
37
|
+
;({ tokenReceiver, gasLimit } = message)
|
|
38
|
+
} else {
|
|
39
|
+
const parsedArgs = decodeExtraArgs(message.extraArgs)
|
|
40
|
+
if (!parsedArgs || parsedArgs._tag !== 'SuiExtraArgsV1')
|
|
41
|
+
throw new Error('Invalid extraArgs for Sui message, must be SUIExtraArgsV1')
|
|
42
|
+
;({ tokenReceiver, gasLimit } = parsedArgs)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const innerHash = concat([
|
|
46
|
+
encodeNumber(message.header.messageId),
|
|
47
|
+
zeroPadValue(message.receiver, 32),
|
|
48
|
+
encodeNumber(message.header.sequenceNumber),
|
|
49
|
+
encodeNumber(gasLimit),
|
|
50
|
+
zeroPadValue(tokenReceiver, 32),
|
|
51
|
+
encodeNumber(message.header.nonce),
|
|
52
|
+
])
|
|
53
|
+
|
|
54
|
+
const tokenHash = concat([
|
|
55
|
+
encodeNumber(message.tokenAmounts.length),
|
|
56
|
+
...message.tokenAmounts.map((token) =>
|
|
57
|
+
concat([
|
|
58
|
+
encodeRawBytes(token.sourcePoolAddress),
|
|
59
|
+
zeroPadValue(token.destTokenAddress, 32),
|
|
60
|
+
encodeNumber(token.destGasAmount),
|
|
61
|
+
encodeRawBytes(token.extraData),
|
|
62
|
+
encodeNumber(token.amount),
|
|
63
|
+
]),
|
|
64
|
+
),
|
|
65
|
+
])
|
|
66
|
+
|
|
67
|
+
const outerHash = concat([
|
|
68
|
+
zeroPadValue(LEAF_DOMAIN_SEPARATOR, 32),
|
|
69
|
+
metadataHash,
|
|
70
|
+
keccak256(innerHash),
|
|
71
|
+
keccak256(message.sender),
|
|
72
|
+
keccak256(message.data),
|
|
73
|
+
keccak256(tokenHash),
|
|
74
|
+
])
|
|
75
|
+
|
|
76
|
+
return keccak256(outerHash)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const hashSuiMetadata = (
|
|
80
|
+
sourceChainSelector: bigint,
|
|
81
|
+
destChainSelector: bigint,
|
|
82
|
+
onRamp: string,
|
|
83
|
+
): string => {
|
|
84
|
+
const versionHash = id('Any2SuiMessageHashV1')
|
|
85
|
+
const encodedSource = encodeNumber(sourceChainSelector)
|
|
86
|
+
const encodedDest = encodeNumber(destChainSelector)
|
|
87
|
+
const onrampHash = keccak256(onRamp)
|
|
88
|
+
|
|
89
|
+
return keccak256(concat([versionHash, encodedSource, encodedDest, onrampHash]))
|
|
90
|
+
}
|
package/src/sui/index.ts
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { type BytesLike, isBytesLike } from 'ethers'
|
|
2
|
+
|
|
3
|
+
import { AptosChain } from '../aptos/index.ts'
|
|
4
|
+
import { type ChainTransaction, type LogFilter, Chain, ChainFamily } from '../chain.ts'
|
|
5
|
+
import type { EVMExtraArgsV2, ExtraArgs, SVMExtraArgsV1 } from '../extra-args.ts'
|
|
6
|
+
import type { LeafHasher } from '../hasher/common.ts'
|
|
7
|
+
import { supportedChains } from '../supported-chains.ts'
|
|
8
|
+
import type {
|
|
9
|
+
AnyMessage,
|
|
10
|
+
CCIPRequest,
|
|
11
|
+
CommitReport,
|
|
12
|
+
ExecutionReceipt,
|
|
13
|
+
ExecutionReport,
|
|
14
|
+
Lane,
|
|
15
|
+
Log_,
|
|
16
|
+
NetworkInfo,
|
|
17
|
+
OffchainTokenData,
|
|
18
|
+
} from '../types.ts'
|
|
19
|
+
import type { CCIPMessage_V1_6_Sui } from './types.ts'
|
|
20
|
+
|
|
21
|
+
export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
22
|
+
static readonly family = ChainFamily.Sui
|
|
23
|
+
static readonly decimals = 8
|
|
24
|
+
|
|
25
|
+
readonly network: NetworkInfo<typeof ChainFamily.Sui>
|
|
26
|
+
|
|
27
|
+
constructor() {
|
|
28
|
+
super()
|
|
29
|
+
throw new Error('Not implemented')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static async fromUrl(_url: string): Promise<SuiChain> {
|
|
33
|
+
return Promise.reject(new Error('Not implemented'))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async destroy(): Promise<void> {
|
|
37
|
+
// Nothing to cleanup for Aptos implementation
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async getBlockTimestamp(_version: number | 'finalized'): Promise<number> {
|
|
41
|
+
return Promise.reject(new Error('Not implemented'))
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async getTransaction(_hash: string | number): Promise<ChainTransaction> {
|
|
45
|
+
return Promise.reject(new Error('Not implemented'))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// eslint-disable-next-line require-yield
|
|
49
|
+
async *getLogs(_opts: LogFilter & { versionAsHash?: boolean }) {
|
|
50
|
+
await Promise.resolve()
|
|
51
|
+
throw new Error('Not implemented')
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async typeAndVersion(
|
|
55
|
+
_address: string,
|
|
56
|
+
): Promise<
|
|
57
|
+
| [type_: string, version: string, typeAndVersion: string]
|
|
58
|
+
| [type_: string, version: string, typeAndVersion: string, suffix: string]
|
|
59
|
+
> {
|
|
60
|
+
return Promise.reject(new Error('Not implemented'))
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getRouterForOnRamp(_onRamp: string, _destChainSelector: bigint): Promise<string> {
|
|
64
|
+
return Promise.reject(new Error('Not implemented'))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
getRouterForOffRamp(_offRamp: string, _sourceChainSelector: bigint): Promise<string> {
|
|
68
|
+
return Promise.reject(new Error('Not implemented'))
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
getNativeTokenForRouter(_router: string): Promise<string> {
|
|
72
|
+
return Promise.reject(new Error('Not implemented'))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
getOffRampsForRouter(_router: string, _sourceChainSelector: bigint): Promise<string[]> {
|
|
76
|
+
return Promise.reject(new Error('Not implemented'))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
getOnRampForRouter(_router: string, _destChainSelector: bigint): Promise<string> {
|
|
80
|
+
return Promise.reject(new Error('Not implemented'))
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async getOnRampForOffRamp(_offRamp: string, _sourceChainSelector: bigint): Promise<string> {
|
|
84
|
+
return Promise.reject(new Error('Not implemented'))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
getCommitStoreForOffRamp(_offRamp: string): Promise<string> {
|
|
88
|
+
return Promise.reject(new Error('Not implemented'))
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async getTokenForTokenPool(_tokenPool: string): Promise<string> {
|
|
92
|
+
return Promise.reject(new Error('Not implemented'))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async getTokenInfo(_token: string): Promise<{ symbol: string; decimals: number }> {
|
|
96
|
+
return Promise.reject(new Error('Not implemented'))
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
getTokenAdminRegistryFor(_address: string): Promise<string> {
|
|
100
|
+
return Promise.reject(new Error('Not implemented'))
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async getWalletAddress(_opts?: { wallet?: unknown }): Promise<string> {
|
|
104
|
+
return Promise.reject(new Error('Not implemented'))
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Static methods for decoding
|
|
108
|
+
static decodeMessage(_log: Log_): CCIPMessage_V1_6_Sui | undefined {
|
|
109
|
+
throw new Error('Not implemented')
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static decodeExtraArgs(
|
|
113
|
+
extraArgs: BytesLike,
|
|
114
|
+
):
|
|
115
|
+
| (EVMExtraArgsV2 & { _tag: 'EVMExtraArgsV2' })
|
|
116
|
+
| (SVMExtraArgsV1 & { _tag: 'SVMExtraArgsV1' })
|
|
117
|
+
| undefined {
|
|
118
|
+
return AptosChain.decodeExtraArgs(extraArgs)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
static encodeExtraArgs(extraArgs: ExtraArgs): string {
|
|
122
|
+
return AptosChain.encodeExtraArgs(extraArgs)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
static decodeCommits(_log: Log_, _lane?: Lane): CommitReport[] | undefined {
|
|
126
|
+
throw new Error('Not implemented')
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
static decodeReceipt(_log: Log_): ExecutionReceipt | undefined {
|
|
130
|
+
throw new Error('Not implemented')
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static getAddress(bytes: BytesLike): string {
|
|
134
|
+
return AptosChain.getAddress(bytes)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static getDestLeafHasher(_lane: Lane): LeafHasher {
|
|
138
|
+
throw new Error('Not implemented')
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async getFee(_router: string, _destChainSelector: bigint, _message: AnyMessage): Promise<bigint> {
|
|
142
|
+
return Promise.reject(new Error('Not implemented'))
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async sendMessage(
|
|
146
|
+
_router: string,
|
|
147
|
+
_destChainSelector: bigint,
|
|
148
|
+
_message: AnyMessage & { fee: bigint },
|
|
149
|
+
_opts?: { wallet?: unknown; approveMax?: boolean },
|
|
150
|
+
): Promise<ChainTransaction> {
|
|
151
|
+
return Promise.reject(new Error('Not implemented'))
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
fetchOffchainTokenData(request: CCIPRequest): Promise<OffchainTokenData[]> {
|
|
155
|
+
if (!('receiverObjectIds' in request.message)) {
|
|
156
|
+
throw new Error('Invalid message, not v1.6 Sui')
|
|
157
|
+
}
|
|
158
|
+
// default offchain token data
|
|
159
|
+
return Promise.resolve(request.message.tokenAmounts.map(() => undefined))
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async executeReport(
|
|
163
|
+
_offRamp: string,
|
|
164
|
+
_execReport: ExecutionReport,
|
|
165
|
+
_opts?: { wallet?: unknown; gasLimit?: number },
|
|
166
|
+
): Promise<ChainTransaction> {
|
|
167
|
+
return Promise.reject(new Error('Not implemented'))
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
static parse(data: unknown) {
|
|
171
|
+
if (isBytesLike(data)) {
|
|
172
|
+
const parsedExtraArgs = this.decodeExtraArgs(data)
|
|
173
|
+
if (parsedExtraArgs) return parsedExtraArgs
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async getSupportedTokens(_address: string): Promise<string[]> {
|
|
178
|
+
return Promise.reject(new Error('Not implemented'))
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async getRegistryTokenConfig(_address: string, _tokenName: string): Promise<never> {
|
|
182
|
+
return Promise.reject(new Error('Not implemented'))
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async getTokenPoolConfigs(_tokenPool: string): Promise<never> {
|
|
186
|
+
return Promise.reject(new Error('Not implemented'))
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async getTokenPoolRemotes(_tokenPool: string): Promise<never> {
|
|
190
|
+
return Promise.reject(new Error('Not implemented'))
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async listFeeTokens(_router: string): Promise<never> {
|
|
194
|
+
return Promise.reject(new Error('Not implemented'))
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
supportedChains[ChainFamily.Sui] = SuiChain
|
package/src/sui/types.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { bcs } from '@mysten/sui/bcs'
|
|
2
|
+
import { concat } from 'ethers'
|
|
3
|
+
|
|
4
|
+
import { type SuiExtraArgsV1, SuiExtraArgsV1Tag } from '../extra-args.ts'
|
|
5
|
+
import type { CCIPMessage_V1_6 } from '../types.ts'
|
|
6
|
+
import { getAddressBytes, getDataBytes } from '../utils.ts'
|
|
7
|
+
|
|
8
|
+
export type CCIPMessage_V1_6_Sui = CCIPMessage_V1_6 & SuiExtraArgsV1
|
|
9
|
+
|
|
10
|
+
export const SuiExtraArgsV1Codec = bcs.struct('SuiExtraArgsV1', {
|
|
11
|
+
gasLimit: bcs.u64(),
|
|
12
|
+
allowOutOfOrderExecution: bcs.bool(),
|
|
13
|
+
tokenReceiver: bcs.vector(bcs.u8()),
|
|
14
|
+
receiverObjectIds: bcs.vector(bcs.vector(bcs.u8())),
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
export function encodeSuiExtraArgsV1(args: SuiExtraArgsV1): string {
|
|
18
|
+
const tokenReceiver = getAddressBytes(args.tokenReceiver)
|
|
19
|
+
const receiverObjectIds = args.receiverObjectIds.map((id) => getDataBytes(id))
|
|
20
|
+
const bcsData = SuiExtraArgsV1Codec.serialize({ ...args, tokenReceiver, receiverObjectIds })
|
|
21
|
+
return concat([SuiExtraArgsV1Tag, bcsData.toBytes()])
|
|
22
|
+
}
|