@chainlink/ccip-sdk 0.93.0 → 0.94.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/aptos/index.d.ts.map +1 -1
- package/dist/aptos/index.js +9 -5
- package/dist/aptos/index.js.map +1 -1
- package/dist/aptos/send.js +1 -1
- package/dist/aptos/send.js.map +1 -1
- package/dist/chain.d.ts +13 -6
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js +14 -0
- package/dist/chain.js.map +1 -1
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +14 -10
- package/dist/evm/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/requests.d.ts +8 -2
- package/dist/requests.d.ts.map +1 -1
- package/dist/requests.js +10 -0
- package/dist/requests.js.map +1 -1
- package/dist/selectors.d.ts.map +1 -1
- package/dist/selectors.js +20 -0
- package/dist/selectors.js.map +1 -1
- package/dist/solana/index.d.ts +7 -3
- package/dist/solana/index.d.ts.map +1 -1
- package/dist/solana/index.js +64 -7
- package/dist/solana/index.js.map +1 -1
- package/dist/sui/index.d.ts +14 -9
- package/dist/sui/index.d.ts.map +1 -1
- package/dist/sui/index.js +47 -19
- package/dist/sui/index.js.map +1 -1
- package/dist/sui/manuallyExec/encoder.d.ts.map +1 -1
- package/dist/sui/manuallyExec/encoder.js +1 -0
- package/dist/sui/manuallyExec/encoder.js.map +1 -1
- package/dist/sui/manuallyExec/index.d.ts.map +1 -1
- package/dist/sui/manuallyExec/index.js +1 -0
- package/dist/sui/manuallyExec/index.js.map +1 -1
- package/dist/sui/objects.d.ts.map +1 -1
- package/dist/sui/objects.js +2 -1
- package/dist/sui/objects.js.map +1 -1
- package/dist/ton/hasher.d.ts.map +1 -1
- package/dist/ton/hasher.js +1 -0
- package/dist/ton/hasher.js.map +1 -1
- package/dist/ton/index.d.ts.map +1 -1
- package/dist/ton/index.js +1 -0
- package/dist/ton/index.js.map +1 -1
- package/dist/types.d.ts +10 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1 -0
- package/dist/utils.js.map +1 -1
- package/package.json +16 -10
- package/src/aptos/index.ts +20 -6
- package/src/aptos/send.ts +1 -1
- package/src/chain.ts +27 -3
- package/src/evm/index.ts +25 -9
- package/src/index.ts +1 -1
- package/src/requests.ts +13 -1
- package/src/selectors.ts +20 -0
- package/src/solana/index.ts +99 -7
- package/src/sui/index.ts +61 -28
- package/src/sui/manuallyExec/encoder.ts +2 -0
- package/src/sui/manuallyExec/index.ts +2 -0
- package/src/sui/objects.ts +3 -1
- package/src/ton/hasher.ts +2 -0
- package/src/ton/index.ts +2 -0
- package/src/types.ts +11 -2
- package/src/utils.ts +2 -0
package/src/chain.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type BytesLike, dataLength } from 'ethers'
|
|
2
2
|
import type { PickDeep, SetOptional } from 'type-fest'
|
|
3
3
|
|
|
4
4
|
import { type LaneLatencyResponse, CCIPAPIClient } from './api/index.ts'
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
CCIPExecTxRevertedError,
|
|
11
11
|
CCIPTransactionNotFinalizedError,
|
|
12
12
|
} from './errors/index.ts'
|
|
13
|
+
import { DEFAULT_GAS_LIMIT } from './evm/const.ts'
|
|
13
14
|
import type { UnsignedEVMTx } from './evm/types.ts'
|
|
14
15
|
import type {
|
|
15
16
|
EVMExtraArgsV1,
|
|
@@ -37,6 +38,7 @@ import {
|
|
|
37
38
|
type Logger,
|
|
38
39
|
type NetworkInfo,
|
|
39
40
|
type OffchainTokenData,
|
|
41
|
+
type MessageInput,
|
|
40
42
|
type WithLogger,
|
|
41
43
|
ExecutionState,
|
|
42
44
|
} from './types.ts'
|
|
@@ -153,7 +155,7 @@ export type UnsignedTx = {
|
|
|
153
155
|
}
|
|
154
156
|
|
|
155
157
|
/**
|
|
156
|
-
* Common options for [[generateUnsignedSendMessage]] and [[sendMessage]] Chain methods
|
|
158
|
+
* Common options for [[getFee]], [[generateUnsignedSendMessage]] and [[sendMessage]] Chain methods
|
|
157
159
|
*/
|
|
158
160
|
export type SendMessageOpts = {
|
|
159
161
|
/** Router address on this chain */
|
|
@@ -161,7 +163,7 @@ export type SendMessageOpts = {
|
|
|
161
163
|
/** Destination network selector. */
|
|
162
164
|
destChainSelector: bigint
|
|
163
165
|
/** Message to send. If `fee` is omitted, it'll be calculated */
|
|
164
|
-
message:
|
|
166
|
+
message: MessageInput
|
|
165
167
|
/** Approve the maximum amount of tokens to transfer */
|
|
166
168
|
approveMax?: boolean
|
|
167
169
|
}
|
|
@@ -690,6 +692,21 @@ export abstract class Chain<F extends ChainFamily = ChainFamily> {
|
|
|
690
692
|
* @returns Mapping of token addresses to respective TokenInfo objects.
|
|
691
693
|
*/
|
|
692
694
|
abstract getFeeTokens(router: string): Promise<Record<string, TokenInfo>>
|
|
695
|
+
|
|
696
|
+
/** {@inheritDoc ChainStatic.buildMessageForDest} */
|
|
697
|
+
static buildMessageForDest(
|
|
698
|
+
message: Parameters<ChainStatic['buildMessageForDest']>[0],
|
|
699
|
+
): AnyMessage {
|
|
700
|
+
// default to GenericExtraArgsV2, aka EVMExtraArgsV2
|
|
701
|
+
return {
|
|
702
|
+
...message,
|
|
703
|
+
extraArgs: {
|
|
704
|
+
gasLimit: message.data && dataLength(message.data) ? DEFAULT_GAS_LIMIT : 0n,
|
|
705
|
+
allowOutOfOrderExecution: true,
|
|
706
|
+
...message.extraArgs,
|
|
707
|
+
},
|
|
708
|
+
}
|
|
709
|
+
}
|
|
693
710
|
}
|
|
694
711
|
|
|
695
712
|
/** Static methods and properties available on Chain class constructors. */
|
|
@@ -775,6 +792,13 @@ export type ChainStatic<F extends ChainFamily = ChainFamily> = Function & {
|
|
|
775
792
|
* @returns Ordered record with messages/properties, or undefined if not a recognized error
|
|
776
793
|
*/
|
|
777
794
|
parse?(data: unknown): Record<string, unknown> | undefined | null
|
|
795
|
+
/**
|
|
796
|
+
* Returns a copy of a message, populating missing fields like `extraArgs` with defaults
|
|
797
|
+
* It's expected to return a message suitable at least for basic token transfers
|
|
798
|
+
* @param message - AnyMessage (from source), containing at least `receiver`
|
|
799
|
+
* @returns A message suitable for `sendMessage` to this destination chain family
|
|
800
|
+
*/
|
|
801
|
+
buildMessageForDest(message: MessageInput): AnyMessage
|
|
778
802
|
}
|
|
779
803
|
|
|
780
804
|
/** Function type for getting a Chain instance by ID, selector, or name. */
|
package/src/evm/index.ts
CHANGED
|
@@ -116,7 +116,12 @@ import {
|
|
|
116
116
|
parseSourceTokenData,
|
|
117
117
|
} from './messages.ts'
|
|
118
118
|
import { encodeEVMOffchainTokenData, fetchEVMOffchainTokenData } from './offchain.ts'
|
|
119
|
-
import {
|
|
119
|
+
import {
|
|
120
|
+
buildMessageForDest,
|
|
121
|
+
getMessageById,
|
|
122
|
+
getMessagesInBatch,
|
|
123
|
+
getMessagesInTx,
|
|
124
|
+
} from '../requests.ts'
|
|
120
125
|
import type { UnsignedEVMTx } from './types.ts'
|
|
121
126
|
export type { UnsignedEVMTx }
|
|
122
127
|
|
|
@@ -960,17 +965,20 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
960
965
|
destChainSelector,
|
|
961
966
|
message,
|
|
962
967
|
}: Parameters<Chain['getFee']>[0]): Promise<bigint> {
|
|
968
|
+
const populatedMessage = buildMessageForDest(message, networkInfo(destChainSelector).family)
|
|
963
969
|
const contract = new Contract(
|
|
964
970
|
router,
|
|
965
971
|
interfaces.Router,
|
|
966
972
|
this.provider,
|
|
967
973
|
) as unknown as TypedContract<typeof Router_ABI>
|
|
968
974
|
return contract.getFee(destChainSelector, {
|
|
969
|
-
receiver: zeroPadValue(getAddressBytes(
|
|
970
|
-
data: hexlify(
|
|
971
|
-
tokenAmounts:
|
|
972
|
-
feeToken:
|
|
973
|
-
extraArgs: hexlify(
|
|
975
|
+
receiver: zeroPadValue(getAddressBytes(populatedMessage.receiver), 32),
|
|
976
|
+
data: hexlify(populatedMessage.data ?? '0x'),
|
|
977
|
+
tokenAmounts: populatedMessage.tokenAmounts ?? [],
|
|
978
|
+
feeToken: populatedMessage.feeToken ?? ZeroAddress,
|
|
979
|
+
extraArgs: hexlify(
|
|
980
|
+
(this.constructor as typeof EVMChain).encodeExtraArgs(populatedMessage.extraArgs),
|
|
981
|
+
),
|
|
974
982
|
})
|
|
975
983
|
}
|
|
976
984
|
|
|
@@ -982,11 +990,19 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
982
990
|
async generateUnsignedSendMessage(
|
|
983
991
|
opts: Parameters<Chain['generateUnsignedSendMessage']>[0],
|
|
984
992
|
): Promise<UnsignedEVMTx> {
|
|
985
|
-
const { sender, router, destChainSelector
|
|
986
|
-
|
|
993
|
+
const { sender, router, destChainSelector } = opts
|
|
994
|
+
const populatedMessage = buildMessageForDest(
|
|
995
|
+
opts.message,
|
|
996
|
+
networkInfo(destChainSelector).family,
|
|
997
|
+
)
|
|
998
|
+
const message = {
|
|
999
|
+
...populatedMessage,
|
|
1000
|
+
fee: opts.message.fee ?? (await this.getFee({ ...opts, message: populatedMessage })),
|
|
1001
|
+
}
|
|
1002
|
+
|
|
987
1003
|
const feeToken = message.feeToken ?? ZeroAddress
|
|
988
1004
|
const receiver = zeroPadValue(getAddressBytes(message.receiver), 32)
|
|
989
|
-
const data = hexlify(message.data)
|
|
1005
|
+
const data = hexlify(message.data ?? '0x')
|
|
990
1006
|
const extraArgs = hexlify(
|
|
991
1007
|
(this.constructor as typeof EVMChain).encodeExtraArgs(message.extraArgs),
|
|
992
1008
|
)
|
package/src/index.ts
CHANGED
|
@@ -24,7 +24,6 @@ export {
|
|
|
24
24
|
export { estimateExecGasForRequest } from './gas.ts'
|
|
25
25
|
export { decodeMessage, getMessagesForSender, sourceToDestTokenAmounts } from './requests.ts'
|
|
26
26
|
export {
|
|
27
|
-
type AnyMessage,
|
|
28
27
|
type CCIPCommit,
|
|
29
28
|
type CCIPExecution,
|
|
30
29
|
type CCIPMessage,
|
|
@@ -37,6 +36,7 @@ export {
|
|
|
37
36
|
type Logger,
|
|
38
37
|
type NetworkInfo,
|
|
39
38
|
type OffchainTokenData,
|
|
39
|
+
type MessageInput,
|
|
40
40
|
type WithLogger,
|
|
41
41
|
CCIPVersion,
|
|
42
42
|
ExecutionState,
|
package/src/requests.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { isBytesLike, toBigInt } from 'ethers'
|
|
|
2
2
|
import type { PickDeep } from 'type-fest'
|
|
3
3
|
import yaml from 'yaml'
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import { type ChainStatic, type LogFilter, Chain } from './chain.ts'
|
|
6
6
|
import {
|
|
7
7
|
CCIPMessageBatchIncompleteError,
|
|
8
8
|
CCIPMessageDecodeError,
|
|
@@ -16,11 +16,13 @@ import type { EVMChain } from './evm/index.ts'
|
|
|
16
16
|
import { decodeExtraArgs } from './extra-args.ts'
|
|
17
17
|
import { supportedChains } from './supported-chains.ts'
|
|
18
18
|
import {
|
|
19
|
+
type AnyMessage,
|
|
19
20
|
type CCIPMessage,
|
|
20
21
|
type CCIPRequest,
|
|
21
22
|
type CCIPVersion,
|
|
22
23
|
type ChainTransaction,
|
|
23
24
|
type Log_,
|
|
25
|
+
type MessageInput,
|
|
24
26
|
ChainFamily,
|
|
25
27
|
} from './types.ts'
|
|
26
28
|
import { convertKeysToCamelCase, decodeAddress, leToBigInt, networkInfo } from './utils.ts'
|
|
@@ -109,6 +111,16 @@ export function decodeMessage(data: string | Uint8Array | Record<string, unknown
|
|
|
109
111
|
throw new CCIPMessageDecodeError()
|
|
110
112
|
}
|
|
111
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Populates missing required fields (e.g. `extraArgs`) from AnyMessage
|
|
116
|
+
* @param message - partial AnyMessage
|
|
117
|
+
* @returns original message or shallow copy with defaults for required fields
|
|
118
|
+
**/
|
|
119
|
+
export function buildMessageForDest(message: MessageInput, dest: ChainFamily): AnyMessage {
|
|
120
|
+
const chain = supportedChains[dest] ?? Chain
|
|
121
|
+
return chain.buildMessageForDest(message)
|
|
122
|
+
}
|
|
123
|
+
|
|
112
124
|
/**
|
|
113
125
|
* Fetch all CCIP messages in a transaction
|
|
114
126
|
* @param source - Chain
|
package/src/selectors.ts
CHANGED
|
@@ -453,6 +453,11 @@ const selectors: Selectors = {
|
|
|
453
453
|
name: 'story-testnet',
|
|
454
454
|
family: 'evm',
|
|
455
455
|
},
|
|
456
|
+
'1672': {
|
|
457
|
+
selector: 7801139999541420232n,
|
|
458
|
+
name: 'pharos-mainnet',
|
|
459
|
+
family: 'evm',
|
|
460
|
+
},
|
|
456
461
|
'1687': {
|
|
457
462
|
selector: 10749384167430721561n,
|
|
458
463
|
name: 'mint-testnet',
|
|
@@ -759,6 +764,11 @@ const selectors: Selectors = {
|
|
|
759
764
|
name: 'ethereum-testnet-sepolia-immutable-zkevm-1',
|
|
760
765
|
family: 'evm',
|
|
761
766
|
},
|
|
767
|
+
'14601': {
|
|
768
|
+
selector: 1763698235108410440n,
|
|
769
|
+
name: 'sonic-testnet',
|
|
770
|
+
family: 'evm',
|
|
771
|
+
},
|
|
762
772
|
'16600': {
|
|
763
773
|
selector: 16088006396410204581n,
|
|
764
774
|
name: '0g-testnet-newton',
|
|
@@ -807,6 +817,11 @@ const selectors: Selectors = {
|
|
|
807
817
|
family: 'evm',
|
|
808
818
|
},
|
|
809
819
|
'36888': { selector: 4829375610284793157n, name: 'ab-mainnet', family: 'evm' },
|
|
820
|
+
'36900': {
|
|
821
|
+
selector: 4059281736450291836n,
|
|
822
|
+
name: 'adi-mainnet',
|
|
823
|
+
family: 'evm',
|
|
824
|
+
},
|
|
810
825
|
'37111': {
|
|
811
826
|
selector: 6827576821754315911n,
|
|
812
827
|
name: 'ethereum-testnet-sepolia-lens-1',
|
|
@@ -1009,6 +1024,11 @@ const selectors: Selectors = {
|
|
|
1009
1024
|
name: 'plume-testnet-sepolia',
|
|
1010
1025
|
family: 'evm',
|
|
1011
1026
|
},
|
|
1027
|
+
'99999': {
|
|
1028
|
+
selector: 9418205736192840573n,
|
|
1029
|
+
name: 'adi-testnet',
|
|
1030
|
+
family: 'evm',
|
|
1031
|
+
},
|
|
1012
1032
|
'128123': {
|
|
1013
1033
|
selector: 1910019406958449359n,
|
|
1014
1034
|
name: 'etherlink-testnet',
|
package/src/solana/index.ts
CHANGED
|
@@ -26,16 +26,18 @@ import {
|
|
|
26
26
|
toBigInt,
|
|
27
27
|
} from 'ethers'
|
|
28
28
|
import { type Memoized, memoize } from 'micro-memoize'
|
|
29
|
-
import type { PickDeep
|
|
29
|
+
import type { PickDeep } from 'type-fest'
|
|
30
30
|
|
|
31
31
|
import {
|
|
32
32
|
type ChainContext,
|
|
33
|
+
type ChainStatic,
|
|
33
34
|
type LogFilter,
|
|
34
35
|
type TokenInfo,
|
|
35
36
|
type TokenPoolRemote,
|
|
36
37
|
Chain,
|
|
37
38
|
} from '../chain.ts'
|
|
38
39
|
import {
|
|
40
|
+
CCIPArgumentInvalidError,
|
|
39
41
|
CCIPBlockTimeNotFoundError,
|
|
40
42
|
CCIPContractNotRouterError,
|
|
41
43
|
CCIPDataFormatUnsupportedError,
|
|
@@ -59,11 +61,17 @@ import {
|
|
|
59
61
|
CCIPTransactionNotFoundError,
|
|
60
62
|
CCIPWalletInvalidError,
|
|
61
63
|
} from '../errors/index.ts'
|
|
62
|
-
import {
|
|
64
|
+
import {
|
|
65
|
+
type EVMExtraArgsV2,
|
|
66
|
+
type ExtraArgs,
|
|
67
|
+
type SVMExtraArgsV1,
|
|
68
|
+
EVMExtraArgsV2Tag,
|
|
69
|
+
} from '../extra-args.ts'
|
|
63
70
|
import type { LeafHasher } from '../hasher/common.ts'
|
|
64
71
|
import SELECTORS from '../selectors.ts'
|
|
65
72
|
import { supportedChains } from '../supported-chains.ts'
|
|
66
73
|
import {
|
|
74
|
+
type AnyMessage,
|
|
67
75
|
type CCIPCommit,
|
|
68
76
|
type CCIPExecution,
|
|
69
77
|
type CCIPMessage,
|
|
@@ -114,8 +122,14 @@ import {
|
|
|
114
122
|
simulateAndSendTxs,
|
|
115
123
|
simulationProvider,
|
|
116
124
|
} from './utils.ts'
|
|
117
|
-
import {
|
|
125
|
+
import {
|
|
126
|
+
buildMessageForDest,
|
|
127
|
+
getMessageById,
|
|
128
|
+
getMessagesInBatch,
|
|
129
|
+
getMessagesInTx,
|
|
130
|
+
} from '../requests.ts'
|
|
118
131
|
import { patchBorsh } from './patchBorsh.ts'
|
|
132
|
+
import { DEFAULT_GAS_LIMIT } from '../evm/const.ts'
|
|
119
133
|
export type { UnsignedSolanaTx }
|
|
120
134
|
|
|
121
135
|
const routerCoder = new BorshCoder(CCIP_ROUTER_IDL)
|
|
@@ -976,7 +990,8 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
976
990
|
|
|
977
991
|
/** {@inheritDoc Chain.getFee} */
|
|
978
992
|
getFee({ router, destChainSelector, message }: Parameters<Chain['getFee']>[0]): Promise<bigint> {
|
|
979
|
-
|
|
993
|
+
const populatedMessage = buildMessageForDest(message, networkInfo(destChainSelector).family)
|
|
994
|
+
return getFee(this, router, destChainSelector, populatedMessage)
|
|
980
995
|
}
|
|
981
996
|
|
|
982
997
|
/**
|
|
@@ -988,14 +1003,21 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
988
1003
|
async generateUnsignedSendMessage(
|
|
989
1004
|
opts: Parameters<Chain['generateUnsignedSendMessage']>[0],
|
|
990
1005
|
): Promise<UnsignedSolanaTx> {
|
|
991
|
-
const { sender, router, destChainSelector
|
|
992
|
-
|
|
1006
|
+
const { sender, router, destChainSelector } = opts
|
|
1007
|
+
const populatedMessage = buildMessageForDest(
|
|
1008
|
+
opts.message,
|
|
1009
|
+
networkInfo(destChainSelector).family,
|
|
1010
|
+
)
|
|
1011
|
+
const message = {
|
|
1012
|
+
...populatedMessage,
|
|
1013
|
+
fee: opts.message.fee ?? (await this.getFee({ ...opts, message: populatedMessage })),
|
|
1014
|
+
}
|
|
993
1015
|
return generateUnsignedCcipSend(
|
|
994
1016
|
this,
|
|
995
1017
|
new PublicKey(sender),
|
|
996
1018
|
new PublicKey(router),
|
|
997
1019
|
destChainSelector,
|
|
998
|
-
message
|
|
1020
|
+
message,
|
|
999
1021
|
opts,
|
|
1000
1022
|
)
|
|
1001
1023
|
}
|
|
@@ -1479,4 +1501,74 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1479
1501
|
// the offramps, so we can use it to narrow the search for the offramp
|
|
1480
1502
|
return program.account.config.fetch(configPda)
|
|
1481
1503
|
}
|
|
1504
|
+
|
|
1505
|
+
/** {@inheritDoc ChainStatic.buildMessageForDest} */
|
|
1506
|
+
static override buildMessageForDest(
|
|
1507
|
+
message: Parameters<ChainStatic['buildMessageForDest']>[0],
|
|
1508
|
+
): AnyMessage & { extraArgs: SVMExtraArgsV1 } {
|
|
1509
|
+
if (
|
|
1510
|
+
!(
|
|
1511
|
+
message.extraArgs &&
|
|
1512
|
+
'tokenReceiver' in message.extraArgs &&
|
|
1513
|
+
message.extraArgs.tokenReceiver
|
|
1514
|
+
) &&
|
|
1515
|
+
message.data &&
|
|
1516
|
+
getDataBytes(message.data).length &&
|
|
1517
|
+
message.tokenAmounts?.length
|
|
1518
|
+
)
|
|
1519
|
+
throw new CCIPArgumentInvalidError(
|
|
1520
|
+
'tokenReceiver',
|
|
1521
|
+
'required when sending tokens with data to Solana',
|
|
1522
|
+
)
|
|
1523
|
+
|
|
1524
|
+
const computeUnits =
|
|
1525
|
+
message.extraArgs &&
|
|
1526
|
+
'computeUnits' in message.extraArgs &&
|
|
1527
|
+
message.extraArgs.computeUnits != null
|
|
1528
|
+
? message.extraArgs.computeUnits
|
|
1529
|
+
: message.extraArgs && 'gasLimit' in message.extraArgs && message.extraArgs.gasLimit != null
|
|
1530
|
+
? message.extraArgs.gasLimit // populates computeUnits from gasLimit
|
|
1531
|
+
: message.data && getDataBytes(message.data).length
|
|
1532
|
+
? DEFAULT_GAS_LIMIT
|
|
1533
|
+
: 0n
|
|
1534
|
+
const allowOutOfOrderExecution =
|
|
1535
|
+
message.extraArgs &&
|
|
1536
|
+
'allowOutOfOrderExecution' in message.extraArgs &&
|
|
1537
|
+
message.extraArgs.allowOutOfOrderExecution != null
|
|
1538
|
+
? message.extraArgs.allowOutOfOrderExecution
|
|
1539
|
+
: true
|
|
1540
|
+
const tokenReceiver =
|
|
1541
|
+
message.extraArgs &&
|
|
1542
|
+
'tokenReceiver' in message.extraArgs &&
|
|
1543
|
+
message.extraArgs.tokenReceiver != null
|
|
1544
|
+
? message.extraArgs.tokenReceiver
|
|
1545
|
+
: message.tokenAmounts?.length
|
|
1546
|
+
? this.getAddress(message.receiver)
|
|
1547
|
+
: PublicKey.default.toBase58()
|
|
1548
|
+
const accounts =
|
|
1549
|
+
message.extraArgs && 'accounts' in message.extraArgs && message.extraArgs.accounts != null
|
|
1550
|
+
? message.extraArgs.accounts
|
|
1551
|
+
: []
|
|
1552
|
+
const accountIsWritableBitmap =
|
|
1553
|
+
message.extraArgs &&
|
|
1554
|
+
'accountIsWritableBitmap' in message.extraArgs &&
|
|
1555
|
+
message.extraArgs.accountIsWritableBitmap != null
|
|
1556
|
+
? message.extraArgs.accountIsWritableBitmap
|
|
1557
|
+
: 0n
|
|
1558
|
+
|
|
1559
|
+
const extraArgs: SVMExtraArgsV1 = {
|
|
1560
|
+
computeUnits,
|
|
1561
|
+
allowOutOfOrderExecution,
|
|
1562
|
+
tokenReceiver,
|
|
1563
|
+
accounts,
|
|
1564
|
+
accountIsWritableBitmap,
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
return {
|
|
1568
|
+
...message,
|
|
1569
|
+
extraArgs,
|
|
1570
|
+
// if tokenReceiver, then message.receiver can (must?) be default
|
|
1571
|
+
...(!!message.tokenAmounts?.length && { receiver: PublicKey.default.toBase58() }),
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1482
1574
|
}
|
package/src/sui/index.ts
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Buffer } from 'buffer'
|
|
2
|
+
|
|
2
3
|
import { type SuiTransactionBlockResponse, SuiClient } from '@mysten/sui/client'
|
|
3
4
|
import type { Keypair } from '@mysten/sui/cryptography'
|
|
4
5
|
import { SuiGraphQLClient } from '@mysten/sui/graphql'
|
|
5
6
|
import { Transaction } from '@mysten/sui/transactions'
|
|
6
|
-
import { type BytesLike,
|
|
7
|
+
import { type BytesLike, dataLength, hexlify, isBytesLike } from 'ethers'
|
|
7
8
|
import type { PickDeep } from 'type-fest'
|
|
8
9
|
|
|
9
10
|
import { AptosChain } from '../aptos/index.ts'
|
|
10
|
-
import { type ChainContext, type LogFilter, Chain } from '../chain.ts'
|
|
11
|
+
import { type ChainContext, type ChainStatic, type LogFilter, Chain } from '../chain.ts'
|
|
11
12
|
import {
|
|
12
13
|
CCIPContractNotRouterError,
|
|
13
14
|
CCIPDataFormatUnsupportedError,
|
|
14
15
|
CCIPError,
|
|
15
16
|
CCIPErrorCode,
|
|
16
17
|
CCIPExecTxRevertedError,
|
|
17
|
-
CCIPExtraArgsInvalidError,
|
|
18
18
|
CCIPNotImplementedError,
|
|
19
19
|
CCIPSuiMessageVersionInvalidError,
|
|
20
20
|
CCIPVersionFeatureUnavailableError,
|
|
21
21
|
} from '../errors/index.ts'
|
|
22
|
-
import type { ExtraArgs, SuiExtraArgsV1 } from '../extra-args.ts'
|
|
22
|
+
import type { EVMExtraArgsV2, ExtraArgs, SVMExtraArgsV1, SuiExtraArgsV1 } from '../extra-args.ts'
|
|
23
23
|
import { getSuiLeafHasher } from './hasher.ts'
|
|
24
24
|
import type { LeafHasher } from '../hasher/common.ts'
|
|
25
25
|
import { supportedChains } from '../supported-chains.ts'
|
|
26
26
|
import {
|
|
27
|
+
type AnyMessage,
|
|
27
28
|
type CCIPExecution,
|
|
28
29
|
type CCIPMessage,
|
|
29
30
|
type CCIPRequest,
|
|
@@ -42,7 +43,7 @@ import {
|
|
|
42
43
|
} from '../types.ts'
|
|
43
44
|
import { discoverCCIP, discoverOfframp } from './discovery.ts'
|
|
44
45
|
import type { CCIPMessage_V1_6_Sui } from './types.ts'
|
|
45
|
-
import { bytesToBuffer, decodeAddress,
|
|
46
|
+
import { bytesToBuffer, decodeAddress, networkInfo } from '../utils.ts'
|
|
46
47
|
import { type CommitEvent, getSuiEventsInTimeRange } from './events.ts'
|
|
47
48
|
import {
|
|
48
49
|
type SuiManuallyExecuteInput,
|
|
@@ -57,6 +58,7 @@ import {
|
|
|
57
58
|
} from './objects.ts'
|
|
58
59
|
|
|
59
60
|
export const SUI_EXTRA_ARGS_V1_TAG = '21ea4ca9' as const
|
|
61
|
+
const DEFAULT_GAS_LIMIT = 1000000n
|
|
60
62
|
|
|
61
63
|
type SuiContractDir = {
|
|
62
64
|
ccip?: string
|
|
@@ -438,28 +440,11 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
438
440
|
*/
|
|
439
441
|
static decodeExtraArgs(
|
|
440
442
|
extraArgs: BytesLike,
|
|
441
|
-
):
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
const abiData = '0x' + hexBytes.slice(8)
|
|
449
|
-
const decoded = AbiCoder.defaultAbiCoder().decode(
|
|
450
|
-
['tuple(uint256,bool,bytes32,bytes32[])'],
|
|
451
|
-
abiData,
|
|
452
|
-
)
|
|
453
|
-
|
|
454
|
-
const tuple = decoded[0] as readonly [bigint, boolean, string, string[]]
|
|
455
|
-
|
|
456
|
-
return {
|
|
457
|
-
gasLimit: tuple[0],
|
|
458
|
-
allowOutOfOrderExecution: tuple[1],
|
|
459
|
-
tokenReceiver: tuple[2],
|
|
460
|
-
receiverObjectIds: tuple[3], // Already an array of hex strings
|
|
461
|
-
_tag: 'SuiExtraArgsV1',
|
|
462
|
-
}
|
|
443
|
+
):
|
|
444
|
+
| (EVMExtraArgsV2 & { _tag: 'EVMExtraArgsV2' })
|
|
445
|
+
| (SVMExtraArgsV1 & { _tag: 'SVMExtraArgsV1' })
|
|
446
|
+
| undefined {
|
|
447
|
+
return AptosChain.decodeExtraArgs(extraArgs)
|
|
463
448
|
}
|
|
464
449
|
|
|
465
450
|
/**
|
|
@@ -743,4 +728,52 @@ export class SuiChain extends Chain<typeof ChainFamily.Sui> {
|
|
|
743
728
|
async getFeeTokens(_router: string): Promise<never> {
|
|
744
729
|
return Promise.reject(new CCIPNotImplementedError('SuiChain.getFeeTokens'))
|
|
745
730
|
}
|
|
731
|
+
|
|
732
|
+
/** {@inheritDoc ChainStatic.buildMessageForDest} */
|
|
733
|
+
static override buildMessageForDest(
|
|
734
|
+
message: Parameters<ChainStatic['buildMessageForDest']>[0],
|
|
735
|
+
): AnyMessage & { extraArgs: SuiExtraArgsV1 } {
|
|
736
|
+
const gasLimit =
|
|
737
|
+
message.extraArgs && 'gasLimit' in message.extraArgs && message.extraArgs.gasLimit != null
|
|
738
|
+
? message.extraArgs.gasLimit
|
|
739
|
+
: message.data && dataLength(message.data)
|
|
740
|
+
? DEFAULT_GAS_LIMIT
|
|
741
|
+
: 0n
|
|
742
|
+
const allowOutOfOrderExecution =
|
|
743
|
+
message.extraArgs &&
|
|
744
|
+
'allowOutOfOrderExecution' in message.extraArgs &&
|
|
745
|
+
message.extraArgs.allowOutOfOrderExecution != null
|
|
746
|
+
? message.extraArgs.allowOutOfOrderExecution
|
|
747
|
+
: true
|
|
748
|
+
const tokenReceiver =
|
|
749
|
+
message.extraArgs &&
|
|
750
|
+
'tokenReceiver' in message.extraArgs &&
|
|
751
|
+
message.extraArgs.tokenReceiver != null
|
|
752
|
+
? message.extraArgs.tokenReceiver
|
|
753
|
+
: message.tokenAmounts?.length
|
|
754
|
+
? this.getAddress(message.receiver)
|
|
755
|
+
: '0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
756
|
+
const receiverObjectIds =
|
|
757
|
+
message.extraArgs &&
|
|
758
|
+
'receiverObjectIds' in message.extraArgs &&
|
|
759
|
+
message.extraArgs.receiverObjectIds?.length
|
|
760
|
+
? message.extraArgs.receiverObjectIds
|
|
761
|
+
: message.extraArgs && 'accounts' in message.extraArgs && message.extraArgs.accounts?.length
|
|
762
|
+
? message.extraArgs.accounts // populates receiverObjectIds from accounts
|
|
763
|
+
: []
|
|
764
|
+
const extraArgs: SuiExtraArgsV1 = {
|
|
765
|
+
gasLimit,
|
|
766
|
+
allowOutOfOrderExecution,
|
|
767
|
+
tokenReceiver,
|
|
768
|
+
receiverObjectIds,
|
|
769
|
+
}
|
|
770
|
+
return {
|
|
771
|
+
...message,
|
|
772
|
+
extraArgs,
|
|
773
|
+
// if tokenReceiver, then message.receiver can (must?) be default
|
|
774
|
+
...(!!message.tokenAmounts?.length && {
|
|
775
|
+
receiver: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
776
|
+
}),
|
|
777
|
+
}
|
|
778
|
+
}
|
|
746
779
|
}
|
package/src/sui/objects.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { Buffer } from 'buffer'
|
|
2
|
+
|
|
1
3
|
import { bcs } from '@mysten/sui/bcs'
|
|
2
4
|
import type { SuiClient } from '@mysten/sui/client'
|
|
3
5
|
import { Transaction } from '@mysten/sui/transactions'
|
|
4
6
|
import { normalizeSuiAddress } from '@mysten/sui/utils'
|
|
5
|
-
import { blake2b } from '@noble/hashes/blake2'
|
|
7
|
+
import { blake2b } from '@noble/hashes/blake2.js'
|
|
6
8
|
|
|
7
9
|
import { CCIPDataFormatUnsupportedError } from '../errors/index.ts'
|
|
8
10
|
import type { CCIPMessage, CCIPVersion } from '../types.ts'
|
package/src/ton/hasher.ts
CHANGED
package/src/ton/index.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -294,12 +294,21 @@ export type ExecutionReport<M extends CCIPMessage = CCIPMessage> = {
|
|
|
294
294
|
export type AnyMessage = {
|
|
295
295
|
/** Receiver address on the destination chain. */
|
|
296
296
|
receiver: BytesLike
|
|
297
|
-
/** Arbitrary data payload. */
|
|
298
|
-
data: BytesLike
|
|
299
297
|
/** Extra arguments for gas limits and other settings. */
|
|
300
298
|
extraArgs: ExtraArgs
|
|
299
|
+
/** Arbitrary data payload. */
|
|
300
|
+
data?: BytesLike
|
|
301
301
|
/** Optional token transfers. */
|
|
302
302
|
tokenAmounts?: readonly { token: string; amount: bigint }[]
|
|
303
303
|
/** Optional fee token address (native if omitted). */
|
|
304
304
|
feeToken?: string
|
|
305
305
|
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Partial [[AnyMessage]], which populates default fields like `extraArgs` if needed
|
|
309
|
+
*/
|
|
310
|
+
export type MessageInput = Partial<AnyMessage> & {
|
|
311
|
+
receiver: AnyMessage['receiver']
|
|
312
|
+
extraArgs?: Partial<ExtraArgs>
|
|
313
|
+
fee?: bigint
|
|
314
|
+
}
|