@chainlink/ccip-sdk 1.0.0 → 1.1.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/dist/api/index.d.ts +4 -4
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +110 -11
- package/dist/api/index.js.map +1 -1
- package/dist/api/types.d.ts +34 -0
- package/dist/api/types.d.ts.map +1 -1
- package/dist/chain.d.ts +93 -4
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js +78 -8
- package/dist/chain.js.map +1 -1
- package/dist/errors/codes.d.ts +1 -1
- package/dist/errors/codes.d.ts.map +1 -1
- package/dist/errors/codes.js +2 -1
- package/dist/errors/codes.js.map +1 -1
- package/dist/errors/index.d.ts +2 -2
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +2 -2
- package/dist/errors/index.js.map +1 -1
- package/dist/errors/recovery.js +1 -1
- package/dist/errors/recovery.js.map +1 -1
- package/dist/errors/specialized.d.ts +22 -19
- package/dist/errors/specialized.d.ts.map +1 -1
- package/dist/errors/specialized.js +30 -25
- package/dist/errors/specialized.js.map +1 -1
- package/dist/evm/abi/OffRamp_2_0.d.ts +24 -12
- package/dist/evm/abi/OffRamp_2_0.d.ts.map +1 -1
- package/dist/evm/abi/OffRamp_2_0.js +16 -8
- package/dist/evm/abi/OffRamp_2_0.js.map +1 -1
- package/dist/evm/abi/TokenPool_2_0.d.ts +1552 -0
- package/dist/evm/abi/TokenPool_2_0.d.ts.map +1 -0
- package/dist/evm/abi/TokenPool_2_0.js +1637 -0
- package/dist/evm/abi/TokenPool_2_0.js.map +1 -0
- package/dist/evm/const.d.ts +1 -0
- package/dist/evm/const.d.ts.map +1 -1
- package/dist/evm/const.js +2 -0
- package/dist/evm/const.js.map +1 -1
- package/dist/evm/index.d.ts +10 -4
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +138 -41
- package/dist/evm/index.js.map +1 -1
- package/dist/evm/messages.d.ts +2 -33
- package/dist/evm/messages.d.ts.map +1 -1
- package/dist/evm/messages.js +0 -210
- package/dist/evm/messages.js.map +1 -1
- package/dist/gas.d.ts +4 -0
- package/dist/gas.d.ts.map +1 -1
- package/dist/gas.js +27 -21
- package/dist/gas.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/messages.d.ts +34 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +211 -0
- package/dist/messages.js.map +1 -0
- package/dist/solana/cleanup.js +2 -2
- package/dist/solana/cleanup.js.map +1 -1
- package/dist/solana/exec.js +1 -1
- package/dist/solana/exec.js.map +1 -1
- package/dist/solana/index.d.ts +19 -19
- package/dist/solana/index.d.ts.map +1 -1
- package/dist/solana/index.js +14 -0
- package/dist/solana/index.js.map +1 -1
- package/dist/sui/index.d.ts.map +1 -1
- package/dist/sui/index.js +14 -1
- package/dist/sui/index.js.map +1 -1
- package/dist/ton/index.d.ts.map +1 -1
- package/dist/ton/index.js +3 -1
- package/dist/ton/index.js.map +1 -1
- package/package.json +5 -5
- package/src/api/index.ts +126 -11
- package/src/api/types.ts +43 -0
- package/src/chain.ts +131 -11
- package/src/errors/codes.ts +2 -1
- package/src/errors/index.ts +1 -1
- package/src/errors/recovery.ts +1 -1
- package/src/errors/specialized.ts +35 -30
- package/src/evm/abi/OffRamp_2_0.ts +16 -8
- package/src/evm/abi/TokenPool_2_0.ts +1636 -0
- package/src/evm/const.ts +2 -0
- package/src/evm/index.ts +230 -75
- package/src/evm/messages.ts +3 -285
- package/src/gas.ts +27 -19
- package/src/index.ts +2 -1
- package/src/messages.ts +278 -0
- package/src/solana/cleanup.ts +2 -2
- package/src/solana/exec.ts +1 -1
- package/src/solana/index.ts +17 -0
- package/src/sui/index.ts +17 -0
- package/src/ton/index.ts +5 -1
package/src/evm/const.ts
CHANGED
|
@@ -19,6 +19,7 @@ import OnRamp_2_0_ABI from './abi/OnRamp_2_0.ts'
|
|
|
19
19
|
import PriceRegistry_1_2_ABI from './abi/PriceRegistry_1_2.ts'
|
|
20
20
|
import Router_ABI from './abi/Router.ts'
|
|
21
21
|
import TokenAdminRegistry_ABI from './abi/TokenAdminRegistry_1_5.ts'
|
|
22
|
+
import TokenPool_2_0_ABI from './abi/TokenPool_2_0.ts'
|
|
22
23
|
|
|
23
24
|
export const defaultAbiCoder = AbiCoder.defaultAbiCoder()
|
|
24
25
|
|
|
@@ -38,6 +39,7 @@ export const interfaces = {
|
|
|
38
39
|
FeeQuoter: new Interface(FeeQuoter_ABI),
|
|
39
40
|
TokenPool_v1_5_1: new Interface(TokenPool_1_5_1_ABI),
|
|
40
41
|
TokenPool_v1_5: new Interface(TokenPool_1_5_ABI),
|
|
42
|
+
TokenPool_v2_0: new Interface(TokenPool_2_0_ABI),
|
|
41
43
|
TokenPool_v1_6: new Interface(TokenPool_1_6_ABI),
|
|
42
44
|
CommitStore_v1_5: new Interface(CommitStore_1_5_ABI),
|
|
43
45
|
CommitStore_v1_2: new Interface(CommitStore_1_2_ABI),
|
package/src/evm/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
getAddress,
|
|
16
16
|
hexlify,
|
|
17
17
|
isBytesLike,
|
|
18
|
+
isError,
|
|
18
19
|
isHexString,
|
|
19
20
|
keccak256,
|
|
20
21
|
toBeHex,
|
|
@@ -27,9 +28,12 @@ import type { PickDeep, SetRequired } from 'type-fest'
|
|
|
27
28
|
import {
|
|
28
29
|
type ChainContext,
|
|
29
30
|
type GetBalanceOpts,
|
|
31
|
+
type LaneFeatures,
|
|
30
32
|
type LogFilter,
|
|
33
|
+
type RateLimiterState,
|
|
31
34
|
type TokenPoolRemote,
|
|
32
35
|
Chain,
|
|
36
|
+
LaneFeature,
|
|
33
37
|
} from '../chain.ts'
|
|
34
38
|
import {
|
|
35
39
|
CCIPAddressInvalidEvmError,
|
|
@@ -38,11 +42,11 @@ import {
|
|
|
38
42
|
CCIPContractNotRouterError,
|
|
39
43
|
CCIPContractTypeInvalidError,
|
|
40
44
|
CCIPDataFormatUnsupportedError,
|
|
45
|
+
CCIPError,
|
|
41
46
|
CCIPExecTxNotConfirmedError,
|
|
42
47
|
CCIPExecTxRevertedError,
|
|
43
48
|
CCIPHasherVersionUnsupportedError,
|
|
44
49
|
CCIPLogDataInvalidError,
|
|
45
|
-
CCIPNotImplementedError,
|
|
46
50
|
CCIPSourceChainUnsupportedError,
|
|
47
51
|
CCIPTokenNotConfiguredError,
|
|
48
52
|
CCIPTokenPoolChainConfigNotFoundError,
|
|
@@ -95,6 +99,7 @@ import type OnRamp_1_6_ABI from './abi/OnRamp_1_6.ts'
|
|
|
95
99
|
import type OnRamp_2_0_ABI from './abi/OnRamp_2_0.ts'
|
|
96
100
|
import type Router_ABI from './abi/Router.ts'
|
|
97
101
|
import type TokenAdminRegistry_1_5_ABI from './abi/TokenAdminRegistry_1_5.ts'
|
|
102
|
+
import type TokenPool_2_0_ABI from './abi/TokenPool_2_0.ts'
|
|
98
103
|
import {
|
|
99
104
|
CCV_INDEXER_URL,
|
|
100
105
|
VersionedContractABI,
|
|
@@ -111,21 +116,21 @@ import {
|
|
|
111
116
|
import { estimateExecGas } from './gas.ts'
|
|
112
117
|
import { getV12LeafHasher, getV16LeafHasher } from './hasher.ts'
|
|
113
118
|
import { getEvmLogs } from './logs.ts'
|
|
114
|
-
import {
|
|
115
|
-
type CCIPMessage_V1_6_EVM,
|
|
116
|
-
type CCIPMessage_V2_0,
|
|
117
|
-
type CleanAddressable,
|
|
118
|
-
type MessageV1,
|
|
119
|
-
type TokenTransferV1,
|
|
120
|
-
decodeMessageV1,
|
|
121
|
-
} from './messages.ts'
|
|
122
|
-
export { decodeMessageV1 }
|
|
123
|
-
export type { MessageV1, TokenTransferV1 }
|
|
119
|
+
import type { CCIPMessage_V1_6_EVM, CCIPMessage_V2_0, CleanAddressable } from './messages.ts'
|
|
124
120
|
import { encodeEVMOffchainTokenData } from './offchain.ts'
|
|
125
121
|
import { buildMessageForDest, decodeMessage, getMessagesInBatch } from '../requests.ts'
|
|
126
122
|
import { type UnsignedEVMTx, resultToObject } from './types.ts'
|
|
123
|
+
import { decodeMessageV1 } from '../messages.ts'
|
|
127
124
|
export type { UnsignedEVMTx }
|
|
128
125
|
|
|
126
|
+
/** Raw on-chain TokenBucket struct returned by TokenPool rate limiter queries. */
|
|
127
|
+
type RateLimiterBucket = { tokens: bigint; isEnabled: boolean; capacity: bigint; rate: bigint }
|
|
128
|
+
|
|
129
|
+
/** Converts an on-chain bucket to the public RateLimiterState, stripping `isEnabled`. */
|
|
130
|
+
function toRateLimiterState(b: RateLimiterBucket): RateLimiterState {
|
|
131
|
+
return b.isEnabled ? { tokens: b.tokens, capacity: b.capacity, rate: b.rate } : null
|
|
132
|
+
}
|
|
133
|
+
|
|
129
134
|
/** typeguard for ethers Signer interface (used for `wallet`s) */
|
|
130
135
|
function isSigner(wallet: unknown): wallet is Signer {
|
|
131
136
|
return (
|
|
@@ -625,6 +630,45 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
625
630
|
}
|
|
626
631
|
}
|
|
627
632
|
|
|
633
|
+
/**
|
|
634
|
+
* {@inheritDoc Chain.getLaneFeatures}
|
|
635
|
+
*/
|
|
636
|
+
override async getLaneFeatures(opts: {
|
|
637
|
+
router: string
|
|
638
|
+
destChainSelector: bigint
|
|
639
|
+
token?: string
|
|
640
|
+
}): Promise<Partial<LaneFeatures>> {
|
|
641
|
+
const onRamp = await this.getOnRampForRouter(opts.router, opts.destChainSelector)
|
|
642
|
+
const [, version] = await this.typeAndVersion(onRamp)
|
|
643
|
+
|
|
644
|
+
const result: Partial<LaneFeatures> = {}
|
|
645
|
+
|
|
646
|
+
// default FTF value for V2_0+ lanes if no token/pool or pool doesn't specify
|
|
647
|
+
if (version >= CCIPVersion.V2_0) result[LaneFeature.MIN_BLOCK_CONFIRMATIONS] = 1
|
|
648
|
+
|
|
649
|
+
// MIN_BLOCK_CONFIRMATIONS — V2_0+ only
|
|
650
|
+
if (opts.token) {
|
|
651
|
+
const { tokenPool } = await this.getRegistryTokenConfig(
|
|
652
|
+
await this.getTokenAdminRegistryFor(onRamp),
|
|
653
|
+
opts.token,
|
|
654
|
+
)
|
|
655
|
+
if (tokenPool) {
|
|
656
|
+
const { minBlockConfirmations } = await this.getTokenPoolConfig(tokenPool)
|
|
657
|
+
if (minBlockConfirmations != null)
|
|
658
|
+
result[LaneFeature.MIN_BLOCK_CONFIRMATIONS] = minBlockConfirmations
|
|
659
|
+
|
|
660
|
+
const remote = await this.getTokenPoolRemote(tokenPool, opts.destChainSelector)
|
|
661
|
+
result[LaneFeature.RATE_LIMITS] = remote.outboundRateLimiterState
|
|
662
|
+
if (minBlockConfirmations && 'customBlockConfirmationsOutboundRateLimiterState' in remote) {
|
|
663
|
+
result[LaneFeature.CUSTOM_BLOCK_CONFIRMATIONS_RATE_LIMITS] =
|
|
664
|
+
remote.customBlockConfirmationsOutboundRateLimiterState
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
return result
|
|
670
|
+
}
|
|
671
|
+
|
|
628
672
|
/**
|
|
629
673
|
* {@inheritDoc Chain.getRouterForOffRamp}
|
|
630
674
|
* @throws {@link CCIPVersionUnsupportedError} if OffRamp version is not supported
|
|
@@ -887,11 +931,22 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
887
931
|
? type.includes('OnRamp')
|
|
888
932
|
? interfaces.EVM2EVMOnRamp_v1_5
|
|
889
933
|
: interfaces.EVM2EVMOffRamp_v1_5
|
|
890
|
-
:
|
|
891
|
-
?
|
|
892
|
-
|
|
934
|
+
: version < CCIPVersion.V2_0
|
|
935
|
+
? type.includes('OnRamp')
|
|
936
|
+
? interfaces.OnRamp_v1_6
|
|
937
|
+
: interfaces.OffRamp_v1_6
|
|
938
|
+
: type.includes('OnRamp')
|
|
939
|
+
? interfaces.OnRamp_v2_0
|
|
940
|
+
: interfaces.OffRamp_v2_0,
|
|
893
941
|
this.provider,
|
|
894
|
-
) as unknown as TypedContract<
|
|
942
|
+
) as unknown as TypedContract<
|
|
943
|
+
| typeof EVM2EVMOnRamp_1_5_ABI
|
|
944
|
+
| typeof EVM2EVMOffRamp_1_5_ABI
|
|
945
|
+
| typeof OnRamp_1_6_ABI
|
|
946
|
+
| typeof OffRamp_1_6_ABI
|
|
947
|
+
| typeof OnRamp_2_0_ABI
|
|
948
|
+
| typeof OffRamp_2_0_ABI
|
|
949
|
+
>
|
|
895
950
|
const { tokenAdminRegistry } = await contract.getStaticConfig()
|
|
896
951
|
return tokenAdminRegistry as string
|
|
897
952
|
}
|
|
@@ -975,10 +1030,12 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
975
1030
|
)
|
|
976
1031
|
|
|
977
1032
|
// make sure to approve once per token, for the total amount (including fee, if needed)
|
|
978
|
-
const amountsToApprove = (message.tokenAmounts ?? [])
|
|
979
|
-
(
|
|
980
|
-
|
|
981
|
-
|
|
1033
|
+
const amountsToApprove = (message.tokenAmounts ?? [])
|
|
1034
|
+
.filter(({ token }) => token && token !== ZeroAddress)
|
|
1035
|
+
.reduce(
|
|
1036
|
+
(acc, { token, amount }) => ({ ...acc, [token]: (acc[token] ?? 0n) + amount }),
|
|
1037
|
+
{} as { [token: string]: bigint },
|
|
1038
|
+
)
|
|
982
1039
|
if (feeToken !== ZeroAddress)
|
|
983
1040
|
amountsToApprove[feeToken] = (amountsToApprove[feeToken] ?? 0n) + message.fee
|
|
984
1041
|
|
|
@@ -992,7 +1049,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
992
1049
|
) as unknown as TypedContract<typeof Token_ABI>
|
|
993
1050
|
const allowance = await contract.allowance(sender, router)
|
|
994
1051
|
if (allowance >= amount) return
|
|
995
|
-
const amnt = opts.approveMax ?
|
|
1052
|
+
const amnt = opts.approveMax ? BigInt(2) ** BigInt(256) - BigInt(1) : amount
|
|
996
1053
|
return contract.approve.populateTransaction(router, amnt, { from: sender })
|
|
997
1054
|
}),
|
|
998
1055
|
)
|
|
@@ -1003,6 +1060,13 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1003
1060
|
interfaces.Router,
|
|
1004
1061
|
this.provider,
|
|
1005
1062
|
) as unknown as TypedContract<typeof Router_ABI>
|
|
1063
|
+
|
|
1064
|
+
// if `token` is ZeroAddress, send its `amount` as `value` to router/EtherSenderReceiver (plus possibly native fee)
|
|
1065
|
+
// if native fee, include it in value; otherwise, it's transferedFrom feeToken
|
|
1066
|
+
const value = (message.tokenAmounts ?? [])
|
|
1067
|
+
.filter(({ token }) => token === ZeroAddress)
|
|
1068
|
+
.reduce((acc, { amount }) => acc + amount, feeToken === ZeroAddress ? message.fee : 0n)
|
|
1069
|
+
|
|
1006
1070
|
const sendTx = await contract.ccipSend.populateTransaction(
|
|
1007
1071
|
destChainSelector,
|
|
1008
1072
|
{
|
|
@@ -1012,11 +1076,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1012
1076
|
extraArgs,
|
|
1013
1077
|
feeToken,
|
|
1014
1078
|
},
|
|
1015
|
-
{
|
|
1016
|
-
from: sender,
|
|
1017
|
-
// if native fee, include it in value; otherwise, it's transferedFrom feeToken
|
|
1018
|
-
...(feeToken === ZeroAddress && { value: message.fee }),
|
|
1019
|
-
},
|
|
1079
|
+
{ from: sender, ...(value > 0n ? { value } : {}) },
|
|
1020
1080
|
)
|
|
1021
1081
|
const txRequests = [...approveTxs, sendTx] as SetRequired<typeof sendTx, 'from'>[]
|
|
1022
1082
|
return {
|
|
@@ -1100,6 +1160,13 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1100
1160
|
const txGasLimit = await contract.executeSingleMessage.estimateGas(
|
|
1101
1161
|
{
|
|
1102
1162
|
...message,
|
|
1163
|
+
onRampAddress: zeroPadValue(getAddressBytes(message.onRampAddress), 32),
|
|
1164
|
+
sender: zeroPadValue(getAddressBytes(message.sender), 32),
|
|
1165
|
+
tokenTransfer: message.tokenTransfer.map((ta) => ({
|
|
1166
|
+
...ta,
|
|
1167
|
+
sourcePoolAddress: zeroPadValue(getAddressBytes(ta.sourcePoolAddress), 32),
|
|
1168
|
+
sourceTokenAddress: zeroPadValue(getAddressBytes(ta.sourceTokenAddress), 32),
|
|
1169
|
+
})),
|
|
1103
1170
|
executionGasLimit: BigInt(message.executionGasLimit),
|
|
1104
1171
|
ccipReceiveGasLimit: BigInt(message.ccipReceiveGasLimit),
|
|
1105
1172
|
finality: BigInt(message.finality),
|
|
@@ -1226,6 +1293,22 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1226
1293
|
default:
|
|
1227
1294
|
throw new CCIPVersionUnsupportedError(version)
|
|
1228
1295
|
}
|
|
1296
|
+
|
|
1297
|
+
/* Executing a message for the first time has some hard try/catches on-chain
|
|
1298
|
+
* so we need to ensure some lower-bounds gasLimits */
|
|
1299
|
+
let gasLimit = await this.provider.estimateGas(manualExecTx)
|
|
1300
|
+
if (
|
|
1301
|
+
'gasLimit' in input.message &&
|
|
1302
|
+
input.message.gasLimit &&
|
|
1303
|
+
gasLimit < input.message.gasLimit + 100000n
|
|
1304
|
+
)
|
|
1305
|
+
// if message requested gasLimit, ensure execution more than 100k above requested, otherwise it's clearly a try/catch fail
|
|
1306
|
+
gasLimit = BigInt(input.message.gasLimit) + 200000n
|
|
1307
|
+
else if ('gasLimit' in input.message && !input.message.gasLimit && gasLimit < 240000n)
|
|
1308
|
+
// if message didn't request gasLimit, ensure execution gasLimit is above 240k (empiric)
|
|
1309
|
+
gasLimit = 240000n
|
|
1310
|
+
manualExecTx.gasLimit = gasLimit
|
|
1311
|
+
|
|
1229
1312
|
return { family: ChainFamily.EVM, transactions: [manualExecTx] }
|
|
1230
1313
|
}
|
|
1231
1314
|
|
|
@@ -1252,7 +1335,8 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1252
1335
|
const response = await submitTransaction(wallet, populatedTx, this.provider)
|
|
1253
1336
|
this.logger.debug('manuallyExecute =>', response.hash)
|
|
1254
1337
|
|
|
1255
|
-
|
|
1338
|
+
let receipt = await response.wait(0)
|
|
1339
|
+
if (!receipt) receipt = await response.wait(1, 240_000)
|
|
1256
1340
|
if (!receipt?.hash) throw new CCIPExecTxNotConfirmedError(response.hash)
|
|
1257
1341
|
if (!receipt.status) throw new CCIPExecTxRevertedError(response.hash)
|
|
1258
1342
|
const tx = await this.getTransaction(receipt)
|
|
@@ -1328,24 +1412,44 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1328
1412
|
token: string
|
|
1329
1413
|
router: string
|
|
1330
1414
|
typeAndVersion: string
|
|
1415
|
+
minBlockConfirmations?: number
|
|
1331
1416
|
}> {
|
|
1332
|
-
const [_, , typeAndVersion] = await this.typeAndVersion(tokenPool)
|
|
1333
|
-
|
|
1334
|
-
const contract = new Contract(
|
|
1335
|
-
tokenPool,
|
|
1336
|
-
interfaces.TokenPool_v1_6,
|
|
1337
|
-
this.provider,
|
|
1338
|
-
) as unknown as TypedContract<typeof TokenPool_ABI>
|
|
1417
|
+
const [_, version, typeAndVersion] = await this.typeAndVersion(tokenPool)
|
|
1339
1418
|
|
|
1419
|
+
let contract, router, minBlockConfirmations
|
|
1420
|
+
if (version < CCIPVersion.V2_0) {
|
|
1421
|
+
contract = new Contract(
|
|
1422
|
+
tokenPool,
|
|
1423
|
+
interfaces.TokenPool_v1_6,
|
|
1424
|
+
this.provider,
|
|
1425
|
+
) as unknown as TypedContract<typeof TokenPool_ABI>
|
|
1426
|
+
router = contract.getRouter()
|
|
1427
|
+
} else {
|
|
1428
|
+
contract = new Contract(
|
|
1429
|
+
tokenPool,
|
|
1430
|
+
interfaces.TokenPool_v2_0,
|
|
1431
|
+
this.provider,
|
|
1432
|
+
) as unknown as TypedContract<typeof TokenPool_2_0_ABI>
|
|
1433
|
+
router = contract.getDynamicConfig().then(([router]) => router)
|
|
1434
|
+
minBlockConfirmations = contract.getMinBlockConfirmations().catch((err) => {
|
|
1435
|
+
if (isError(err, 'CALL_EXCEPTION')) return 0
|
|
1436
|
+
throw CCIPError.from(err)
|
|
1437
|
+
})
|
|
1438
|
+
}
|
|
1340
1439
|
const token = contract.getToken()
|
|
1341
|
-
|
|
1342
|
-
return Promise.all([token, router]).then(
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1440
|
+
|
|
1441
|
+
return Promise.all([token, router, minBlockConfirmations]).then(
|
|
1442
|
+
([token, router, minBlockConfirmations]) => {
|
|
1443
|
+
return {
|
|
1444
|
+
token: token as CleanAddressable<typeof token>,
|
|
1445
|
+
router: router as CleanAddressable<typeof router>,
|
|
1446
|
+
typeAndVersion,
|
|
1447
|
+
...(minBlockConfirmations != null && {
|
|
1448
|
+
minBlockConfirmations: Number(minBlockConfirmations),
|
|
1449
|
+
}),
|
|
1450
|
+
}
|
|
1451
|
+
},
|
|
1452
|
+
)
|
|
1349
1453
|
}
|
|
1350
1454
|
|
|
1351
1455
|
/** {@inheritDoc Chain.getTokenPoolRemotes} */
|
|
@@ -1359,53 +1463,93 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1359
1463
|
if (remoteChainSelector) supportedChains = Promise.resolve([networkInfo(remoteChainSelector)])
|
|
1360
1464
|
|
|
1361
1465
|
let remotePools: Promise<string[][]>
|
|
1362
|
-
let
|
|
1466
|
+
let remoteInfo
|
|
1363
1467
|
if (version < '1.5.1') {
|
|
1364
|
-
const
|
|
1468
|
+
const contract = new Contract(
|
|
1365
1469
|
tokenPool,
|
|
1366
1470
|
interfaces.TokenPool_v1_5,
|
|
1367
1471
|
this.provider,
|
|
1368
1472
|
) as unknown as TypedContract<typeof TokenPool_1_5_ABI>
|
|
1369
|
-
contract = contract_
|
|
1370
1473
|
supportedChains ??= contract.getSupportedChains().then((chains) => chains.map(networkInfo))
|
|
1371
1474
|
remotePools = supportedChains.then((chains) =>
|
|
1372
1475
|
Promise.all(
|
|
1373
1476
|
chains.map((chain) =>
|
|
1374
|
-
|
|
1477
|
+
contract
|
|
1375
1478
|
.getRemotePool(chain.chainSelector)
|
|
1376
1479
|
.then((remotePool) => [decodeAddress(remotePool, chain.family)]),
|
|
1377
1480
|
),
|
|
1378
1481
|
),
|
|
1379
1482
|
)
|
|
1380
|
-
|
|
1381
|
-
|
|
1483
|
+
remoteInfo = supportedChains.then((chains) =>
|
|
1484
|
+
Promise.all(
|
|
1485
|
+
chains.map((chain) =>
|
|
1486
|
+
Promise.all([
|
|
1487
|
+
contract.getRemoteToken(chain.chainSelector),
|
|
1488
|
+
resultToObject(contract.getCurrentOutboundRateLimiterState(chain.chainSelector)),
|
|
1489
|
+
resultToObject(contract.getCurrentInboundRateLimiterState(chain.chainSelector)),
|
|
1490
|
+
] as const),
|
|
1491
|
+
),
|
|
1492
|
+
),
|
|
1493
|
+
)
|
|
1494
|
+
} else if (version < CCIPVersion.V2_0) {
|
|
1495
|
+
const contract = new Contract(
|
|
1382
1496
|
tokenPool,
|
|
1383
1497
|
interfaces.TokenPool_v1_6,
|
|
1384
1498
|
this.provider,
|
|
1385
1499
|
) as unknown as TypedContract<typeof TokenPool_ABI>
|
|
1386
|
-
contract = contract_
|
|
1387
1500
|
supportedChains ??= contract.getSupportedChains().then((chains) => chains.map(networkInfo))
|
|
1388
1501
|
remotePools = supportedChains.then((chains) =>
|
|
1389
1502
|
Promise.all(
|
|
1390
1503
|
chains.map((chain) =>
|
|
1391
|
-
|
|
1504
|
+
contract
|
|
1392
1505
|
.getRemotePools(chain.chainSelector)
|
|
1393
1506
|
.then((pools) => pools.map((remotePool) => decodeAddress(remotePool, chain.family))),
|
|
1394
1507
|
),
|
|
1395
1508
|
),
|
|
1396
1509
|
)
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1510
|
+
remoteInfo = supportedChains.then((chains) =>
|
|
1511
|
+
Promise.all(
|
|
1512
|
+
chains.map((chain) =>
|
|
1513
|
+
Promise.all([
|
|
1514
|
+
contract.getRemoteToken(chain.chainSelector),
|
|
1515
|
+
resultToObject(contract.getCurrentOutboundRateLimiterState(chain.chainSelector)),
|
|
1516
|
+
resultToObject(contract.getCurrentInboundRateLimiterState(chain.chainSelector)),
|
|
1517
|
+
] as const),
|
|
1518
|
+
),
|
|
1406
1519
|
),
|
|
1407
|
-
)
|
|
1408
|
-
|
|
1520
|
+
)
|
|
1521
|
+
} else {
|
|
1522
|
+
const contract = new Contract(
|
|
1523
|
+
tokenPool,
|
|
1524
|
+
interfaces.TokenPool_v2_0,
|
|
1525
|
+
this.provider,
|
|
1526
|
+
) as unknown as TypedContract<typeof TokenPool_2_0_ABI>
|
|
1527
|
+
supportedChains ??= contract.getSupportedChains().then((chains) => chains.map(networkInfo))
|
|
1528
|
+
remotePools = supportedChains.then((chains) =>
|
|
1529
|
+
Promise.all(
|
|
1530
|
+
chains.map((chain) =>
|
|
1531
|
+
contract
|
|
1532
|
+
.getRemotePools(chain.chainSelector)
|
|
1533
|
+
.then((pools) => pools.map((remotePool) => decodeAddress(remotePool, chain.family))),
|
|
1534
|
+
),
|
|
1535
|
+
),
|
|
1536
|
+
)
|
|
1537
|
+
remoteInfo = supportedChains.then((chains) =>
|
|
1538
|
+
Promise.all(
|
|
1539
|
+
chains.map((chain) =>
|
|
1540
|
+
Promise.all([
|
|
1541
|
+
contract.getRemoteToken(chain.chainSelector),
|
|
1542
|
+
contract.getCurrentRateLimiterState(chain.chainSelector, false),
|
|
1543
|
+
contract.getCurrentRateLimiterState(chain.chainSelector, true),
|
|
1544
|
+
] as const).then(
|
|
1545
|
+
([remoteToken, [outbound, inbound], [customOutbound, customInbound]]) => {
|
|
1546
|
+
return [remoteToken, outbound, inbound, customOutbound, customInbound] as const
|
|
1547
|
+
},
|
|
1548
|
+
),
|
|
1549
|
+
),
|
|
1550
|
+
),
|
|
1551
|
+
)
|
|
1552
|
+
}
|
|
1409
1553
|
return Promise.all([supportedChains, remotePools, remoteInfo]).then(
|
|
1410
1554
|
([supportedChains, remotePools, remoteInfo]) =>
|
|
1411
1555
|
Object.fromEntries(
|
|
@@ -1418,8 +1562,16 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1418
1562
|
{
|
|
1419
1563
|
remoteToken: decodeAddress(remoteTokenRaw, chain.family),
|
|
1420
1564
|
remotePools: remotePools[i]!.map((pool) => decodeAddress(pool, chain.family)),
|
|
1421
|
-
|
|
1422
|
-
|
|
1565
|
+
outboundRateLimiterState: toRateLimiterState(remoteInfo[i]![1]),
|
|
1566
|
+
inboundRateLimiterState: toRateLimiterState(remoteInfo[i]![2]),
|
|
1567
|
+
...(remoteInfo[i]!.length === 5 && {
|
|
1568
|
+
customBlockConfirmationsOutboundRateLimiterState: toRateLimiterState(
|
|
1569
|
+
remoteInfo[i]![3],
|
|
1570
|
+
),
|
|
1571
|
+
customBlockConfirmationsInboundRateLimiterState: toRateLimiterState(
|
|
1572
|
+
remoteInfo[i]![4],
|
|
1573
|
+
),
|
|
1574
|
+
}),
|
|
1423
1575
|
},
|
|
1424
1576
|
] as const
|
|
1425
1577
|
}),
|
|
@@ -1461,7 +1613,8 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1461
1613
|
tokens = Array.from(tokens_)
|
|
1462
1614
|
break
|
|
1463
1615
|
}
|
|
1464
|
-
case CCIPVersion.V1_6:
|
|
1616
|
+
case CCIPVersion.V1_6:
|
|
1617
|
+
case CCIPVersion.V2_0: {
|
|
1465
1618
|
const feeQuoter = await this.getFeeQuoterFor(onRamp)
|
|
1466
1619
|
const contract = new Contract(
|
|
1467
1620
|
feeQuoter,
|
|
@@ -1489,15 +1642,13 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1489
1642
|
): Promise<CCIPVerifications> {
|
|
1490
1643
|
const { offRamp, request } = opts
|
|
1491
1644
|
if (request.lane.version >= CCIPVersion.V2_0) {
|
|
1492
|
-
const
|
|
1493
|
-
if (!message.encodedMessage)
|
|
1494
|
-
throw new CCIPNotImplementedError(`CCIPAPIClient getMessageById v2 encodedMessage`)
|
|
1645
|
+
const { encodedMessage } = request.message as CCIPMessage_V2_0
|
|
1495
1646
|
const contract = new Contract(
|
|
1496
1647
|
offRamp,
|
|
1497
1648
|
interfaces.OffRamp_v2_0,
|
|
1498
1649
|
this.provider,
|
|
1499
1650
|
) as unknown as TypedContract<typeof OffRamp_2_0_ABI>
|
|
1500
|
-
const ccvs = await contract.getCCVsForMessage(
|
|
1651
|
+
const ccvs = await contract.getCCVsForMessage(encodedMessage)
|
|
1501
1652
|
const [requiredCCVs, optionalCCVs, optionalThreshold] = ccvs.map(
|
|
1502
1653
|
resultToObject,
|
|
1503
1654
|
) as unknown as CleanAddressable<typeof ccvs>
|
|
@@ -1511,20 +1662,24 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1511
1662
|
const apiRes = await this.apiClient.getMessageById(request.message.messageId)
|
|
1512
1663
|
if ('verifiers' in apiRes.message) {
|
|
1513
1664
|
const verifiers = apiRes.message.verifiers as {
|
|
1514
|
-
items
|
|
1665
|
+
items?: {
|
|
1515
1666
|
destAddress: string
|
|
1516
1667
|
sourceAddress: string
|
|
1517
|
-
verification
|
|
1668
|
+
verification?: { data: string; timestamp: string }
|
|
1518
1669
|
}[]
|
|
1519
1670
|
}
|
|
1520
1671
|
return {
|
|
1521
1672
|
verificationPolicy,
|
|
1522
|
-
verifications: verifiers.items
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1673
|
+
verifications: (verifiers.items ?? [])
|
|
1674
|
+
.filter((item) => item.verification?.data)
|
|
1675
|
+
.map((item) => ({
|
|
1676
|
+
destAddress: item.destAddress,
|
|
1677
|
+
sourceAddress: item.sourceAddress,
|
|
1678
|
+
ccvData: item.verification!.data,
|
|
1679
|
+
...(!!item.verification?.timestamp && {
|
|
1680
|
+
timestamp: new Date(item.verification.timestamp).getTime() / 1e3,
|
|
1681
|
+
}),
|
|
1682
|
+
})),
|
|
1528
1683
|
}
|
|
1529
1684
|
}
|
|
1530
1685
|
}
|