@chainlink/ccip-sdk 1.3.1 → 1.4.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 +17 -6
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +17 -6
- package/dist/api/index.js.map +1 -1
- package/dist/aptos/index.d.ts +7 -1
- package/dist/aptos/index.d.ts.map +1 -1
- package/dist/aptos/index.js +20 -0
- package/dist/aptos/index.js.map +1 -1
- package/dist/chain.d.ts +64 -6
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js +37 -2
- package/dist/chain.js.map +1 -1
- package/dist/errors/recovery.js +1 -1
- package/dist/errors/specialized.d.ts +17 -3
- package/dist/errors/specialized.d.ts.map +1 -1
- package/dist/errors/specialized.js +17 -3
- package/dist/errors/specialized.js.map +1 -1
- package/dist/evm/const.d.ts.map +1 -1
- package/dist/evm/const.js +1 -0
- package/dist/evm/const.js.map +1 -1
- package/dist/evm/errors.d.ts.map +1 -1
- package/dist/evm/errors.js +20 -5
- package/dist/evm/errors.js.map +1 -1
- package/dist/evm/index.d.ts +11 -2
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +65 -14
- package/dist/evm/index.js.map +1 -1
- package/dist/gas.d.ts +2 -1
- package/dist/gas.d.ts.map +1 -1
- package/dist/gas.js +2 -1
- package/dist/gas.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/offchain.d.ts +1 -0
- package/dist/offchain.d.ts.map +1 -1
- package/dist/offchain.js +1 -0
- package/dist/offchain.js.map +1 -1
- package/dist/requests.d.ts +6 -5
- package/dist/requests.d.ts.map +1 -1
- package/dist/requests.js +6 -5
- package/dist/requests.js.map +1 -1
- package/dist/solana/idl/1.6.0/FEE_QUOTER.d.ts +1719 -0
- package/dist/solana/idl/1.6.0/FEE_QUOTER.d.ts.map +1 -0
- package/dist/solana/idl/1.6.0/FEE_QUOTER.js +1719 -0
- package/dist/solana/idl/1.6.0/FEE_QUOTER.js.map +1 -0
- package/dist/solana/index.d.ts +17 -1
- package/dist/solana/index.d.ts.map +1 -1
- package/dist/solana/index.js +32 -0
- package/dist/solana/index.js.map +1 -1
- package/dist/solana/utils.d.ts +5 -2
- package/dist/solana/utils.d.ts.map +1 -1
- package/dist/solana/utils.js +5 -2
- package/dist/solana/utils.js.map +1 -1
- package/dist/sui/index.d.ts +1 -1
- package/dist/sui/index.d.ts.map +1 -1
- package/dist/sui/index.js +1 -1
- package/dist/sui/index.js.map +1 -1
- package/dist/ton/index.d.ts +11 -9
- package/dist/ton/index.d.ts.map +1 -1
- package/dist/ton/index.js +11 -9
- package/dist/ton/index.js.map +1 -1
- package/dist/ton/send.d.ts +7 -0
- package/dist/ton/send.d.ts.map +1 -1
- package/dist/ton/send.js +7 -0
- package/dist/ton/send.js.map +1 -1
- package/dist/utils.d.ts +9 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +9 -2
- package/dist/utils.js.map +1 -1
- package/package.json +7 -7
- package/src/api/index.ts +17 -6
- package/src/aptos/index.ts +31 -0
- package/src/chain.ts +67 -7
- package/src/errors/recovery.ts +1 -1
- package/src/errors/specialized.ts +17 -3
- package/src/evm/const.ts +1 -0
- package/src/evm/errors.ts +22 -5
- package/src/evm/index.ts +102 -13
- package/src/gas.ts +2 -1
- package/src/index.ts +1 -0
- package/src/offchain.ts +1 -0
- package/src/requests.ts +6 -5
- package/src/solana/idl/1.6.0/FEE_QUOTER.ts +3440 -0
- package/src/solana/index.ts +49 -0
- package/src/solana/utils.ts +5 -2
- package/src/sui/index.ts +1 -1
- package/src/ton/index.ts +11 -9
- package/src/ton/send.ts +7 -0
- package/src/utils.ts +9 -2
package/src/evm/index.ts
CHANGED
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
type LogFilter,
|
|
35
35
|
type RateLimiterState,
|
|
36
36
|
type TokenPoolRemote,
|
|
37
|
+
type TokenPrice,
|
|
37
38
|
type TokenTransferFeeConfig,
|
|
38
39
|
type TokenTransferFeeOpts,
|
|
39
40
|
type TotalFeesEstimate,
|
|
@@ -56,7 +57,6 @@ import {
|
|
|
56
57
|
CCIPTokenNotConfiguredError,
|
|
57
58
|
CCIPTokenPoolChainConfigNotFoundError,
|
|
58
59
|
CCIPTransactionNotFoundError,
|
|
59
|
-
CCIPVersionFeatureUnavailableError,
|
|
60
60
|
CCIPVersionRequiresLaneError,
|
|
61
61
|
CCIPVersionUnsupportedError,
|
|
62
62
|
CCIPWalletInvalidError,
|
|
@@ -87,6 +87,7 @@ import {
|
|
|
87
87
|
decodeOnRampAddress,
|
|
88
88
|
getAddressBytes,
|
|
89
89
|
getDataBytes,
|
|
90
|
+
getSomeBlockNumberBefore,
|
|
90
91
|
networkInfo,
|
|
91
92
|
parseTypeAndVersion,
|
|
92
93
|
} from '../utils.ts'
|
|
@@ -250,6 +251,10 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
250
251
|
this.getFeeTokens = memoize(this.getFeeTokens.bind(this), { async: true, maxArgs: 1 })
|
|
251
252
|
this.detectUsdcDomains = memoize(this.detectUsdcDomains.bind(this))
|
|
252
253
|
this.resolveVerifier = memoize(this.resolveVerifier.bind(this))
|
|
254
|
+
this.getFeeQuoterFor = memoize(this.getFeeQuoterFor.bind(this), {
|
|
255
|
+
async: true,
|
|
256
|
+
maxArgs: 1,
|
|
257
|
+
})
|
|
253
258
|
}
|
|
254
259
|
|
|
255
260
|
/**
|
|
@@ -970,17 +975,26 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
970
975
|
* @throws {@link CCIPVersionFeatureUnavailableError} if contract version is below v1.6
|
|
971
976
|
*/
|
|
972
977
|
async getFeeQuoterFor(address: string): Promise<string> {
|
|
973
|
-
|
|
974
|
-
if (type === 'FeeQuoter') {
|
|
978
|
+
const [type, version, typeAndVersion] = await this.typeAndVersion(address)
|
|
979
|
+
if (type === 'FeeQuoter' || type === 'PriceRegistry') {
|
|
975
980
|
return address
|
|
976
981
|
} else if (type === 'Router') {
|
|
977
|
-
|
|
978
|
-
;[type, version, typeAndVersion] = await this.typeAndVersion(address)
|
|
982
|
+
return this.getFeeQuoterFor(await this._getSomeOnRampFor(address)) // use cache
|
|
979
983
|
} else if (!type.includes('Ramp')) {
|
|
980
984
|
throw new CCIPContractNotRouterError(address, typeAndVersion)
|
|
981
985
|
}
|
|
982
|
-
|
|
983
|
-
|
|
986
|
+
|
|
987
|
+
if (version < CCIPVersion.V1_6) {
|
|
988
|
+
const contract = new Contract(
|
|
989
|
+
address,
|
|
990
|
+
version === CCIPVersion.V1_2
|
|
991
|
+
? interfaces.EVM2EVMOnRamp_v1_2
|
|
992
|
+
: interfaces.EVM2EVMOnRamp_v1_5,
|
|
993
|
+
this.provider,
|
|
994
|
+
) as unknown as TypedContract<typeof EVM2EVMOnRamp_1_2_ABI | typeof EVM2EVMOnRamp_1_5_ABI>
|
|
995
|
+
const { priceRegistry } = await contract.getDynamicConfig()
|
|
996
|
+
return priceRegistry as string
|
|
997
|
+
}
|
|
984
998
|
|
|
985
999
|
const isOnRamp = type.includes('OnRamp')
|
|
986
1000
|
const contract = new Contract(
|
|
@@ -1017,7 +1031,10 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1017
1031
|
this.provider,
|
|
1018
1032
|
) as unknown as TypedContract<typeof Router_ABI>
|
|
1019
1033
|
return contract.getFee(destChainSelector, {
|
|
1020
|
-
receiver:
|
|
1034
|
+
receiver: (() => {
|
|
1035
|
+
const receiverBytes = getAddressBytes(populatedMessage.receiver)
|
|
1036
|
+
return receiverBytes.length <= 32 ? zeroPadValue(receiverBytes, 32) : hexlify(receiverBytes)
|
|
1037
|
+
})(),
|
|
1021
1038
|
data: hexlify(populatedMessage.data ?? '0x'),
|
|
1022
1039
|
tokenAmounts: populatedMessage.tokenAmounts ?? [],
|
|
1023
1040
|
feeToken: populatedMessage.feeToken ?? ZeroAddress,
|
|
@@ -1133,6 +1150,52 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1133
1150
|
return undefined
|
|
1134
1151
|
}
|
|
1135
1152
|
|
|
1153
|
+
/** {@inheritDoc Chain.getTokenPrice} */
|
|
1154
|
+
override async getTokenPrice(opts: {
|
|
1155
|
+
router: string
|
|
1156
|
+
token: string
|
|
1157
|
+
timestamp?: number
|
|
1158
|
+
}): Promise<TokenPrice> {
|
|
1159
|
+
let { token } = opts
|
|
1160
|
+
|
|
1161
|
+
// Resolve native token (ZeroAddress) to wrapped native
|
|
1162
|
+
if (token === ZeroAddress) {
|
|
1163
|
+
token = await this.getNativeTokenForRouter(opts.router)
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
const priceContractAddress = await this.getFeeQuoterFor(opts.router)
|
|
1167
|
+
|
|
1168
|
+
// Both PriceRegistry (v1.2/v1.5) and FeeQuoter (v1.6+) expose
|
|
1169
|
+
// getTokenPrice(address) → { value: uint224, timestamp: uint32 }
|
|
1170
|
+
const contract = new Contract(
|
|
1171
|
+
priceContractAddress,
|
|
1172
|
+
interfaces.FeeQuoter,
|
|
1173
|
+
this.provider,
|
|
1174
|
+
) as unknown as TypedContract<typeof FeeQuoter_ABI>
|
|
1175
|
+
|
|
1176
|
+
// If timestamp provided, resolve to block number for historical query
|
|
1177
|
+
let blockTag: number | undefined
|
|
1178
|
+
if (opts.timestamp != null) {
|
|
1179
|
+
const { number: latestBlock } = (await this.provider.getBlock('latest'))!
|
|
1180
|
+
blockTag = await getSomeBlockNumberBefore(
|
|
1181
|
+
async (block: number) => (await this.provider.getBlock(block))!.timestamp,
|
|
1182
|
+
latestBlock,
|
|
1183
|
+
opts.timestamp,
|
|
1184
|
+
this,
|
|
1185
|
+
)
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
const [result, { decimals }] = await Promise.all([
|
|
1189
|
+
blockTag != null
|
|
1190
|
+
? contract.getTokenPrice.staticCall(token, { blockTag })
|
|
1191
|
+
: contract.getTokenPrice(token),
|
|
1192
|
+
this.getTokenInfo(token),
|
|
1193
|
+
])
|
|
1194
|
+
|
|
1195
|
+
const rawPrice = BigInt(result.value)
|
|
1196
|
+
return { price: Number(rawPrice) * 10 ** (decimals - 36) }
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1136
1199
|
/** {@inheritDoc Chain.getTotalFeesEstimate} */
|
|
1137
1200
|
override async getTotalFeesEstimate(
|
|
1138
1201
|
opts: Parameters<Chain['getTotalFeesEstimate']>[0],
|
|
@@ -1152,7 +1215,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1152
1215
|
let tokenArgs: string = '0x'
|
|
1153
1216
|
if (extraArgs && 'blockConfirmations' in extraArgs) {
|
|
1154
1217
|
blockConfirmations = extraArgs.blockConfirmations as number
|
|
1155
|
-
tokenArgs = hexlify(extraArgs.tokenArgs
|
|
1218
|
+
if (extraArgs.tokenArgs) tokenArgs = hexlify(extraArgs.tokenArgs)
|
|
1156
1219
|
}
|
|
1157
1220
|
|
|
1158
1221
|
// Skip pool-level fee lookup for pre-v2.0 lanes
|
|
@@ -1257,7 +1320,9 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1257
1320
|
}
|
|
1258
1321
|
|
|
1259
1322
|
const feeToken = message.feeToken ?? ZeroAddress
|
|
1260
|
-
const
|
|
1323
|
+
const receiverBytes = getAddressBytes(message.receiver)
|
|
1324
|
+
const receiver =
|
|
1325
|
+
receiverBytes.length <= 32 ? zeroPadValue(receiverBytes, 32) : hexlify(receiverBytes)
|
|
1261
1326
|
const data = hexlify(message.data ?? '0x')
|
|
1262
1327
|
const extraArgs = hexlify(
|
|
1263
1328
|
(this.constructor as typeof EVMChain).encodeExtraArgs(message.extraArgs),
|
|
@@ -1639,7 +1704,10 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1639
1704
|
* Fetches the token pool configuration for an EVM token pool contract.
|
|
1640
1705
|
*
|
|
1641
1706
|
* @param tokenPool - Token pool contract address.
|
|
1642
|
-
* @param feeOpts - Optional parameters to also fetch token transfer fee config
|
|
1707
|
+
* @param feeOpts - Optional parameters to also fetch token transfer fee config:
|
|
1708
|
+
* - `destChainSelector` — destination chain selector.
|
|
1709
|
+
* - `blockConfirmationsRequested` — number of block confirmations (0 = standard, positive = FTF).
|
|
1710
|
+
* - `tokenArgs` — hex-encoded bytes passed to the pool contract.
|
|
1643
1711
|
* @returns Token pool config containing token, router, typeAndVersion, and optionally
|
|
1644
1712
|
* minBlockConfirmations and tokenTransferFeeConfig.
|
|
1645
1713
|
*
|
|
@@ -1658,7 +1726,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1658
1726
|
minBlockConfirmations?: number
|
|
1659
1727
|
tokenTransferFeeConfig?: TokenTransferFeeConfig
|
|
1660
1728
|
}> {
|
|
1661
|
-
const [
|
|
1729
|
+
const [type, version, typeAndVersion] = await this.typeAndVersion(tokenPool)
|
|
1662
1730
|
|
|
1663
1731
|
let token, router, minBlockConfirmations, tokenTransferFeeConfig
|
|
1664
1732
|
if (version < CCIPVersion.V2_0) {
|
|
@@ -1670,6 +1738,14 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1670
1738
|
token = contract.getToken()
|
|
1671
1739
|
router = contract.getRouter()
|
|
1672
1740
|
} else {
|
|
1741
|
+
if (type === 'USDCTokenPoolProxy') {
|
|
1742
|
+
const proxy = new Contract(
|
|
1743
|
+
tokenPool,
|
|
1744
|
+
interfaces.USDCTokenPoolProxy_v2_0,
|
|
1745
|
+
this.provider,
|
|
1746
|
+
) as unknown as TypedContract<typeof USDCTokenPoolProxy_2_0_ABI>
|
|
1747
|
+
tokenPool = (await proxy.getPools())['cctpV2PoolWithCCV'] as string
|
|
1748
|
+
}
|
|
1673
1749
|
const contract = new Contract(
|
|
1674
1750
|
tokenPool,
|
|
1675
1751
|
interfaces.TokenPool_v2_0,
|
|
@@ -1678,6 +1754,11 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1678
1754
|
token = contract.getToken()
|
|
1679
1755
|
router = contract.getDynamicConfig().then(([router]) => router)
|
|
1680
1756
|
minBlockConfirmations = contract.getMinBlockConfirmations().catch((err) => {
|
|
1757
|
+
this.logger.debug(
|
|
1758
|
+
typeAndVersion,
|
|
1759
|
+
'threw when fetching minBlockConfirmations, defaulting to 0:',
|
|
1760
|
+
err,
|
|
1761
|
+
)
|
|
1681
1762
|
if (isError(err, 'CALL_EXCEPTION')) return 0
|
|
1682
1763
|
throw CCIPError.from(err)
|
|
1683
1764
|
})
|
|
@@ -1750,7 +1831,7 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1750
1831
|
tokenPool: string,
|
|
1751
1832
|
remoteChainSelector?: bigint,
|
|
1752
1833
|
): Promise<Record<string, TokenPoolRemote>> {
|
|
1753
|
-
const [
|
|
1834
|
+
const [type, version] = await this.typeAndVersion(tokenPool)
|
|
1754
1835
|
|
|
1755
1836
|
let supportedChains: Promise<NetworkInfo[]> | undefined
|
|
1756
1837
|
if (remoteChainSelector) supportedChains = Promise.resolve([networkInfo(remoteChainSelector)])
|
|
@@ -1812,6 +1893,14 @@ export class EVMChain extends Chain<typeof ChainFamily.EVM> {
|
|
|
1812
1893
|
),
|
|
1813
1894
|
)
|
|
1814
1895
|
} else {
|
|
1896
|
+
if (type === 'USDCTokenPoolProxy') {
|
|
1897
|
+
const proxy = new Contract(
|
|
1898
|
+
tokenPool,
|
|
1899
|
+
interfaces.USDCTokenPoolProxy_v2_0,
|
|
1900
|
+
this.provider,
|
|
1901
|
+
) as unknown as TypedContract<typeof USDCTokenPoolProxy_2_0_ABI>
|
|
1902
|
+
tokenPool = (await proxy.getPools())['cctpV2PoolWithCCV'] as string
|
|
1903
|
+
}
|
|
1815
1904
|
const contract = new Contract(
|
|
1816
1905
|
tokenPool,
|
|
1817
1906
|
interfaces.TokenPool_v2_0,
|
package/src/gas.ts
CHANGED
|
@@ -57,11 +57,12 @@ export type EstimateReceiveExecutionOpts = {
|
|
|
57
57
|
* Estimate CCIP gasLimit needed to execute a request on a contract receiver.
|
|
58
58
|
*
|
|
59
59
|
* @param opts - {@link EstimateReceiveExecutionOpts} for estimation
|
|
60
|
-
* @returns Estimated
|
|
60
|
+
* @returns Estimated execution gas (base transaction cost subtracted)
|
|
61
61
|
*
|
|
62
62
|
* @throws {@link CCIPMethodUnsupportedError} if dest chain doesn't support estimation
|
|
63
63
|
* @throws {@link CCIPContractTypeInvalidError} if routerOrRamp is not a valid contract type
|
|
64
64
|
* @throws {@link CCIPTokenDecimalsInsufficientError} if dest token has insufficient decimals
|
|
65
|
+
* @throws {@link CCIPOnRampRequiredError} if no OnRamp found for the given OffRamp and source chain
|
|
65
66
|
*
|
|
66
67
|
* @example
|
|
67
68
|
* ```typescript
|
package/src/index.ts
CHANGED
package/src/offchain.ts
CHANGED
|
@@ -86,6 +86,7 @@ export const CCTP_FINALITY_STANDARD = 2000
|
|
|
86
86
|
* @param destDomain - CCTP destination domain identifier
|
|
87
87
|
* @param networkType - network type (mainnet or testnet)
|
|
88
88
|
* @returns Array of fee tiers with finality thresholds and BPS fees
|
|
89
|
+
* @throws {@link CCIPUsdcBurnFeesError} if the HTTP request fails or the response is not a valid array of fee tiers
|
|
89
90
|
*/
|
|
90
91
|
export async function getUsdcBurnFees(
|
|
91
92
|
sourceDomain: number,
|
package/src/requests.ts
CHANGED
|
@@ -310,6 +310,7 @@ const BLOCK_LOG_WINDOW_SIZE = 5000
|
|
|
310
310
|
* @param range - Object containing minSeqNr and maxSeqNr for the batch range.
|
|
311
311
|
* @param opts - Optional log filtering parameters.
|
|
312
312
|
* @returns Array of messages in the batch.
|
|
313
|
+
* @throws {@link CCIPMessageBatchIncompleteError} if not all messages in the batch range could be found in source chain logs
|
|
313
314
|
* @see {@link getVerifications} - Get commit report to determine batch range
|
|
314
315
|
*/
|
|
315
316
|
export async function getMessagesInBatch<
|
|
@@ -409,12 +410,12 @@ export async function getMessagesInBatch<
|
|
|
409
410
|
* import { sourceToDestTokenAddresses, EVMChain } from '@chainlink/ccip-sdk'
|
|
410
411
|
*
|
|
411
412
|
* const source = await EVMChain.fromUrl('https://rpc.sepolia.org')
|
|
412
|
-
* const tokenAmount = await sourceToDestTokenAddresses(
|
|
413
|
+
* const tokenAmount = await sourceToDestTokenAddresses({
|
|
413
414
|
* source,
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
* { token: '0xLINK...', amount: 1000000000000000000n }
|
|
417
|
-
* )
|
|
415
|
+
* onRamp: '0xOnRamp...',
|
|
416
|
+
* destChainSelector: 14767482510784806043n,
|
|
417
|
+
* sourceTokenAmount: { token: '0xLINK...', amount: 1000000000000000000n },
|
|
418
|
+
* })
|
|
418
419
|
* console.log(`Pool: ${tokenAmount.sourcePoolAddress}`)
|
|
419
420
|
* console.log(`Dest token: ${tokenAmount.destTokenAddress}`)
|
|
420
421
|
* ```
|