@chainlink/ccip-sdk 1.0.0 → 1.1.1
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/aptos/index.d.ts.map +1 -1
- package/dist/aptos/index.js +5 -5
- package/dist/aptos/index.js.map +1 -1
- package/dist/chain.d.ts +109 -5
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js +96 -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 +139 -51
- 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 +3 -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 +17 -2
- package/dist/solana/index.js.map +1 -1
- package/dist/sui/exec.d.ts +30 -0
- package/dist/sui/exec.d.ts.map +1 -0
- package/dist/sui/exec.js +92 -0
- package/dist/sui/exec.js.map +1 -0
- package/dist/sui/index.d.ts +7 -2
- package/dist/sui/index.d.ts.map +1 -1
- package/dist/sui/index.js +36 -65
- package/dist/sui/index.js.map +1 -1
- package/dist/sui/manuallyExec/index.d.ts.map +1 -1
- package/dist/sui/manuallyExec/index.js +10 -13
- package/dist/sui/manuallyExec/index.js.map +1 -1
- package/dist/sui/objects.d.ts.map +1 -1
- package/dist/sui/objects.js +4 -2
- package/dist/sui/objects.js.map +1 -1
- package/dist/sui/types.d.ts +9 -1
- package/dist/sui/types.d.ts.map +1 -1
- package/dist/sui/types.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/aptos/index.ts +7 -9
- package/src/chain.ts +152 -12
- 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 +231 -84
- package/src/evm/messages.ts +3 -285
- package/src/gas.ts +27 -19
- package/src/index.ts +3 -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 +20 -2
- package/src/sui/exec.ts +131 -0
- package/src/sui/index.ts +50 -98
- package/src/sui/manuallyExec/index.ts +11 -17
- package/src/sui/objects.ts +4 -2
- package/src/sui/types.ts +10 -1
- 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,22 +28,24 @@ 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,
|
|
36
|
-
CCIPApiClientNotAvailableError,
|
|
37
40
|
CCIPBlockNotFoundError,
|
|
38
41
|
CCIPContractNotRouterError,
|
|
39
42
|
CCIPContractTypeInvalidError,
|
|
40
43
|
CCIPDataFormatUnsupportedError,
|
|
44
|
+
CCIPError,
|
|
41
45
|
CCIPExecTxNotConfirmedError,
|
|
42
46
|
CCIPExecTxRevertedError,
|
|
43
47
|
CCIPHasherVersionUnsupportedError,
|
|
44
48
|
CCIPLogDataInvalidError,
|
|
45
|
-
CCIPNotImplementedError,
|
|
46
49
|
CCIPSourceChainUnsupportedError,
|
|
47
50
|
CCIPTokenNotConfiguredError,
|
|
48
51
|
CCIPTokenPoolChainConfigNotFoundError,
|
|
@@ -63,7 +66,6 @@ import {
|
|
|
63
66
|
type ChainLog,
|
|
64
67
|
type ChainTransaction,
|
|
65
68
|
type CommitReport,
|
|
66
|
-
type ExecutionInput,
|
|
67
69
|
type ExecutionReceipt,
|
|
68
70
|
type ExecutionState,
|
|
69
71
|
type Lane,
|
|
@@ -95,6 +97,7 @@ import type OnRamp_1_6_ABI from './abi/OnRamp_1_6.ts'
|
|
|
95
97
|
import type OnRamp_2_0_ABI from './abi/OnRamp_2_0.ts'
|
|
96
98
|
import type Router_ABI from './abi/Router.ts'
|
|
97
99
|
import type TokenAdminRegistry_1_5_ABI from './abi/TokenAdminRegistry_1_5.ts'
|
|
100
|
+
import type TokenPool_2_0_ABI from './abi/TokenPool_2_0.ts'
|
|
98
101
|
import {
|
|
99
102
|
CCV_INDEXER_URL,
|
|
100
103
|
VersionedContractABI,
|
|
@@ -111,21 +114,21 @@ import {
|
|
|
111
114
|
import { estimateExecGas } from './gas.ts'
|
|
112
115
|
import { getV12LeafHasher, getV16LeafHasher } from './hasher.ts'
|
|
113
116
|
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 }
|
|
117
|
+
import type { CCIPMessage_V1_6_EVM, CCIPMessage_V2_0, CleanAddressable } from './messages.ts'
|
|
124
118
|
import { encodeEVMOffchainTokenData } from './offchain.ts'
|
|
125
119
|
import { buildMessageForDest, decodeMessage, getMessagesInBatch } from '../requests.ts'
|
|
126
120
|
import { type UnsignedEVMTx, resultToObject } from './types.ts'
|
|
121
|
+
import { decodeMessageV1 } from '../messages.ts'
|
|
127
122
|
export type { UnsignedEVMTx }
|
|
128
123
|
|
|
124
|
+
/** Raw on-chain TokenBucket struct returned by TokenPool rate limiter queries. */
|
|
125
|
+
type RateLimiterBucket = { tokens: bigint; isEnabled: boolean; capacity: bigint; rate: bigint }
|
|
126
|
+
|
|
127
|
+
/** Converts an on-chain bucket to the public RateLimiterState, stripping `isEnabled`. */
|
|
128
|
+
function toRateLimiterState(b: RateLimiterBucket): RateLimiterState {
|
|
129
|
+
return b.isEnabled ? { tokens: b.tokens, capacity: b.capacity, rate: b.rate } : null
|
|
130
|
+
}
|
|
131
|
+
|
|
129
132
|
/** typeguard for ethers Signer interface (used for `wallet`s) */
|
|
130
133
|
function isSigner(wallet: unknown): wallet is Signer {
|
|
131
134
|
return (
|
|
@@ -625,6 +628,45 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
625
628
|
}
|
|
626
629
|
}
|
|
627
630
|
|
|
631
|
+
/**
|
|
632
|
+
* {@inheritDoc Chain.getLaneFeatures}
|
|
633
|
+
*/
|
|
634
|
+
override async getLaneFeatures(opts: {
|
|
635
|
+
router: string
|
|
636
|
+
destChainSelector: bigint
|
|
637
|
+
token?: string
|
|
638
|
+
}): Promise<Partial<LaneFeatures>> {
|
|
639
|
+
const onRamp = await this.getOnRampForRouter(opts.router, opts.destChainSelector)
|
|
640
|
+
const [, version] = await this.typeAndVersion(onRamp)
|
|
641
|
+
|
|
642
|
+
const result: Partial<LaneFeatures> = {}
|
|
643
|
+
|
|
644
|
+
// default FTF value for V2_0+ lanes if no token/pool or pool doesn't specify
|
|
645
|
+
if (version >= CCIPVersion.V2_0) result[LaneFeature.MIN_BLOCK_CONFIRMATIONS] = 1
|
|
646
|
+
|
|
647
|
+
// MIN_BLOCK_CONFIRMATIONS — V2_0+ only
|
|
648
|
+
if (opts.token) {
|
|
649
|
+
const { tokenPool } = await this.getRegistryTokenConfig(
|
|
650
|
+
await this.getTokenAdminRegistryFor(onRamp),
|
|
651
|
+
opts.token,
|
|
652
|
+
)
|
|
653
|
+
if (tokenPool) {
|
|
654
|
+
const { minBlockConfirmations } = await this.getTokenPoolConfig(tokenPool)
|
|
655
|
+
if (minBlockConfirmations != null)
|
|
656
|
+
result[LaneFeature.MIN_BLOCK_CONFIRMATIONS] = minBlockConfirmations
|
|
657
|
+
|
|
658
|
+
const remote = await this.getTokenPoolRemote(tokenPool, opts.destChainSelector)
|
|
659
|
+
result[LaneFeature.RATE_LIMITS] = remote.outboundRateLimiterState
|
|
660
|
+
if (minBlockConfirmations && 'customBlockConfirmationsOutboundRateLimiterState' in remote) {
|
|
661
|
+
result[LaneFeature.CUSTOM_BLOCK_CONFIRMATIONS_RATE_LIMITS] =
|
|
662
|
+
remote.customBlockConfirmationsOutboundRateLimiterState
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return result
|
|
668
|
+
}
|
|
669
|
+
|
|
628
670
|
/**
|
|
629
671
|
* {@inheritDoc Chain.getRouterForOffRamp}
|
|
630
672
|
* @throws {@link CCIPVersionUnsupportedError} if OffRamp version is not supported
|
|
@@ -887,11 +929,22 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
887
929
|
? type.includes('OnRamp')
|
|
888
930
|
? interfaces.EVM2EVMOnRamp_v1_5
|
|
889
931
|
: interfaces.EVM2EVMOffRamp_v1_5
|
|
890
|
-
:
|
|
891
|
-
?
|
|
892
|
-
|
|
932
|
+
: version < CCIPVersion.V2_0
|
|
933
|
+
? type.includes('OnRamp')
|
|
934
|
+
? interfaces.OnRamp_v1_6
|
|
935
|
+
: interfaces.OffRamp_v1_6
|
|
936
|
+
: type.includes('OnRamp')
|
|
937
|
+
? interfaces.OnRamp_v2_0
|
|
938
|
+
: interfaces.OffRamp_v2_0,
|
|
893
939
|
this.provider,
|
|
894
|
-
) as unknown as TypedContract<
|
|
940
|
+
) as unknown as TypedContract<
|
|
941
|
+
| typeof EVM2EVMOnRamp_1_5_ABI
|
|
942
|
+
| typeof EVM2EVMOffRamp_1_5_ABI
|
|
943
|
+
| typeof OnRamp_1_6_ABI
|
|
944
|
+
| typeof OffRamp_1_6_ABI
|
|
945
|
+
| typeof OnRamp_2_0_ABI
|
|
946
|
+
| typeof OffRamp_2_0_ABI
|
|
947
|
+
>
|
|
895
948
|
const { tokenAdminRegistry } = await contract.getStaticConfig()
|
|
896
949
|
return tokenAdminRegistry as string
|
|
897
950
|
}
|
|
@@ -975,10 +1028,12 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
975
1028
|
)
|
|
976
1029
|
|
|
977
1030
|
// make sure to approve once per token, for the total amount (including fee, if needed)
|
|
978
|
-
const amountsToApprove = (message.tokenAmounts ?? [])
|
|
979
|
-
(
|
|
980
|
-
|
|
981
|
-
|
|
1031
|
+
const amountsToApprove = (message.tokenAmounts ?? [])
|
|
1032
|
+
.filter(({ token }) => token && token !== ZeroAddress)
|
|
1033
|
+
.reduce(
|
|
1034
|
+
(acc, { token, amount }) => ({ ...acc, [token]: (acc[token] ?? 0n) + amount }),
|
|
1035
|
+
{} as { [token: string]: bigint },
|
|
1036
|
+
)
|
|
982
1037
|
if (feeToken !== ZeroAddress)
|
|
983
1038
|
amountsToApprove[feeToken] = (amountsToApprove[feeToken] ?? 0n) + message.fee
|
|
984
1039
|
|
|
@@ -992,7 +1047,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
992
1047
|
) as unknown as TypedContract<typeof Token_ABI>
|
|
993
1048
|
const allowance = await contract.allowance(sender, router)
|
|
994
1049
|
if (allowance >= amount) return
|
|
995
|
-
const amnt = opts.approveMax ?
|
|
1050
|
+
const amnt = opts.approveMax ? BigInt(2) ** BigInt(256) - BigInt(1) : amount
|
|
996
1051
|
return contract.approve.populateTransaction(router, amnt, { from: sender })
|
|
997
1052
|
}),
|
|
998
1053
|
)
|
|
@@ -1003,6 +1058,13 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1003
1058
|
interfaces.Router,
|
|
1004
1059
|
this.provider,
|
|
1005
1060
|
) as unknown as TypedContract<typeof Router_ABI>
|
|
1061
|
+
|
|
1062
|
+
// if `token` is ZeroAddress, send its `amount` as `value` to router/EtherSenderReceiver (plus possibly native fee)
|
|
1063
|
+
// if native fee, include it in value; otherwise, it's transferedFrom feeToken
|
|
1064
|
+
const value = (message.tokenAmounts ?? [])
|
|
1065
|
+
.filter(({ token }) => token === ZeroAddress)
|
|
1066
|
+
.reduce((acc, { amount }) => acc + amount, feeToken === ZeroAddress ? message.fee : 0n)
|
|
1067
|
+
|
|
1006
1068
|
const sendTx = await contract.ccipSend.populateTransaction(
|
|
1007
1069
|
destChainSelector,
|
|
1008
1070
|
{
|
|
@@ -1012,11 +1074,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1012
1074
|
extraArgs,
|
|
1013
1075
|
feeToken,
|
|
1014
1076
|
},
|
|
1015
|
-
{
|
|
1016
|
-
from: sender,
|
|
1017
|
-
// if native fee, include it in value; otherwise, it's transferedFrom feeToken
|
|
1018
|
-
...(feeToken === ZeroAddress && { value: message.fee }),
|
|
1019
|
-
},
|
|
1077
|
+
{ from: sender, ...(value > 0n ? { value } : {}) },
|
|
1020
1078
|
)
|
|
1021
1079
|
const txRequests = [...approveTxs, sendTx] as SetRequired<typeof sendTx, 'from'>[]
|
|
1022
1080
|
return {
|
|
@@ -1080,13 +1138,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1080
1138
|
async generateUnsignedExecute(
|
|
1081
1139
|
opts: Parameters<Chain['generateUnsignedExecute']>[0],
|
|
1082
1140
|
): Promise<UnsignedEVMTx> {
|
|
1083
|
-
|
|
1084
|
-
if (!('input' in opts)) {
|
|
1085
|
-
if (!this.apiClient) throw new CCIPApiClientNotAvailableError()
|
|
1086
|
-
;({ offRamp, ...input } = await this.apiClient.getExecutionInput(opts.messageId))
|
|
1087
|
-
} else {
|
|
1088
|
-
;({ offRamp, input } = opts)
|
|
1089
|
-
}
|
|
1141
|
+
const { offRamp, input } = await this.resolveExecuteOpts(opts)
|
|
1090
1142
|
if ('verifications' in input) {
|
|
1091
1143
|
const contract = new Contract(
|
|
1092
1144
|
offRamp,
|
|
@@ -1100,6 +1152,13 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1100
1152
|
const txGasLimit = await contract.executeSingleMessage.estimateGas(
|
|
1101
1153
|
{
|
|
1102
1154
|
...message,
|
|
1155
|
+
onRampAddress: zeroPadValue(getAddressBytes(message.onRampAddress), 32),
|
|
1156
|
+
sender: zeroPadValue(getAddressBytes(message.sender), 32),
|
|
1157
|
+
tokenTransfer: message.tokenTransfer.map((ta) => ({
|
|
1158
|
+
...ta,
|
|
1159
|
+
sourcePoolAddress: zeroPadValue(getAddressBytes(ta.sourcePoolAddress), 32),
|
|
1160
|
+
sourceTokenAddress: zeroPadValue(getAddressBytes(ta.sourceTokenAddress), 32),
|
|
1161
|
+
})),
|
|
1103
1162
|
executionGasLimit: BigInt(message.executionGasLimit),
|
|
1104
1163
|
ccipReceiveGasLimit: BigInt(message.ccipReceiveGasLimit),
|
|
1105
1164
|
finality: BigInt(message.finality),
|
|
@@ -1226,6 +1285,22 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1226
1285
|
default:
|
|
1227
1286
|
throw new CCIPVersionUnsupportedError(version)
|
|
1228
1287
|
}
|
|
1288
|
+
|
|
1289
|
+
/* Executing a message for the first time has some hard try/catches on-chain
|
|
1290
|
+
* so we need to ensure some lower-bounds gasLimits */
|
|
1291
|
+
let gasLimit = await this.provider.estimateGas(manualExecTx)
|
|
1292
|
+
if (
|
|
1293
|
+
'gasLimit' in input.message &&
|
|
1294
|
+
input.message.gasLimit &&
|
|
1295
|
+
gasLimit < input.message.gasLimit + 100000n
|
|
1296
|
+
)
|
|
1297
|
+
// if message requested gasLimit, ensure execution more than 100k above requested, otherwise it's clearly a try/catch fail
|
|
1298
|
+
gasLimit = BigInt(input.message.gasLimit) + 200000n
|
|
1299
|
+
else if ('gasLimit' in input.message && !input.message.gasLimit && gasLimit < 240000n)
|
|
1300
|
+
// if message didn't request gasLimit, ensure execution gasLimit is above 240k (empiric)
|
|
1301
|
+
gasLimit = 240000n
|
|
1302
|
+
manualExecTx.gasLimit = gasLimit
|
|
1303
|
+
|
|
1229
1304
|
return { family: ChainFamily.EVM, transactions: [manualExecTx] }
|
|
1230
1305
|
}
|
|
1231
1306
|
|
|
@@ -1252,7 +1327,8 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1252
1327
|
const response = await submitTransaction(wallet, populatedTx, this.provider)
|
|
1253
1328
|
this.logger.debug('manuallyExecute =>', response.hash)
|
|
1254
1329
|
|
|
1255
|
-
|
|
1330
|
+
let receipt = await response.wait(0)
|
|
1331
|
+
if (!receipt) receipt = await response.wait(1, 240_000)
|
|
1256
1332
|
if (!receipt?.hash) throw new CCIPExecTxNotConfirmedError(response.hash)
|
|
1257
1333
|
if (!receipt.status) throw new CCIPExecTxRevertedError(response.hash)
|
|
1258
1334
|
const tx = await this.getTransaction(receipt)
|
|
@@ -1328,24 +1404,44 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1328
1404
|
token: string
|
|
1329
1405
|
router: string
|
|
1330
1406
|
typeAndVersion: string
|
|
1407
|
+
minBlockConfirmations?: number
|
|
1331
1408
|
}> {
|
|
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>
|
|
1409
|
+
const [_, version, typeAndVersion] = await this.typeAndVersion(tokenPool)
|
|
1339
1410
|
|
|
1411
|
+
let contract, router, minBlockConfirmations
|
|
1412
|
+
if (version < CCIPVersion.V2_0) {
|
|
1413
|
+
contract = new Contract(
|
|
1414
|
+
tokenPool,
|
|
1415
|
+
interfaces.TokenPool_v1_6,
|
|
1416
|
+
this.provider,
|
|
1417
|
+
) as unknown as TypedContract<typeof TokenPool_ABI>
|
|
1418
|
+
router = contract.getRouter()
|
|
1419
|
+
} else {
|
|
1420
|
+
contract = new Contract(
|
|
1421
|
+
tokenPool,
|
|
1422
|
+
interfaces.TokenPool_v2_0,
|
|
1423
|
+
this.provider,
|
|
1424
|
+
) as unknown as TypedContract<typeof TokenPool_2_0_ABI>
|
|
1425
|
+
router = contract.getDynamicConfig().then(([router]) => router)
|
|
1426
|
+
minBlockConfirmations = contract.getMinBlockConfirmations().catch((err) => {
|
|
1427
|
+
if (isError(err, 'CALL_EXCEPTION')) return 0
|
|
1428
|
+
throw CCIPError.from(err)
|
|
1429
|
+
})
|
|
1430
|
+
}
|
|
1340
1431
|
const token = contract.getToken()
|
|
1341
|
-
|
|
1342
|
-
return Promise.all([token, router]).then(
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1432
|
+
|
|
1433
|
+
return Promise.all([token, router, minBlockConfirmations]).then(
|
|
1434
|
+
([token, router, minBlockConfirmations]) => {
|
|
1435
|
+
return {
|
|
1436
|
+
token: token as CleanAddressable<typeof token>,
|
|
1437
|
+
router: router as CleanAddressable<typeof router>,
|
|
1438
|
+
typeAndVersion,
|
|
1439
|
+
...(minBlockConfirmations != null && {
|
|
1440
|
+
minBlockConfirmations: Number(minBlockConfirmations),
|
|
1441
|
+
}),
|
|
1442
|
+
}
|
|
1443
|
+
},
|
|
1444
|
+
)
|
|
1349
1445
|
}
|
|
1350
1446
|
|
|
1351
1447
|
/** {@inheritDoc Chain.getTokenPoolRemotes} */
|
|
@@ -1359,53 +1455,93 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1359
1455
|
if (remoteChainSelector) supportedChains = Promise.resolve([networkInfo(remoteChainSelector)])
|
|
1360
1456
|
|
|
1361
1457
|
let remotePools: Promise<string[][]>
|
|
1362
|
-
let
|
|
1458
|
+
let remoteInfo
|
|
1363
1459
|
if (version < '1.5.1') {
|
|
1364
|
-
const
|
|
1460
|
+
const contract = new Contract(
|
|
1365
1461
|
tokenPool,
|
|
1366
1462
|
interfaces.TokenPool_v1_5,
|
|
1367
1463
|
this.provider,
|
|
1368
1464
|
) as unknown as TypedContract<typeof TokenPool_1_5_ABI>
|
|
1369
|
-
contract = contract_
|
|
1370
1465
|
supportedChains ??= contract.getSupportedChains().then((chains) => chains.map(networkInfo))
|
|
1371
1466
|
remotePools = supportedChains.then((chains) =>
|
|
1372
1467
|
Promise.all(
|
|
1373
1468
|
chains.map((chain) =>
|
|
1374
|
-
|
|
1469
|
+
contract
|
|
1375
1470
|
.getRemotePool(chain.chainSelector)
|
|
1376
1471
|
.then((remotePool) => [decodeAddress(remotePool, chain.family)]),
|
|
1377
1472
|
),
|
|
1378
1473
|
),
|
|
1379
1474
|
)
|
|
1380
|
-
|
|
1381
|
-
|
|
1475
|
+
remoteInfo = supportedChains.then((chains) =>
|
|
1476
|
+
Promise.all(
|
|
1477
|
+
chains.map((chain) =>
|
|
1478
|
+
Promise.all([
|
|
1479
|
+
contract.getRemoteToken(chain.chainSelector),
|
|
1480
|
+
resultToObject(contract.getCurrentOutboundRateLimiterState(chain.chainSelector)),
|
|
1481
|
+
resultToObject(contract.getCurrentInboundRateLimiterState(chain.chainSelector)),
|
|
1482
|
+
] as const),
|
|
1483
|
+
),
|
|
1484
|
+
),
|
|
1485
|
+
)
|
|
1486
|
+
} else if (version < CCIPVersion.V2_0) {
|
|
1487
|
+
const contract = new Contract(
|
|
1382
1488
|
tokenPool,
|
|
1383
1489
|
interfaces.TokenPool_v1_6,
|
|
1384
1490
|
this.provider,
|
|
1385
1491
|
) as unknown as TypedContract<typeof TokenPool_ABI>
|
|
1386
|
-
contract = contract_
|
|
1387
1492
|
supportedChains ??= contract.getSupportedChains().then((chains) => chains.map(networkInfo))
|
|
1388
1493
|
remotePools = supportedChains.then((chains) =>
|
|
1389
1494
|
Promise.all(
|
|
1390
1495
|
chains.map((chain) =>
|
|
1391
|
-
|
|
1496
|
+
contract
|
|
1392
1497
|
.getRemotePools(chain.chainSelector)
|
|
1393
1498
|
.then((pools) => pools.map((remotePool) => decodeAddress(remotePool, chain.family))),
|
|
1394
1499
|
),
|
|
1395
1500
|
),
|
|
1396
1501
|
)
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1502
|
+
remoteInfo = supportedChains.then((chains) =>
|
|
1503
|
+
Promise.all(
|
|
1504
|
+
chains.map((chain) =>
|
|
1505
|
+
Promise.all([
|
|
1506
|
+
contract.getRemoteToken(chain.chainSelector),
|
|
1507
|
+
resultToObject(contract.getCurrentOutboundRateLimiterState(chain.chainSelector)),
|
|
1508
|
+
resultToObject(contract.getCurrentInboundRateLimiterState(chain.chainSelector)),
|
|
1509
|
+
] as const),
|
|
1510
|
+
),
|
|
1406
1511
|
),
|
|
1407
|
-
)
|
|
1408
|
-
|
|
1512
|
+
)
|
|
1513
|
+
} else {
|
|
1514
|
+
const contract = new Contract(
|
|
1515
|
+
tokenPool,
|
|
1516
|
+
interfaces.TokenPool_v2_0,
|
|
1517
|
+
this.provider,
|
|
1518
|
+
) as unknown as TypedContract<typeof TokenPool_2_0_ABI>
|
|
1519
|
+
supportedChains ??= contract.getSupportedChains().then((chains) => chains.map(networkInfo))
|
|
1520
|
+
remotePools = supportedChains.then((chains) =>
|
|
1521
|
+
Promise.all(
|
|
1522
|
+
chains.map((chain) =>
|
|
1523
|
+
contract
|
|
1524
|
+
.getRemotePools(chain.chainSelector)
|
|
1525
|
+
.then((pools) => pools.map((remotePool) => decodeAddress(remotePool, chain.family))),
|
|
1526
|
+
),
|
|
1527
|
+
),
|
|
1528
|
+
)
|
|
1529
|
+
remoteInfo = supportedChains.then((chains) =>
|
|
1530
|
+
Promise.all(
|
|
1531
|
+
chains.map((chain) =>
|
|
1532
|
+
Promise.all([
|
|
1533
|
+
contract.getRemoteToken(chain.chainSelector),
|
|
1534
|
+
contract.getCurrentRateLimiterState(chain.chainSelector, false),
|
|
1535
|
+
contract.getCurrentRateLimiterState(chain.chainSelector, true),
|
|
1536
|
+
] as const).then(
|
|
1537
|
+
([remoteToken, [outbound, inbound], [customOutbound, customInbound]]) => {
|
|
1538
|
+
return [remoteToken, outbound, inbound, customOutbound, customInbound] as const
|
|
1539
|
+
},
|
|
1540
|
+
),
|
|
1541
|
+
),
|
|
1542
|
+
),
|
|
1543
|
+
)
|
|
1544
|
+
}
|
|
1409
1545
|
return Promise.all([supportedChains, remotePools, remoteInfo]).then(
|
|
1410
1546
|
([supportedChains, remotePools, remoteInfo]) =>
|
|
1411
1547
|
Object.fromEntries(
|
|
@@ -1418,8 +1554,16 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1418
1554
|
{
|
|
1419
1555
|
remoteToken: decodeAddress(remoteTokenRaw, chain.family),
|
|
1420
1556
|
remotePools: remotePools[i]!.map((pool) => decodeAddress(pool, chain.family)),
|
|
1421
|
-
|
|
1422
|
-
|
|
1557
|
+
outboundRateLimiterState: toRateLimiterState(remoteInfo[i]![1]),
|
|
1558
|
+
inboundRateLimiterState: toRateLimiterState(remoteInfo[i]![2]),
|
|
1559
|
+
...(remoteInfo[i]!.length === 5 && {
|
|
1560
|
+
customBlockConfirmationsOutboundRateLimiterState: toRateLimiterState(
|
|
1561
|
+
remoteInfo[i]![3],
|
|
1562
|
+
),
|
|
1563
|
+
customBlockConfirmationsInboundRateLimiterState: toRateLimiterState(
|
|
1564
|
+
remoteInfo[i]![4],
|
|
1565
|
+
),
|
|
1566
|
+
}),
|
|
1423
1567
|
},
|
|
1424
1568
|
] as const
|
|
1425
1569
|
}),
|
|
@@ -1461,7 +1605,8 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1461
1605
|
tokens = Array.from(tokens_)
|
|
1462
1606
|
break
|
|
1463
1607
|
}
|
|
1464
|
-
case CCIPVersion.V1_6:
|
|
1608
|
+
case CCIPVersion.V1_6:
|
|
1609
|
+
case CCIPVersion.V2_0: {
|
|
1465
1610
|
const feeQuoter = await this.getFeeQuoterFor(onRamp)
|
|
1466
1611
|
const contract = new Contract(
|
|
1467
1612
|
feeQuoter,
|
|
@@ -1489,15 +1634,13 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1489
1634
|
): Promise<CCIPVerifications> {
|
|
1490
1635
|
const { offRamp, request } = opts
|
|
1491
1636
|
if (request.lane.version >= CCIPVersion.V2_0) {
|
|
1492
|
-
const
|
|
1493
|
-
if (!message.encodedMessage)
|
|
1494
|
-
throw new CCIPNotImplementedError(`CCIPAPIClient getMessageById v2 encodedMessage`)
|
|
1637
|
+
const { encodedMessage } = request.message as CCIPMessage_V2_0
|
|
1495
1638
|
const contract = new Contract(
|
|
1496
1639
|
offRamp,
|
|
1497
1640
|
interfaces.OffRamp_v2_0,
|
|
1498
1641
|
this.provider,
|
|
1499
1642
|
) as unknown as TypedContract<typeof OffRamp_2_0_ABI>
|
|
1500
|
-
const ccvs = await contract.getCCVsForMessage(
|
|
1643
|
+
const ccvs = await contract.getCCVsForMessage(encodedMessage)
|
|
1501
1644
|
const [requiredCCVs, optionalCCVs, optionalThreshold] = ccvs.map(
|
|
1502
1645
|
resultToObject,
|
|
1503
1646
|
) as unknown as CleanAddressable<typeof ccvs>
|
|
@@ -1511,20 +1654,24 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1511
1654
|
const apiRes = await this.apiClient.getMessageById(request.message.messageId)
|
|
1512
1655
|
if ('verifiers' in apiRes.message) {
|
|
1513
1656
|
const verifiers = apiRes.message.verifiers as {
|
|
1514
|
-
items
|
|
1657
|
+
items?: {
|
|
1515
1658
|
destAddress: string
|
|
1516
1659
|
sourceAddress: string
|
|
1517
|
-
verification
|
|
1660
|
+
verification?: { data: string; timestamp: string }
|
|
1518
1661
|
}[]
|
|
1519
1662
|
}
|
|
1520
1663
|
return {
|
|
1521
1664
|
verificationPolicy,
|
|
1522
|
-
verifications: verifiers.items
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1665
|
+
verifications: (verifiers.items ?? [])
|
|
1666
|
+
.filter((item) => item.verification?.data)
|
|
1667
|
+
.map((item) => ({
|
|
1668
|
+
destAddress: item.destAddress,
|
|
1669
|
+
sourceAddress: item.sourceAddress,
|
|
1670
|
+
ccvData: item.verification!.data,
|
|
1671
|
+
...(!!item.verification?.timestamp && {
|
|
1672
|
+
timestamp: new Date(item.verification.timestamp).getTime() / 1e3,
|
|
1673
|
+
}),
|
|
1674
|
+
})),
|
|
1528
1675
|
}
|
|
1529
1676
|
}
|
|
1530
1677
|
}
|