damm-sdk 1.4.20 → 1.4.21
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/dist/index.cjs +49086 -41257
- package/dist/index.cjs.map +121 -55
- package/dist/index.js +9734 -10808
- package/dist/index.js.map +50 -65
- package/dist/integrations/ccip/ccip.router.abi.d.ts +85 -0
- package/dist/integrations/ccip/ccip.router.abi.d.ts.map +1 -0
- package/dist/integrations/ccip/ccip.router.d.ts +72 -0
- package/dist/integrations/ccip/ccip.router.d.ts.map +1 -0
- package/dist/integrations/ccip/index.d.ts +3 -0
- package/dist/integrations/ccip/index.d.ts.map +1 -0
- package/dist/integrations/index.d.ts +1 -0
- package/dist/integrations/index.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/integrations/ccip/ccip.router.abi.ts +62 -0
- package/src/integrations/ccip/ccip.router.ts +172 -0
- package/src/integrations/ccip/index.ts +19 -0
- package/src/integrations/index.ts +1 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal ABI for Chainlink CCIP Router contract.
|
|
3
|
+
* Only includes functions needed for bridge operations.
|
|
4
|
+
*
|
|
5
|
+
* Full contract: https://etherscan.io/address/0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D
|
|
6
|
+
*/
|
|
7
|
+
declare const _default: readonly [{
|
|
8
|
+
readonly inputs: readonly [{
|
|
9
|
+
readonly name: "destinationChainSelector";
|
|
10
|
+
readonly type: "uint64";
|
|
11
|
+
}, {
|
|
12
|
+
readonly name: "message";
|
|
13
|
+
readonly type: "tuple";
|
|
14
|
+
readonly components: readonly [{
|
|
15
|
+
readonly name: "receiver";
|
|
16
|
+
readonly type: "bytes";
|
|
17
|
+
}, {
|
|
18
|
+
readonly name: "data";
|
|
19
|
+
readonly type: "bytes";
|
|
20
|
+
}, {
|
|
21
|
+
readonly name: "tokenAmounts";
|
|
22
|
+
readonly type: "tuple[]";
|
|
23
|
+
readonly components: readonly [{
|
|
24
|
+
readonly name: "token";
|
|
25
|
+
readonly type: "address";
|
|
26
|
+
}, {
|
|
27
|
+
readonly name: "amount";
|
|
28
|
+
readonly type: "uint256";
|
|
29
|
+
}];
|
|
30
|
+
}, {
|
|
31
|
+
readonly name: "feeToken";
|
|
32
|
+
readonly type: "address";
|
|
33
|
+
}, {
|
|
34
|
+
readonly name: "extraArgs";
|
|
35
|
+
readonly type: "bytes";
|
|
36
|
+
}];
|
|
37
|
+
}];
|
|
38
|
+
readonly name: "ccipSend";
|
|
39
|
+
readonly outputs: readonly [{
|
|
40
|
+
readonly name: "messageId";
|
|
41
|
+
readonly type: "bytes32";
|
|
42
|
+
}];
|
|
43
|
+
readonly stateMutability: "payable";
|
|
44
|
+
readonly type: "function";
|
|
45
|
+
}, {
|
|
46
|
+
readonly inputs: readonly [{
|
|
47
|
+
readonly name: "destinationChainSelector";
|
|
48
|
+
readonly type: "uint64";
|
|
49
|
+
}, {
|
|
50
|
+
readonly name: "message";
|
|
51
|
+
readonly type: "tuple";
|
|
52
|
+
readonly components: readonly [{
|
|
53
|
+
readonly name: "receiver";
|
|
54
|
+
readonly type: "bytes";
|
|
55
|
+
}, {
|
|
56
|
+
readonly name: "data";
|
|
57
|
+
readonly type: "bytes";
|
|
58
|
+
}, {
|
|
59
|
+
readonly name: "tokenAmounts";
|
|
60
|
+
readonly type: "tuple[]";
|
|
61
|
+
readonly components: readonly [{
|
|
62
|
+
readonly name: "token";
|
|
63
|
+
readonly type: "address";
|
|
64
|
+
}, {
|
|
65
|
+
readonly name: "amount";
|
|
66
|
+
readonly type: "uint256";
|
|
67
|
+
}];
|
|
68
|
+
}, {
|
|
69
|
+
readonly name: "feeToken";
|
|
70
|
+
readonly type: "address";
|
|
71
|
+
}, {
|
|
72
|
+
readonly name: "extraArgs";
|
|
73
|
+
readonly type: "bytes";
|
|
74
|
+
}];
|
|
75
|
+
}];
|
|
76
|
+
readonly name: "getFee";
|
|
77
|
+
readonly outputs: readonly [{
|
|
78
|
+
readonly name: "fee";
|
|
79
|
+
readonly type: "uint256";
|
|
80
|
+
}];
|
|
81
|
+
readonly stateMutability: "view";
|
|
82
|
+
readonly type: "function";
|
|
83
|
+
}];
|
|
84
|
+
export default _default;
|
|
85
|
+
//# sourceMappingURL=ccip.router.abi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ccip.router.abi.d.ts","sourceRoot":"","sources":["../../../src/integrations/ccip/ccip.router.abi.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACH,wBAuDW"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { Call, HexString, Unwrapable } from "../../types";
|
|
2
|
+
import type { Address } from "viem";
|
|
3
|
+
/**
|
|
4
|
+
* CCIP chain selectors (uint64).
|
|
5
|
+
* Source: https://docs.chain.link/ccip/directory/mainnet
|
|
6
|
+
* Verified on-chain 2026-04-13 via typeAndVersion() on each Router.
|
|
7
|
+
*/
|
|
8
|
+
export declare const CCIP_CHAIN_SELECTORS: Readonly<Record<number, string>>;
|
|
9
|
+
/**
|
|
10
|
+
* Get the CCIP chain selector for a given chain ID.
|
|
11
|
+
* @throws if the chain is not supported
|
|
12
|
+
*/
|
|
13
|
+
export declare const getCCIPChainSelector: (chainId: number) => string;
|
|
14
|
+
export type CCIPTokenAmount = Readonly<{
|
|
15
|
+
token: Address;
|
|
16
|
+
amount: bigint;
|
|
17
|
+
}>;
|
|
18
|
+
export type EVM2AnyMessage = Readonly<{
|
|
19
|
+
/** abi.encode(destinationAddress) */
|
|
20
|
+
receiver: HexString;
|
|
21
|
+
/** Empty (0x) for token-only transfers */
|
|
22
|
+
data: HexString;
|
|
23
|
+
/** Tokens to bridge */
|
|
24
|
+
tokenAmounts: readonly CCIPTokenAmount[];
|
|
25
|
+
/** address(0) = pay fee in native ETH/MON */
|
|
26
|
+
feeToken: Address;
|
|
27
|
+
/** Extra args (0x for defaults) */
|
|
28
|
+
extraArgs: HexString;
|
|
29
|
+
}>;
|
|
30
|
+
export type GetFeeArgs = Readonly<{
|
|
31
|
+
destinationChainSelector: string;
|
|
32
|
+
message: EVM2AnyMessage;
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Encode calldata for Router.getFee(destinationChainSelector, message).
|
|
36
|
+
* Use this to quote the CCIP fee via an RPC call.
|
|
37
|
+
*/
|
|
38
|
+
export declare const CCIPGetFeeCalldata: (args: GetFeeArgs) => HexString;
|
|
39
|
+
/**
|
|
40
|
+
* Build a Call for Router.getFee (read-only, value=0).
|
|
41
|
+
*/
|
|
42
|
+
export declare const CCIPGetFeeTrx: ({ routerAddress, args, }: {
|
|
43
|
+
routerAddress: Address;
|
|
44
|
+
args: GetFeeArgs;
|
|
45
|
+
}) => Unwrapable<Call>;
|
|
46
|
+
export type CCIPSendArgs = Readonly<{
|
|
47
|
+
destinationChainSelector: string;
|
|
48
|
+
message: EVM2AnyMessage;
|
|
49
|
+
/** Native fee (from getFee). The Router does NOT refund excess. */
|
|
50
|
+
nativeFee: bigint;
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Encode calldata for Router.ccipSend(destinationChainSelector, message).
|
|
54
|
+
*/
|
|
55
|
+
export declare const CCIPSendCalldata: (args: CCIPSendArgs) => HexString;
|
|
56
|
+
/**
|
|
57
|
+
* Build a Call for Router.ccipSend with msg.value = nativeFee.
|
|
58
|
+
*/
|
|
59
|
+
export declare const ccipSendTrx: ({ routerAddress, args, }: {
|
|
60
|
+
routerAddress: Address;
|
|
61
|
+
args: CCIPSendArgs;
|
|
62
|
+
}) => Unwrapable<Call>;
|
|
63
|
+
/**
|
|
64
|
+
* Build a standard EVM2AnyMessage for bridging a single token.
|
|
65
|
+
* Receiver = abi.encode(destinationAddress), feeToken = address(0) (native).
|
|
66
|
+
*/
|
|
67
|
+
export declare const buildCCIPMessage: ({ receiver, token, amount, }: {
|
|
68
|
+
receiver: Address;
|
|
69
|
+
token: Address;
|
|
70
|
+
amount: bigint;
|
|
71
|
+
}) => EVM2AnyMessage;
|
|
72
|
+
//# sourceMappingURL=ccip.router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ccip.router.d.ts","sourceRoot":"","sources":["../../../src/integrations/ccip/ccip.router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAIpC;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQhE,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,YAAa,MAAM,KAAG,MAMtD,CAAC;AAIF,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAClC,qCAAqC;IACrC,QAAQ,EAAE,SAAS,CAAC;IACpB,0CAA0C;IAC1C,IAAI,EAAE,SAAS,CAAC;IAChB,uBAAuB;IACvB,YAAY,EAAE,SAAS,eAAe,EAAE,CAAC;IACzC,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,SAAS,EAAE,SAAS,CAAC;CACxB,CAAC,CAAC;AAIH,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAC9B,wBAAwB,EAAE,MAAM,CAAC;IACjC,OAAO,EAAE,cAAc,CAAC;CAC3B,CAAC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,SAAU,UAAU,KAAG,SAcrD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa;mBAIP,OAAO;UAChB,UAAU;MAChB,WAAW,IAAI,CAOlB,CAAC;AAIF,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAChC,wBAAwB,EAAE,MAAM,CAAC;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB,SAAU,YAAY,KAAG,SAcrD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW;mBAIL,OAAO;UAChB,YAAY;MAClB,WAAW,IAAI,CAOlB,CAAC;AAIF;;;GAGG;AACH,eAAO,MAAM,gBAAgB;cAKf,OAAO;WACV,OAAO;YACN,MAAM;MACd,cAWH,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { default as CCIPRouterAbi } from "./ccip.router.abi";
|
|
2
|
+
export { CCIP_CHAIN_SELECTORS, getCCIPChainSelector, CCIPGetFeeCalldata, CCIPGetFeeTrx, CCIPSendCalldata, ccipSendTrx, buildCCIPMessage, type CCIPTokenAmount, type EVM2AnyMessage, type GetFeeArgs, type CCIPSendArgs, } from "./ccip.router";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/integrations/ccip/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAEH,oBAAoB,EACpB,oBAAoB,EAEpB,kBAAkB,EAClB,aAAa,EAEb,gBAAgB,EAChB,WAAW,EAEX,gBAAgB,EAEhB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,YAAY,GACpB,MAAM,eAAe,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/integrations/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"main": "./dist/index.cjs",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"version": "1.4.
|
|
7
|
+
"version": "1.4.21",
|
|
8
8
|
"files": [
|
|
9
9
|
"dist",
|
|
10
10
|
"src",
|
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
21
|
"build": "rm -rf ./dist && bun build ./src/index.ts --outdir ./dist --entry-naming index.js --format esm --sourcemap=external && bun build ./src/index.ts --outdir ./dist --entry-naming index.cjs --format cjs --sourcemap=external && bun tsc --project tsconfig.json",
|
|
22
|
+
"verify:dist": "bun run scripts/verify-dist.ts",
|
|
22
23
|
"fmt": "prettier --write . && forge fmt",
|
|
23
|
-
"release": "bun run fmt && bun run build && npm publish --tag latest"
|
|
24
|
+
"release": "bun run fmt && bun run build && bun run verify:dist && npm publish --tag latest"
|
|
24
25
|
},
|
|
25
26
|
"devDependencies": {
|
|
26
27
|
"@types/bun": "latest",
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal ABI for Chainlink CCIP Router contract.
|
|
3
|
+
* Only includes functions needed for bridge operations.
|
|
4
|
+
*
|
|
5
|
+
* Full contract: https://etherscan.io/address/0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D
|
|
6
|
+
*/
|
|
7
|
+
export default [
|
|
8
|
+
{
|
|
9
|
+
inputs: [
|
|
10
|
+
{ name: "destinationChainSelector", type: "uint64" },
|
|
11
|
+
{
|
|
12
|
+
name: "message",
|
|
13
|
+
type: "tuple",
|
|
14
|
+
components: [
|
|
15
|
+
{ name: "receiver", type: "bytes" },
|
|
16
|
+
{ name: "data", type: "bytes" },
|
|
17
|
+
{
|
|
18
|
+
name: "tokenAmounts",
|
|
19
|
+
type: "tuple[]",
|
|
20
|
+
components: [
|
|
21
|
+
{ name: "token", type: "address" },
|
|
22
|
+
{ name: "amount", type: "uint256" },
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
{ name: "feeToken", type: "address" },
|
|
26
|
+
{ name: "extraArgs", type: "bytes" },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
name: "ccipSend",
|
|
31
|
+
outputs: [{ name: "messageId", type: "bytes32" }],
|
|
32
|
+
stateMutability: "payable",
|
|
33
|
+
type: "function",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
inputs: [
|
|
37
|
+
{ name: "destinationChainSelector", type: "uint64" },
|
|
38
|
+
{
|
|
39
|
+
name: "message",
|
|
40
|
+
type: "tuple",
|
|
41
|
+
components: [
|
|
42
|
+
{ name: "receiver", type: "bytes" },
|
|
43
|
+
{ name: "data", type: "bytes" },
|
|
44
|
+
{
|
|
45
|
+
name: "tokenAmounts",
|
|
46
|
+
type: "tuple[]",
|
|
47
|
+
components: [
|
|
48
|
+
{ name: "token", type: "address" },
|
|
49
|
+
{ name: "amount", type: "uint256" },
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
{ name: "feeToken", type: "address" },
|
|
53
|
+
{ name: "extraArgs", type: "bytes" },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
name: "getFee",
|
|
58
|
+
outputs: [{ name: "fee", type: "uint256" }],
|
|
59
|
+
stateMutability: "view",
|
|
60
|
+
type: "function",
|
|
61
|
+
},
|
|
62
|
+
] as const;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { ethers } from "ethers";
|
|
2
|
+
import ccipRouterAbi from "./ccip.router.abi";
|
|
3
|
+
import type { Call, HexString, Unwrapable } from "../../types";
|
|
4
|
+
import { createCall } from "../../types";
|
|
5
|
+
import type { Address } from "viem";
|
|
6
|
+
|
|
7
|
+
const ccipRouterInterface = new ethers.utils.Interface(ccipRouterAbi as any);
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* CCIP chain selectors (uint64).
|
|
11
|
+
* Source: https://docs.chain.link/ccip/directory/mainnet
|
|
12
|
+
* Verified on-chain 2026-04-13 via typeAndVersion() on each Router.
|
|
13
|
+
*/
|
|
14
|
+
export const CCIP_CHAIN_SELECTORS: Readonly<Record<number, string>> = Object.freeze({
|
|
15
|
+
1: "5009297550715157269", // Mainnet
|
|
16
|
+
42161: "4949039107694359620", // Arbitrum
|
|
17
|
+
8453: "15971525489660198786", // Base
|
|
18
|
+
10: "3734403246176062136", // Optimism
|
|
19
|
+
137: "4051577828743386545", // Polygon
|
|
20
|
+
56: "11344663589394136015", // BSC
|
|
21
|
+
143: "8481857512324358265", // Monad
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get the CCIP chain selector for a given chain ID.
|
|
26
|
+
* @throws if the chain is not supported
|
|
27
|
+
*/
|
|
28
|
+
export const getCCIPChainSelector = (chainId: number): string => {
|
|
29
|
+
const selector = CCIP_CHAIN_SELECTORS[chainId];
|
|
30
|
+
if (!selector) {
|
|
31
|
+
throw new Error(`CCIP: No chain selector for chainId ${chainId}`);
|
|
32
|
+
}
|
|
33
|
+
return selector;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// ─── EVM2AnyMessage struct ───────────────────────────────────────────────
|
|
37
|
+
|
|
38
|
+
export type CCIPTokenAmount = Readonly<{
|
|
39
|
+
token: Address;
|
|
40
|
+
amount: bigint;
|
|
41
|
+
}>;
|
|
42
|
+
|
|
43
|
+
export type EVM2AnyMessage = Readonly<{
|
|
44
|
+
/** abi.encode(destinationAddress) */
|
|
45
|
+
receiver: HexString;
|
|
46
|
+
/** Empty (0x) for token-only transfers */
|
|
47
|
+
data: HexString;
|
|
48
|
+
/** Tokens to bridge */
|
|
49
|
+
tokenAmounts: readonly CCIPTokenAmount[];
|
|
50
|
+
/** address(0) = pay fee in native ETH/MON */
|
|
51
|
+
feeToken: Address;
|
|
52
|
+
/** Extra args (0x for defaults) */
|
|
53
|
+
extraArgs: HexString;
|
|
54
|
+
}>;
|
|
55
|
+
|
|
56
|
+
// ─── getFee ──────────────────────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
export type GetFeeArgs = Readonly<{
|
|
59
|
+
destinationChainSelector: string;
|
|
60
|
+
message: EVM2AnyMessage;
|
|
61
|
+
}>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Encode calldata for Router.getFee(destinationChainSelector, message).
|
|
65
|
+
* Use this to quote the CCIP fee via an RPC call.
|
|
66
|
+
*/
|
|
67
|
+
export const CCIPGetFeeCalldata = (args: GetFeeArgs): HexString => {
|
|
68
|
+
return ccipRouterInterface.encodeFunctionData("getFee", [
|
|
69
|
+
args.destinationChainSelector,
|
|
70
|
+
{
|
|
71
|
+
receiver: args.message.receiver,
|
|
72
|
+
data: args.message.data,
|
|
73
|
+
tokenAmounts: args.message.tokenAmounts.map((t) => ({
|
|
74
|
+
token: t.token,
|
|
75
|
+
amount: t.amount,
|
|
76
|
+
})),
|
|
77
|
+
feeToken: args.message.feeToken,
|
|
78
|
+
extraArgs: args.message.extraArgs,
|
|
79
|
+
},
|
|
80
|
+
]) as HexString;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Build a Call for Router.getFee (read-only, value=0).
|
|
85
|
+
*/
|
|
86
|
+
export const CCIPGetFeeTrx = ({
|
|
87
|
+
routerAddress,
|
|
88
|
+
args,
|
|
89
|
+
}: {
|
|
90
|
+
routerAddress: Address;
|
|
91
|
+
args: GetFeeArgs;
|
|
92
|
+
}): Unwrapable<Call> => {
|
|
93
|
+
return createCall({
|
|
94
|
+
operation: 0,
|
|
95
|
+
to: routerAddress,
|
|
96
|
+
data: CCIPGetFeeCalldata(args),
|
|
97
|
+
value: 0n,
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// ─── ccipSend ────────────────────────────────────────────────────────────
|
|
102
|
+
|
|
103
|
+
export type CCIPSendArgs = Readonly<{
|
|
104
|
+
destinationChainSelector: string;
|
|
105
|
+
message: EVM2AnyMessage;
|
|
106
|
+
/** Native fee (from getFee). The Router does NOT refund excess. */
|
|
107
|
+
nativeFee: bigint;
|
|
108
|
+
}>;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Encode calldata for Router.ccipSend(destinationChainSelector, message).
|
|
112
|
+
*/
|
|
113
|
+
export const CCIPSendCalldata = (args: CCIPSendArgs): HexString => {
|
|
114
|
+
return ccipRouterInterface.encodeFunctionData("ccipSend", [
|
|
115
|
+
args.destinationChainSelector,
|
|
116
|
+
{
|
|
117
|
+
receiver: args.message.receiver,
|
|
118
|
+
data: args.message.data,
|
|
119
|
+
tokenAmounts: args.message.tokenAmounts.map((t) => ({
|
|
120
|
+
token: t.token,
|
|
121
|
+
amount: t.amount,
|
|
122
|
+
})),
|
|
123
|
+
feeToken: args.message.feeToken,
|
|
124
|
+
extraArgs: args.message.extraArgs,
|
|
125
|
+
},
|
|
126
|
+
]) as HexString;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Build a Call for Router.ccipSend with msg.value = nativeFee.
|
|
131
|
+
*/
|
|
132
|
+
export const ccipSendTrx = ({
|
|
133
|
+
routerAddress,
|
|
134
|
+
args,
|
|
135
|
+
}: {
|
|
136
|
+
routerAddress: Address;
|
|
137
|
+
args: CCIPSendArgs;
|
|
138
|
+
}): Unwrapable<Call> => {
|
|
139
|
+
return createCall({
|
|
140
|
+
operation: 0,
|
|
141
|
+
to: routerAddress,
|
|
142
|
+
data: CCIPSendCalldata(args),
|
|
143
|
+
value: args.nativeFee,
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// ─── Helper: build EVM2AnyMessage for a single token bridge ──────────────
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Build a standard EVM2AnyMessage for bridging a single token.
|
|
151
|
+
* Receiver = abi.encode(destinationAddress), feeToken = address(0) (native).
|
|
152
|
+
*/
|
|
153
|
+
export const buildCCIPMessage = ({
|
|
154
|
+
receiver,
|
|
155
|
+
token,
|
|
156
|
+
amount,
|
|
157
|
+
}: {
|
|
158
|
+
receiver: Address;
|
|
159
|
+
token: Address;
|
|
160
|
+
amount: bigint;
|
|
161
|
+
}): EVM2AnyMessage => {
|
|
162
|
+
// Pad receiver to 32 bytes (abi.encode(address))
|
|
163
|
+
const receiverEncoded = ("0x" + receiver.slice(2).padStart(64, "0")) as HexString;
|
|
164
|
+
|
|
165
|
+
return Object.freeze({
|
|
166
|
+
receiver: receiverEncoded,
|
|
167
|
+
data: "0x" as HexString,
|
|
168
|
+
tokenAmounts: Object.freeze([Object.freeze({ token, amount })]),
|
|
169
|
+
feeToken: "0x0000000000000000000000000000000000000000" as Address,
|
|
170
|
+
extraArgs: "0x" as HexString,
|
|
171
|
+
});
|
|
172
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { default as CCIPRouterAbi } from "./ccip.router.abi";
|
|
2
|
+
export {
|
|
3
|
+
// Chain selectors
|
|
4
|
+
CCIP_CHAIN_SELECTORS,
|
|
5
|
+
getCCIPChainSelector,
|
|
6
|
+
// getFee
|
|
7
|
+
CCIPGetFeeCalldata,
|
|
8
|
+
CCIPGetFeeTrx,
|
|
9
|
+
// ccipSend
|
|
10
|
+
CCIPSendCalldata,
|
|
11
|
+
ccipSendTrx,
|
|
12
|
+
// Helper
|
|
13
|
+
buildCCIPMessage,
|
|
14
|
+
// Types
|
|
15
|
+
type CCIPTokenAmount,
|
|
16
|
+
type EVM2AnyMessage,
|
|
17
|
+
type GetFeeArgs,
|
|
18
|
+
type CCIPSendArgs,
|
|
19
|
+
} from "./ccip.router";
|