@chainlink/ccip-sdk 0.97.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/README.md +12 -9
- package/dist/api/index.d.ts +7 -3
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +124 -13
- 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 +4 -6
- package/dist/aptos/index.d.ts.map +1 -1
- package/dist/aptos/index.js +0 -5
- package/dist/aptos/index.js.map +1 -1
- package/dist/aptos/logs.d.ts +2 -2
- package/dist/aptos/logs.d.ts.map +1 -1
- package/dist/chain.d.ts +104 -16
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js +97 -9
- 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 +5 -5
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +5 -5
- 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/OnRamp_2_0.d.ts +1 -1
- package/dist/evm/abi/OnRamp_2_0.js +1 -1
- package/dist/evm/abi/OnRamp_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 +11 -7
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +139 -46
- package/dist/evm/index.js.map +1 -1
- package/dist/evm/logs.d.ts +1 -1
- package/dist/evm/logs.js +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/evm/offchain.d.ts +1 -14
- package/dist/evm/offchain.d.ts.map +1 -1
- package/dist/evm/offchain.js +1 -133
- package/dist/evm/offchain.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 +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- 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/offchain.d.ts +23 -6
- package/dist/offchain.d.ts.map +1 -1
- package/dist/offchain.js +92 -17
- package/dist/offchain.js.map +1 -1
- package/dist/requests.d.ts.map +1 -1
- package/dist/requests.js +0 -1
- package/dist/requests.js.map +1 -1
- 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/idl/1.6.0/BASE_TOKEN_POOL.d.ts +1 -1
- package/dist/solana/idl/1.6.0/BASE_TOKEN_POOL.js +1 -1
- package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.d.ts +1 -1
- package/dist/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.js +1 -1
- package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.d.ts +1 -1
- package/dist/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.js +1 -1
- package/dist/solana/idl/1.6.0/CCIP_COMMON.d.ts +16 -1
- package/dist/solana/idl/1.6.0/CCIP_COMMON.d.ts.map +1 -1
- package/dist/solana/idl/1.6.0/CCIP_COMMON.js +16 -1
- package/dist/solana/idl/1.6.0/CCIP_COMMON.js.map +1 -1
- package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.d.ts +1 -1
- package/dist/solana/idl/1.6.0/CCIP_OFFRAMP.js +1 -1
- package/dist/solana/idl/1.6.0/CCIP_ROUTER.d.ts +1 -1
- package/dist/solana/idl/1.6.0/CCIP_ROUTER.js +1 -1
- package/dist/solana/index.d.ts +25 -27
- package/dist/solana/index.d.ts.map +1 -1
- package/dist/solana/index.js +16 -7
- package/dist/solana/index.js.map +1 -1
- package/dist/solana/offchain.d.ts +1 -13
- package/dist/solana/offchain.d.ts.map +1 -1
- package/dist/solana/offchain.js +1 -66
- package/dist/solana/offchain.js.map +1 -1
- package/dist/solana/utils.d.ts +4 -4
- package/dist/solana/utils.d.ts.map +1 -1
- package/dist/solana/utils.js +1 -1
- package/dist/solana/utils.js.map +1 -1
- package/dist/sui/index.d.ts +4 -6
- package/dist/sui/index.d.ts.map +1 -1
- package/dist/sui/index.js +14 -6
- package/dist/sui/index.js.map +1 -1
- package/dist/ton/exec.d.ts +2 -2
- package/dist/ton/exec.d.ts.map +1 -1
- package/dist/ton/exec.js +1 -1
- package/dist/ton/exec.js.map +1 -1
- package/dist/ton/index.d.ts +5 -6
- package/dist/ton/index.d.ts.map +1 -1
- package/dist/ton/index.js +3 -5
- package/dist/ton/index.js.map +1 -1
- package/dist/ton/types.d.ts +3 -5
- package/dist/ton/types.d.ts.map +1 -1
- package/dist/ton/types.js.map +1 -1
- package/dist/types.d.ts +10 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +11 -7
- package/src/api/index.ts +145 -17
- package/src/api/types.ts +43 -0
- package/src/aptos/index.ts +4 -11
- package/src/aptos/logs.ts +2 -2
- package/src/chain.ts +148 -23
- package/src/errors/codes.ts +2 -1
- package/src/errors/index.ts +4 -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/OnRamp_2_0.ts +1 -1
- package/src/evm/abi/TokenPool_2_0.ts +1636 -0
- package/src/evm/const.ts +2 -0
- package/src/evm/index.ts +234 -85
- package/src/evm/logs.ts +1 -1
- package/src/evm/messages.ts +3 -285
- package/src/evm/offchain.ts +2 -191
- package/src/gas.ts +27 -19
- package/src/index.ts +10 -2
- package/src/messages.ts +278 -0
- package/src/offchain.ts +125 -28
- package/src/requests.ts +2 -3
- package/src/solana/cleanup.ts +2 -2
- package/src/solana/exec.ts +1 -1
- package/src/solana/idl/1.6.0/BASE_TOKEN_POOL.ts +2 -2
- package/src/solana/idl/1.6.0/BURN_MINT_TOKEN_POOL.ts +2 -2
- package/src/solana/idl/1.6.0/CCIP_CCTP_TOKEN_POOL.ts +2 -2
- package/src/solana/idl/1.6.0/CCIP_COMMON.ts +32 -2
- package/src/solana/idl/1.6.0/CCIP_OFFRAMP.ts +2 -2
- package/src/solana/idl/1.6.0/CCIP_ROUTER.ts +2 -2
- package/src/solana/index.ts +27 -17
- package/src/solana/offchain.ts +3 -100
- package/src/solana/utils.ts +8 -5
- package/src/sui/index.ts +22 -12
- package/src/ton/exec.ts +3 -6
- package/src/ton/index.ts +15 -16
- package/src/ton/types.ts +3 -6
- package/src/types.ts +13 -10
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,
|
|
@@ -60,15 +64,14 @@ import {
|
|
|
60
64
|
type CCIPMessage,
|
|
61
65
|
type CCIPRequest,
|
|
62
66
|
type CCIPVerifications,
|
|
67
|
+
type ChainLog,
|
|
63
68
|
type ChainTransaction,
|
|
64
69
|
type CommitReport,
|
|
65
70
|
type ExecutionInput,
|
|
66
71
|
type ExecutionReceipt,
|
|
67
72
|
type ExecutionState,
|
|
68
73
|
type Lane,
|
|
69
|
-
type Log_,
|
|
70
74
|
type NetworkInfo,
|
|
71
|
-
type OffchainTokenData,
|
|
72
75
|
type WithLogger,
|
|
73
76
|
CCIPVersion,
|
|
74
77
|
ChainFamily,
|
|
@@ -96,6 +99,7 @@ import type OnRamp_1_6_ABI from './abi/OnRamp_1_6.ts'
|
|
|
96
99
|
import type OnRamp_2_0_ABI from './abi/OnRamp_2_0.ts'
|
|
97
100
|
import type Router_ABI from './abi/Router.ts'
|
|
98
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'
|
|
99
103
|
import {
|
|
100
104
|
CCV_INDEXER_URL,
|
|
101
105
|
VersionedContractABI,
|
|
@@ -112,21 +116,21 @@ import {
|
|
|
112
116
|
import { estimateExecGas } from './gas.ts'
|
|
113
117
|
import { getV12LeafHasher, getV16LeafHasher } from './hasher.ts'
|
|
114
118
|
import { getEvmLogs } from './logs.ts'
|
|
115
|
-
import {
|
|
116
|
-
|
|
117
|
-
type CCIPMessage_V2_0,
|
|
118
|
-
type CleanAddressable,
|
|
119
|
-
type MessageV1,
|
|
120
|
-
type TokenTransferV1,
|
|
121
|
-
decodeMessageV1,
|
|
122
|
-
} from './messages.ts'
|
|
123
|
-
export { decodeMessageV1 }
|
|
124
|
-
export type { MessageV1, TokenTransferV1 }
|
|
125
|
-
import { encodeEVMOffchainTokenData, fetchEVMOffchainTokenData } from './offchain.ts'
|
|
119
|
+
import type { CCIPMessage_V1_6_EVM, CCIPMessage_V2_0, CleanAddressable } from './messages.ts'
|
|
120
|
+
import { encodeEVMOffchainTokenData } from './offchain.ts'
|
|
126
121
|
import { buildMessageForDest, decodeMessage, getMessagesInBatch } from '../requests.ts'
|
|
127
122
|
import { type UnsignedEVMTx, resultToObject } from './types.ts'
|
|
123
|
+
import { decodeMessageV1 } from '../messages.ts'
|
|
128
124
|
export type { UnsignedEVMTx }
|
|
129
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
|
+
|
|
130
134
|
/** typeguard for ethers Signer interface (used for `wallet`s) */
|
|
131
135
|
function isSigner(wallet: unknown): wallet is Signer {
|
|
132
136
|
return (
|
|
@@ -339,9 +343,9 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
339
343
|
const chainTx = {
|
|
340
344
|
...tx,
|
|
341
345
|
timestamp,
|
|
342
|
-
logs: [] as
|
|
346
|
+
logs: [] as ChainLog[],
|
|
343
347
|
}
|
|
344
|
-
const logs:
|
|
348
|
+
const logs: ChainLog[] = tx.logs.map((l) => Object.assign(l, { tx: chainTx }))
|
|
345
349
|
chainTx.logs = logs
|
|
346
350
|
return chainTx
|
|
347
351
|
}
|
|
@@ -626,6 +630,45 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
626
630
|
}
|
|
627
631
|
}
|
|
628
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
|
+
|
|
629
672
|
/**
|
|
630
673
|
* {@inheritDoc Chain.getRouterForOffRamp}
|
|
631
674
|
* @throws {@link CCIPVersionUnsupportedError} if OffRamp version is not supported
|
|
@@ -888,11 +931,22 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
888
931
|
? type.includes('OnRamp')
|
|
889
932
|
? interfaces.EVM2EVMOnRamp_v1_5
|
|
890
933
|
: interfaces.EVM2EVMOffRamp_v1_5
|
|
891
|
-
:
|
|
892
|
-
?
|
|
893
|
-
|
|
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,
|
|
894
941
|
this.provider,
|
|
895
|
-
) 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
|
+
>
|
|
896
950
|
const { tokenAdminRegistry } = await contract.getStaticConfig()
|
|
897
951
|
return tokenAdminRegistry as string
|
|
898
952
|
}
|
|
@@ -976,10 +1030,12 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
976
1030
|
)
|
|
977
1031
|
|
|
978
1032
|
// make sure to approve once per token, for the total amount (including fee, if needed)
|
|
979
|
-
const amountsToApprove = (message.tokenAmounts ?? [])
|
|
980
|
-
(
|
|
981
|
-
|
|
982
|
-
|
|
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
|
+
)
|
|
983
1039
|
if (feeToken !== ZeroAddress)
|
|
984
1040
|
amountsToApprove[feeToken] = (amountsToApprove[feeToken] ?? 0n) + message.fee
|
|
985
1041
|
|
|
@@ -993,7 +1049,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
993
1049
|
) as unknown as TypedContract<typeof Token_ABI>
|
|
994
1050
|
const allowance = await contract.allowance(sender, router)
|
|
995
1051
|
if (allowance >= amount) return
|
|
996
|
-
const amnt = opts.approveMax ?
|
|
1052
|
+
const amnt = opts.approveMax ? BigInt(2) ** BigInt(256) - BigInt(1) : amount
|
|
997
1053
|
return contract.approve.populateTransaction(router, amnt, { from: sender })
|
|
998
1054
|
}),
|
|
999
1055
|
)
|
|
@@ -1004,6 +1060,13 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1004
1060
|
interfaces.Router,
|
|
1005
1061
|
this.provider,
|
|
1006
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
|
+
|
|
1007
1070
|
const sendTx = await contract.ccipSend.populateTransaction(
|
|
1008
1071
|
destChainSelector,
|
|
1009
1072
|
{
|
|
@@ -1013,11 +1076,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1013
1076
|
extraArgs,
|
|
1014
1077
|
feeToken,
|
|
1015
1078
|
},
|
|
1016
|
-
{
|
|
1017
|
-
from: sender,
|
|
1018
|
-
// if native fee, include it in value; otherwise, it's transferedFrom feeToken
|
|
1019
|
-
...(feeToken === ZeroAddress && { value: message.fee }),
|
|
1020
|
-
},
|
|
1079
|
+
{ from: sender, ...(value > 0n ? { value } : {}) },
|
|
1021
1080
|
)
|
|
1022
1081
|
const txRequests = [...approveTxs, sendTx] as SetRequired<typeof sendTx, 'from'>[]
|
|
1023
1082
|
return {
|
|
@@ -1073,11 +1132,6 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1073
1132
|
return (await this.getMessagesInTx(await this.getTransaction(tx)))[0]!
|
|
1074
1133
|
}
|
|
1075
1134
|
|
|
1076
|
-
/** {@inheritDoc Chain.getOffchainTokenData} */
|
|
1077
|
-
getOffchainTokenData(request: CCIPRequest): Promise<OffchainTokenData[]> {
|
|
1078
|
-
return fetchEVMOffchainTokenData(request, this)
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
1135
|
/**
|
|
1082
1136
|
* {@inheritDoc Chain.generateUnsignedExecute}
|
|
1083
1137
|
* @returns array containing one unsigned `manuallyExecute` TransactionRequest object
|
|
@@ -1106,6 +1160,13 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1106
1160
|
const txGasLimit = await contract.executeSingleMessage.estimateGas(
|
|
1107
1161
|
{
|
|
1108
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
|
+
})),
|
|
1109
1170
|
executionGasLimit: BigInt(message.executionGasLimit),
|
|
1110
1171
|
ccipReceiveGasLimit: BigInt(message.ccipReceiveGasLimit),
|
|
1111
1172
|
finality: BigInt(message.finality),
|
|
@@ -1232,6 +1293,22 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1232
1293
|
default:
|
|
1233
1294
|
throw new CCIPVersionUnsupportedError(version)
|
|
1234
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
|
+
|
|
1235
1312
|
return { family: ChainFamily.EVM, transactions: [manualExecTx] }
|
|
1236
1313
|
}
|
|
1237
1314
|
|
|
@@ -1258,7 +1335,8 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1258
1335
|
const response = await submitTransaction(wallet, populatedTx, this.provider)
|
|
1259
1336
|
this.logger.debug('manuallyExecute =>', response.hash)
|
|
1260
1337
|
|
|
1261
|
-
|
|
1338
|
+
let receipt = await response.wait(0)
|
|
1339
|
+
if (!receipt) receipt = await response.wait(1, 240_000)
|
|
1262
1340
|
if (!receipt?.hash) throw new CCIPExecTxNotConfirmedError(response.hash)
|
|
1263
1341
|
if (!receipt.status) throw new CCIPExecTxRevertedError(response.hash)
|
|
1264
1342
|
const tx = await this.getTransaction(receipt)
|
|
@@ -1334,24 +1412,44 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1334
1412
|
token: string
|
|
1335
1413
|
router: string
|
|
1336
1414
|
typeAndVersion: string
|
|
1415
|
+
minBlockConfirmations?: number
|
|
1337
1416
|
}> {
|
|
1338
|
-
const [_, , typeAndVersion] = await this.typeAndVersion(tokenPool)
|
|
1339
|
-
|
|
1340
|
-
const contract = new Contract(
|
|
1341
|
-
tokenPool,
|
|
1342
|
-
interfaces.TokenPool_v1_6,
|
|
1343
|
-
this.provider,
|
|
1344
|
-
) as unknown as TypedContract<typeof TokenPool_ABI>
|
|
1417
|
+
const [_, version, typeAndVersion] = await this.typeAndVersion(tokenPool)
|
|
1345
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
|
+
}
|
|
1346
1439
|
const token = contract.getToken()
|
|
1347
|
-
|
|
1348
|
-
return Promise.all([token, router]).then(
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
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
|
+
)
|
|
1355
1453
|
}
|
|
1356
1454
|
|
|
1357
1455
|
/** {@inheritDoc Chain.getTokenPoolRemotes} */
|
|
@@ -1365,53 +1463,93 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1365
1463
|
if (remoteChainSelector) supportedChains = Promise.resolve([networkInfo(remoteChainSelector)])
|
|
1366
1464
|
|
|
1367
1465
|
let remotePools: Promise<string[][]>
|
|
1368
|
-
let
|
|
1466
|
+
let remoteInfo
|
|
1369
1467
|
if (version < '1.5.1') {
|
|
1370
|
-
const
|
|
1468
|
+
const contract = new Contract(
|
|
1371
1469
|
tokenPool,
|
|
1372
1470
|
interfaces.TokenPool_v1_5,
|
|
1373
1471
|
this.provider,
|
|
1374
1472
|
) as unknown as TypedContract<typeof TokenPool_1_5_ABI>
|
|
1375
|
-
contract = contract_
|
|
1376
1473
|
supportedChains ??= contract.getSupportedChains().then((chains) => chains.map(networkInfo))
|
|
1377
1474
|
remotePools = supportedChains.then((chains) =>
|
|
1378
1475
|
Promise.all(
|
|
1379
1476
|
chains.map((chain) =>
|
|
1380
|
-
|
|
1477
|
+
contract
|
|
1381
1478
|
.getRemotePool(chain.chainSelector)
|
|
1382
1479
|
.then((remotePool) => [decodeAddress(remotePool, chain.family)]),
|
|
1383
1480
|
),
|
|
1384
1481
|
),
|
|
1385
1482
|
)
|
|
1386
|
-
|
|
1387
|
-
|
|
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(
|
|
1388
1496
|
tokenPool,
|
|
1389
1497
|
interfaces.TokenPool_v1_6,
|
|
1390
1498
|
this.provider,
|
|
1391
1499
|
) as unknown as TypedContract<typeof TokenPool_ABI>
|
|
1392
|
-
contract = contract_
|
|
1393
1500
|
supportedChains ??= contract.getSupportedChains().then((chains) => chains.map(networkInfo))
|
|
1394
1501
|
remotePools = supportedChains.then((chains) =>
|
|
1395
1502
|
Promise.all(
|
|
1396
1503
|
chains.map((chain) =>
|
|
1397
|
-
|
|
1504
|
+
contract
|
|
1398
1505
|
.getRemotePools(chain.chainSelector)
|
|
1399
1506
|
.then((pools) => pools.map((remotePool) => decodeAddress(remotePool, chain.family))),
|
|
1400
1507
|
),
|
|
1401
1508
|
),
|
|
1402
1509
|
)
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
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
|
+
),
|
|
1412
1519
|
),
|
|
1413
|
-
)
|
|
1414
|
-
|
|
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
|
+
}
|
|
1415
1553
|
return Promise.all([supportedChains, remotePools, remoteInfo]).then(
|
|
1416
1554
|
([supportedChains, remotePools, remoteInfo]) =>
|
|
1417
1555
|
Object.fromEntries(
|
|
@@ -1424,8 +1562,16 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1424
1562
|
{
|
|
1425
1563
|
remoteToken: decodeAddress(remoteTokenRaw, chain.family),
|
|
1426
1564
|
remotePools: remotePools[i]!.map((pool) => decodeAddress(pool, chain.family)),
|
|
1427
|
-
|
|
1428
|
-
|
|
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
|
+
}),
|
|
1429
1575
|
},
|
|
1430
1576
|
] as const
|
|
1431
1577
|
}),
|
|
@@ -1467,7 +1613,8 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1467
1613
|
tokens = Array.from(tokens_)
|
|
1468
1614
|
break
|
|
1469
1615
|
}
|
|
1470
|
-
case CCIPVersion.V1_6:
|
|
1616
|
+
case CCIPVersion.V1_6:
|
|
1617
|
+
case CCIPVersion.V2_0: {
|
|
1471
1618
|
const feeQuoter = await this.getFeeQuoterFor(onRamp)
|
|
1472
1619
|
const contract = new Contract(
|
|
1473
1620
|
feeQuoter,
|
|
@@ -1495,15 +1642,13 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1495
1642
|
): Promise<CCIPVerifications> {
|
|
1496
1643
|
const { offRamp, request } = opts
|
|
1497
1644
|
if (request.lane.version >= CCIPVersion.V2_0) {
|
|
1498
|
-
const
|
|
1499
|
-
if (!message.encodedMessage)
|
|
1500
|
-
throw new CCIPNotImplementedError(`CCIPAPIClient getMessageById v2 encodedMessage`)
|
|
1645
|
+
const { encodedMessage } = request.message as CCIPMessage_V2_0
|
|
1501
1646
|
const contract = new Contract(
|
|
1502
1647
|
offRamp,
|
|
1503
1648
|
interfaces.OffRamp_v2_0,
|
|
1504
1649
|
this.provider,
|
|
1505
1650
|
) as unknown as TypedContract<typeof OffRamp_2_0_ABI>
|
|
1506
|
-
const ccvs = await contract.getCCVsForMessage(
|
|
1651
|
+
const ccvs = await contract.getCCVsForMessage(encodedMessage)
|
|
1507
1652
|
const [requiredCCVs, optionalCCVs, optionalThreshold] = ccvs.map(
|
|
1508
1653
|
resultToObject,
|
|
1509
1654
|
) as unknown as CleanAddressable<typeof ccvs>
|
|
@@ -1517,20 +1662,24 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1517
1662
|
const apiRes = await this.apiClient.getMessageById(request.message.messageId)
|
|
1518
1663
|
if ('verifiers' in apiRes.message) {
|
|
1519
1664
|
const verifiers = apiRes.message.verifiers as {
|
|
1520
|
-
items
|
|
1665
|
+
items?: {
|
|
1521
1666
|
destAddress: string
|
|
1522
1667
|
sourceAddress: string
|
|
1523
|
-
verification
|
|
1668
|
+
verification?: { data: string; timestamp: string }
|
|
1524
1669
|
}[]
|
|
1525
1670
|
}
|
|
1526
1671
|
return {
|
|
1527
1672
|
verificationPolicy,
|
|
1528
|
-
verifications: verifiers.items
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
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
|
+
})),
|
|
1534
1683
|
}
|
|
1535
1684
|
}
|
|
1536
1685
|
}
|
package/src/evm/logs.ts
CHANGED
|
@@ -183,7 +183,7 @@ async function getFallbackArchiveLogs(
|
|
|
183
183
|
* - If undefined (default): paginate main provider only by filter.page
|
|
184
184
|
* - If false: first try whole range with main provider, then fallback to archive provider
|
|
185
185
|
* - If true: don't paginate (throw if can't fetch wide range from either provider)
|
|
186
|
-
* @param ctx - Context object containing provider, logger and
|
|
186
|
+
* @param ctx - Context object containing provider, logger and destroy$ notify promise
|
|
187
187
|
* @returns Async iterator of logs.
|
|
188
188
|
*/
|
|
189
189
|
export async function* getEvmLogs(
|