@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,309 @@
|
|
|
1
|
+
// For reference implementation, see https://github.com/smartcontractkit/ccip/blob/ccip-develop/core/services/ocr2/plugins/ccip/merklemulti/merkle_multi.go
|
|
2
|
+
import { ZERO_HASH, hashInternal } from './common.ts'
|
|
3
|
+
|
|
4
|
+
export const MAX_NUMBER_TREE_LEAVES = 256
|
|
5
|
+
|
|
6
|
+
type Hash = string
|
|
7
|
+
|
|
8
|
+
interface SingleLayerProof {
|
|
9
|
+
nextIndices: number[]
|
|
10
|
+
subProof: Hash[]
|
|
11
|
+
sourceFlags: boolean[]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Proof represents a proof data structure with hashes and source flags.
|
|
16
|
+
* @template Hash The hash type.
|
|
17
|
+
*/
|
|
18
|
+
export class Proof {
|
|
19
|
+
hashes: Hash[] = []
|
|
20
|
+
sourceFlags: boolean[] = []
|
|
21
|
+
|
|
22
|
+
constructor(hashes: Hash[] = [], sourceFlags: boolean[] = []) {
|
|
23
|
+
this.hashes = hashes
|
|
24
|
+
this.sourceFlags = sourceFlags
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Counts the number of source flags that match the given boolean value.
|
|
29
|
+
* @param b The boolean value to count.
|
|
30
|
+
* @returns The count of source flags matching the provided boolean value.
|
|
31
|
+
*/
|
|
32
|
+
countSourceFlags(b: boolean): number {
|
|
33
|
+
return this.sourceFlags.filter((flag) => flag === b).length
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Computes the next layer of a binary tree structure represented as an array of hash values.
|
|
39
|
+
*
|
|
40
|
+
* This function takes a context `ctx` and an array `layer` containing hash values as input.
|
|
41
|
+
* It processes the `layer` to generate the next layer of hash values, pairing adjacent values
|
|
42
|
+
* and applying the hashing function provided by the context.
|
|
43
|
+
*
|
|
44
|
+
* @template Hash - Generic type parameter representing the hash type.
|
|
45
|
+
* @param {Hash[]} layer - An array of hash values representing the current layer of the binary tree.
|
|
46
|
+
* @returns {[Hash[], Hash[]]} A tuple containing two arrays:
|
|
47
|
+
* - The first array contains the original input layer.
|
|
48
|
+
* - The second array contains the next layer of hash values generated by combining pairs of hashes.
|
|
49
|
+
*/
|
|
50
|
+
function computeNextLayer(layer: Hash[]): readonly [Hash[], Hash[]] {
|
|
51
|
+
if (layer.length === 1) {
|
|
52
|
+
return [layer, layer]
|
|
53
|
+
}
|
|
54
|
+
if (layer.length % 2 !== 0) {
|
|
55
|
+
layer.push(ZERO_HASH)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const nextLayer: Hash[] = []
|
|
59
|
+
for (let i = 0; i < layer.length; i += 2) {
|
|
60
|
+
nextLayer.push(hashInternal(layer[i], layer[i + 1]))
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return [layer, nextLayer]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Calculates the parent index of a given index in a binary tree.
|
|
68
|
+
* @param idx The index for which to calculate the parent index.
|
|
69
|
+
* @returns The parent index.
|
|
70
|
+
*/
|
|
71
|
+
function parentIndex(idx: number): number {
|
|
72
|
+
return Math.floor(idx / 2)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Calculates the sibling index of a given index in a binary tree.
|
|
77
|
+
* @param idx The index for which to calculate the sibling index.
|
|
78
|
+
* @returns The sibling index.
|
|
79
|
+
*/
|
|
80
|
+
function siblingIndex(idx: number): number {
|
|
81
|
+
return idx ^ 1
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Generates a single-layer Merkle proof for a given set of indices within a layer.
|
|
86
|
+
* @param layer The layer of data for which to generate the proof.
|
|
87
|
+
* @param indices The indices within the layer for which to generate the proof.
|
|
88
|
+
* @returns A single-layer proof object containing nextIndices, subProof, and sourceFlags.
|
|
89
|
+
*/
|
|
90
|
+
function proveSingleLayer(layer: Hash[], indices: number[]): SingleLayerProof {
|
|
91
|
+
const authIndices: number[] = []
|
|
92
|
+
const nextIndices: number[] = []
|
|
93
|
+
const sourceFlags: boolean[] = []
|
|
94
|
+
|
|
95
|
+
let j = 0
|
|
96
|
+
while (j < indices.length) {
|
|
97
|
+
const x = indices[j]
|
|
98
|
+
|
|
99
|
+
// Calculate the parent index for the current index and add it to the nextIndices array.
|
|
100
|
+
nextIndices.push(parentIndex(x))
|
|
101
|
+
|
|
102
|
+
// Check if there is a sibling index following the current index.
|
|
103
|
+
if (j + 1 < indices.length && indices[j + 1] === siblingIndex(x)) {
|
|
104
|
+
// If a sibling index is found, mark it as a source of the proof (sourceFlag = true).
|
|
105
|
+
j++
|
|
106
|
+
sourceFlags.push(true)
|
|
107
|
+
} else {
|
|
108
|
+
// If there is no sibling index, add the sibling index to the authentication indices.
|
|
109
|
+
authIndices.push(siblingIndex(x))
|
|
110
|
+
// Mark it as not a source of the proof (sourceFlag = false).
|
|
111
|
+
sourceFlags.push(false)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
j++
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Initialize an array to store the subproof.
|
|
118
|
+
const subProof: Hash[] = []
|
|
119
|
+
for (const i of authIndices) {
|
|
120
|
+
// Populate the subproof array with the values from the authentication indices in the layer.
|
|
121
|
+
subProof.push(layer[i])
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Return the single-layer proof object containing nextIndices, subProof, and sourceFlags.
|
|
125
|
+
return {
|
|
126
|
+
nextIndices,
|
|
127
|
+
subProof,
|
|
128
|
+
sourceFlags,
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Represents a Merkle Tree data structure.
|
|
134
|
+
* @typeparam Hash The type of hash used in the tree.
|
|
135
|
+
*/
|
|
136
|
+
export class Tree {
|
|
137
|
+
layers: Hash[][]
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Creates a new Merkle Tree using the provided context and leaf hashes.
|
|
141
|
+
* @param leafHashes An array of leaf hashes to construct the tree.
|
|
142
|
+
* @returns A new Merkle Tree instance.
|
|
143
|
+
* @throws Error if there are no leaf hashes provided.
|
|
144
|
+
*/
|
|
145
|
+
constructor(leafHashes: Hash[]) {
|
|
146
|
+
if (leafHashes.length === 0) {
|
|
147
|
+
throw new Error('Cannot construct a tree without leaves')
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Initialize the first layer with leaf hashes.
|
|
151
|
+
let layer: Hash[] = [...leafHashes]
|
|
152
|
+
|
|
153
|
+
// Initialize an array to store layers.
|
|
154
|
+
const layers: Hash[][] = [layer]
|
|
155
|
+
|
|
156
|
+
let curr = 0
|
|
157
|
+
|
|
158
|
+
// Continue building layers until there is only one hash remaining.
|
|
159
|
+
while (layer.length > 1) {
|
|
160
|
+
const [paddedLayer, nextLayer] = computeNextLayer(layer)
|
|
161
|
+
layers[curr] = paddedLayer
|
|
162
|
+
curr++
|
|
163
|
+
layers.push(nextLayer)
|
|
164
|
+
layer = nextLayer
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
this.layers = layers
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Returns the root hash of the Merkle Tree.
|
|
172
|
+
* @returns The root hash.
|
|
173
|
+
*/
|
|
174
|
+
root(): Hash {
|
|
175
|
+
return this.layers[this.layers.length - 1][0]
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Generates a Merkle proof for a set of indices in the tree.
|
|
180
|
+
* @param indices The indices for which to generate the proof.
|
|
181
|
+
* @returns A proof object containing hashes and source flags.
|
|
182
|
+
*/
|
|
183
|
+
prove(indices: number[]): Proof {
|
|
184
|
+
const proof: Proof = new Proof([], [])
|
|
185
|
+
|
|
186
|
+
for (const layer of this.layers.slice(0, this.layers.length - 1)) {
|
|
187
|
+
const res = proveSingleLayer(layer, indices)
|
|
188
|
+
|
|
189
|
+
indices = res.nextIndices
|
|
190
|
+
proof.hashes.push(...res.subProof)
|
|
191
|
+
proof.sourceFlags.push(...res.sourceFlags)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return proof
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Converts an array of boolean proof flags to a BigNumber where each flag represents a bit.
|
|
200
|
+
* @param proofFlags An array of boolean proof flags.
|
|
201
|
+
* @returns A BigNumber representing the encoded flags.
|
|
202
|
+
*/
|
|
203
|
+
export function proofFlagsToBits(proofFlags: boolean[]): bigint {
|
|
204
|
+
let encodedFlags = 0n
|
|
205
|
+
|
|
206
|
+
// Iterate through the proof flags to encode them into bits.
|
|
207
|
+
for (let i = 0; i < proofFlags.length; i++) {
|
|
208
|
+
if (proofFlags[i]) {
|
|
209
|
+
// If the current flag is true, set the corresponding bit to 1 using bitwise OR.
|
|
210
|
+
encodedFlags |= 1n << BigInt(i)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Return the final BigNumber representing the encoded flags.
|
|
214
|
+
return encodedFlags
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Verifies and computes the Merkle root hash based on provided leaf hashes and a Merkle proof.
|
|
219
|
+
* @param ctx The Merkle context.
|
|
220
|
+
* @param leafHashes An array of leaf hashes.
|
|
221
|
+
* @param proof The Merkle proof containing hashes and source flags.
|
|
222
|
+
* @returns The computed Merkle root hash.
|
|
223
|
+
*/
|
|
224
|
+
export function verifyComputeRoot(leafHashes: Hash[], proof: Proof): Hash {
|
|
225
|
+
const leavesLength = leafHashes.length
|
|
226
|
+
const proofsLength = proof.hashes.length
|
|
227
|
+
|
|
228
|
+
if (leavesLength === 0 && proofsLength === 0) {
|
|
229
|
+
throw new Error('leaves and proofs are empty')
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (leavesLength > MAX_NUMBER_TREE_LEAVES + 1 || proofsLength > MAX_NUMBER_TREE_LEAVES + 1) {
|
|
233
|
+
throw new Error(`leaves or proofs length beyond the limit of ${MAX_NUMBER_TREE_LEAVES}`)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const totalHashes = leavesLength + proofsLength - 1
|
|
237
|
+
|
|
238
|
+
if (totalHashes > MAX_NUMBER_TREE_LEAVES) {
|
|
239
|
+
throw new Error(`total hashes length cannot be larger than ${MAX_NUMBER_TREE_LEAVES}`)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (totalHashes !== proof.sourceFlags.length) {
|
|
243
|
+
throw new Error(`hashes ${totalHashes} != sourceFlags ${proof.sourceFlags.length}`)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// If there are no hashes, return the first leaf hash.
|
|
247
|
+
if (totalHashes === 0) {
|
|
248
|
+
return leafHashes[0]
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Count the number of source flags pointing to proofs.
|
|
252
|
+
const sourceProofCount = proof.countSourceFlags(false)
|
|
253
|
+
|
|
254
|
+
if (sourceProofCount !== proofsLength) {
|
|
255
|
+
throw new Error(`proof source flags ${sourceProofCount} != proof hashes ${proofsLength}`)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const hashes: Hash[] = new Array<Hash>(totalHashes)
|
|
259
|
+
|
|
260
|
+
for (let i = 0; i < totalHashes; i++) {
|
|
261
|
+
// Initialize the hashes array with the first leaf hash.
|
|
262
|
+
hashes.push(leafHashes[0])
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
let leafPos = 0
|
|
266
|
+
let hashPos = 0
|
|
267
|
+
let proofPos = 0
|
|
268
|
+
|
|
269
|
+
for (let i = 0; i < totalHashes; i++) {
|
|
270
|
+
let a: Hash | undefined = undefined
|
|
271
|
+
let b: Hash | undefined = undefined
|
|
272
|
+
|
|
273
|
+
if (proof.sourceFlags[i] === true) {
|
|
274
|
+
if (leafPos < leavesLength) {
|
|
275
|
+
a = leafHashes[leafPos]
|
|
276
|
+
leafPos++
|
|
277
|
+
} else {
|
|
278
|
+
a = hashes[hashPos]
|
|
279
|
+
hashPos++
|
|
280
|
+
}
|
|
281
|
+
} else if (proof.sourceFlags[i] === false) {
|
|
282
|
+
a = proof.hashes[proofPos]
|
|
283
|
+
proofPos++
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (leafPos < leavesLength) {
|
|
287
|
+
b = leafHashes[leafPos]
|
|
288
|
+
leafPos++
|
|
289
|
+
} else {
|
|
290
|
+
b = hashes[hashPos]
|
|
291
|
+
hashPos++
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (a === undefined || b === undefined) {
|
|
295
|
+
throw new Error('a or b is undefined')
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Compute the hash of a and b and store it in the hashes array.
|
|
299
|
+
hashes[i] = hashInternal(a, b)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Check if all proofs were used during processing.
|
|
303
|
+
if (hashPos !== totalHashes - 1 || leafPos !== leavesLength || proofPos !== proofsLength) {
|
|
304
|
+
throw new Error('not all proofs used during processing')
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Return the computed Merkle root hash.
|
|
308
|
+
return hashes[totalHashes - 1]
|
|
309
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export { AptosChain } from './aptos/index.ts'
|
|
2
|
+
export {
|
|
3
|
+
type Chain,
|
|
4
|
+
type ChainGetter,
|
|
5
|
+
type ChainStatic,
|
|
6
|
+
type ChainTransaction,
|
|
7
|
+
type LogFilter,
|
|
8
|
+
type RateLimiterState,
|
|
9
|
+
type TokenInfo,
|
|
10
|
+
type TokenPoolRemote,
|
|
11
|
+
ChainFamily,
|
|
12
|
+
} from './chain.ts'
|
|
13
|
+
export { EVMChain } from './evm/index.ts'
|
|
14
|
+
export { calculateManualExecProof, discoverOffRamp } from './execution.ts'
|
|
15
|
+
export {
|
|
16
|
+
type EVMExtraArgsV1,
|
|
17
|
+
type EVMExtraArgsV2,
|
|
18
|
+
type ExtraArgs,
|
|
19
|
+
type SVMExtraArgsV1,
|
|
20
|
+
type SuiExtraArgsV1,
|
|
21
|
+
decodeExtraArgs,
|
|
22
|
+
encodeExtraArgs,
|
|
23
|
+
} from './extra-args.ts'
|
|
24
|
+
export { estimateExecGasForRequest } from './gas.ts'
|
|
25
|
+
export {
|
|
26
|
+
decodeMessage,
|
|
27
|
+
fetchAllMessagesInBatch,
|
|
28
|
+
fetchCCIPMessageById,
|
|
29
|
+
fetchCCIPRequestsInTx,
|
|
30
|
+
fetchRequestsForSender,
|
|
31
|
+
sourceToDestTokenAmounts,
|
|
32
|
+
} from './requests.ts'
|
|
33
|
+
export { SolanaChain } from './solana/index.ts'
|
|
34
|
+
export { SuiChain } from './sui/index.ts'
|
|
35
|
+
export { supportedChains } from './supported-chains.ts'
|
|
36
|
+
export {
|
|
37
|
+
type AnyMessage,
|
|
38
|
+
type CCIPCommit,
|
|
39
|
+
type CCIPExecution,
|
|
40
|
+
type CCIPMessage,
|
|
41
|
+
type CCIPRequest,
|
|
42
|
+
type CommitReport,
|
|
43
|
+
type ExecutionReceipt,
|
|
44
|
+
type ExecutionReport,
|
|
45
|
+
type Lane,
|
|
46
|
+
type NetworkInfo,
|
|
47
|
+
type OffchainTokenData,
|
|
48
|
+
CCIPVersion,
|
|
49
|
+
ExecutionState,
|
|
50
|
+
} from './types.ts'
|
|
51
|
+
export { bigIntReplacer, bigIntReviver, decodeAddress, getDataBytes, networkInfo } from './utils.ts'
|
package/src/offchain.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { keccak256 } from 'ethers'
|
|
2
|
+
|
|
3
|
+
const CIRCLE_API_URL = {
|
|
4
|
+
mainnet: 'https://iris-api.circle.com/v1',
|
|
5
|
+
testnet: 'https://iris-api-sandbox.circle.com/v1',
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
type CctpAttestationResponse =
|
|
9
|
+
| { error: 'string' }
|
|
10
|
+
| { status: 'pending_confirmations' }
|
|
11
|
+
| { status: 'complete'; attestation: string }
|
|
12
|
+
|
|
13
|
+
const LOMBARD_API_URL = {
|
|
14
|
+
mainnet: 'https://mainnet.prod.lombard.finance',
|
|
15
|
+
testnet: 'https://gastald-testnet.prod.lombard.finance',
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type LombardAttestation =
|
|
19
|
+
| { status: 'NOTARIZATION_STATUS_SESSION_APPROVED'; message_hash: string; attestation: string }
|
|
20
|
+
| { status: string; message_hash: string }
|
|
21
|
+
type LombardAttestationsResponse = { attestations: Array<LombardAttestation> }
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Returns the USDC attestation for a given MessageSent Log
|
|
25
|
+
* https://developers.circle.com/stablecoins/reference/getattestation
|
|
26
|
+
*
|
|
27
|
+
* @param message - payload of USDC MessageSent(bytes message) event
|
|
28
|
+
* @param isTestnet - true if this was from a testnet
|
|
29
|
+
* @returns USDC/CCTP attestation bytes
|
|
30
|
+
*/
|
|
31
|
+
export async function getUsdcAttestation(message: string, isTestnet: boolean): Promise<string> {
|
|
32
|
+
const msgHash = keccak256(message)
|
|
33
|
+
|
|
34
|
+
const circleApiBaseUrl = isTestnet ? CIRCLE_API_URL.testnet : CIRCLE_API_URL.mainnet
|
|
35
|
+
const res = await fetch(`${circleApiBaseUrl}/attestations/${msgHash}`)
|
|
36
|
+
const json = (await res.json()) as CctpAttestationResponse
|
|
37
|
+
if (!('status' in json) || json.status !== 'complete' || !json.attestation) {
|
|
38
|
+
throw new Error('Could not fetch USDC attestation. Response: ' + JSON.stringify(json, null, 2))
|
|
39
|
+
}
|
|
40
|
+
return json.attestation
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Returns the LBTC attestation for a given payload hash
|
|
45
|
+
*
|
|
46
|
+
* @param payloadHash - hash of the payload of the LBTC transfer
|
|
47
|
+
* @param isTestnet - true if this was from a testnet
|
|
48
|
+
* @returns LBTC attestation bytes
|
|
49
|
+
*/
|
|
50
|
+
export async function getLbtcAttestation(
|
|
51
|
+
payloadHash: string,
|
|
52
|
+
isTestnet: boolean,
|
|
53
|
+
): Promise<{
|
|
54
|
+
attestation: string
|
|
55
|
+
}> {
|
|
56
|
+
const lbtcApiBaseUrl = isTestnet ? LOMBARD_API_URL.testnet : LOMBARD_API_URL.mainnet
|
|
57
|
+
const res = await fetch(`${lbtcApiBaseUrl}/api/bridge/v1/deposits/getByHash`, {
|
|
58
|
+
method: 'POST',
|
|
59
|
+
body: JSON.stringify({ messageHash: [payloadHash] }),
|
|
60
|
+
})
|
|
61
|
+
const response = (await res.json()) as LombardAttestationsResponse
|
|
62
|
+
if (response == null || !('attestations' in response)) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
'Error while fetching LBTC attestation. Response: ' + JSON.stringify(response, null, 2),
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
const attestation = response.attestations.find((att) => att.message_hash === payloadHash)
|
|
68
|
+
if (attestation == null) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
'Could not find requested LBTC attestation with hash:' +
|
|
71
|
+
payloadHash +
|
|
72
|
+
' in response: ' +
|
|
73
|
+
JSON.stringify(response, null, 2),
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
if (
|
|
77
|
+
attestation.status !== 'NOTARIZATION_STATUS_SESSION_APPROVED' ||
|
|
78
|
+
!('attestation' in attestation)
|
|
79
|
+
) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
'LBTC attestation is not approved or invalid. Response: ' +
|
|
82
|
+
JSON.stringify(attestation, null, 2),
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
return attestation
|
|
86
|
+
}
|