@across-protocol/sdk 4.3.59 → 4.3.61
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/cjs/arch/svm/SpokeUtils.d.ts +11 -1
- package/dist/cjs/arch/svm/SpokeUtils.js +102 -27
- package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/cjs/constants.d.ts +1 -0
- package/dist/cjs/constants.js +1 -0
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/providers/alchemy.js +1 -0
- package/dist/cjs/providers/alchemy.js.map +1 -1
- package/dist/cjs/providers/quicknode.js +1 -0
- package/dist/cjs/providers/quicknode.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/factory.d.ts +18 -0
- package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +18 -0
- package/dist/cjs/utils/AddressUtils.d.ts +2 -1
- package/dist/cjs/utils/AddressUtils.js +18 -6
- package/dist/cjs/utils/AddressUtils.js.map +1 -1
- package/dist/cjs/utils/Multicall.js +1 -0
- package/dist/cjs/utils/Multicall.js.map +1 -1
- package/dist/cjs/utils/NetworkUtils.js +1 -1
- package/dist/cjs/utils/NetworkUtils.js.map +1 -1
- package/dist/cjs/utils/TokenUtils.d.ts +36 -0
- package/dist/esm/arch/svm/SpokeUtils.d.ts +18 -1
- package/dist/esm/arch/svm/SpokeUtils.js +108 -27
- package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/esm/constants.d.ts +1 -0
- package/dist/esm/constants.js +1 -0
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/providers/alchemy.js +1 -0
- package/dist/esm/providers/alchemy.js.map +1 -1
- package/dist/esm/providers/quicknode.js +1 -0
- package/dist/esm/providers/quicknode.js.map +1 -1
- package/dist/esm/relayFeeCalculator/chain-queries/factory.d.ts +18 -0
- package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +18 -0
- package/dist/esm/utils/AddressUtils.d.ts +8 -1
- package/dist/esm/utils/AddressUtils.js +25 -7
- package/dist/esm/utils/AddressUtils.js.map +1 -1
- package/dist/esm/utils/Multicall.js +1 -0
- package/dist/esm/utils/Multicall.js.map +1 -1
- package/dist/esm/utils/NetworkUtils.js +1 -1
- package/dist/esm/utils/NetworkUtils.js.map +1 -1
- package/dist/esm/utils/TokenUtils.d.ts +36 -0
- package/dist/types/arch/svm/SpokeUtils.d.ts +18 -1
- package/dist/types/arch/svm/SpokeUtils.d.ts.map +1 -1
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/types/providers/alchemy.d.ts.map +1 -1
- package/dist/types/providers/quicknode.d.ts.map +1 -1
- package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts +18 -0
- package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts.map +1 -1
- package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +18 -0
- package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
- package/dist/types/utils/AddressUtils.d.ts +8 -1
- package/dist/types/utils/AddressUtils.d.ts.map +1 -1
- package/dist/types/utils/Multicall.d.ts.map +1 -1
- package/dist/types/utils/TokenUtils.d.ts +36 -0
- package/dist/types/utils/TokenUtils.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/arch/svm/SpokeUtils.ts +93 -2
- package/src/constants.ts +1 -0
- package/src/providers/alchemy.ts +1 -0
- package/src/providers/quicknode.ts +1 -0
- package/src/utils/AddressUtils.ts +31 -7
- package/src/utils/Multicall.ts +1 -0
- package/src/utils/NetworkUtils.ts +1 -1
|
@@ -106,6 +106,16 @@ type ProtoFill = Omit<RelayData, "recipient" | "outputToken"> & {
|
|
|
106
106
|
outputToken: SvmAddress;
|
|
107
107
|
};
|
|
108
108
|
|
|
109
|
+
type CCTPDepositAccounts = {
|
|
110
|
+
tokenMessenger: Address;
|
|
111
|
+
tokenMinter: Address;
|
|
112
|
+
localToken: Address;
|
|
113
|
+
cctpEventAuthority: Address;
|
|
114
|
+
remoteTokenMessenger: Address;
|
|
115
|
+
tokenMessengerMinterSenderAuthority: Address;
|
|
116
|
+
messageTransmitter: Address;
|
|
117
|
+
};
|
|
118
|
+
|
|
109
119
|
export function getSlot(provider: SVMProvider, commitment: Commitment, logger?: winston.Logger): Promise<bigint> {
|
|
110
120
|
return _callGetSlotWithRetry(provider, commitment, logger);
|
|
111
121
|
}
|
|
@@ -1265,7 +1275,9 @@ export const hasCCTPV1MessageBeenProcessed = async (
|
|
|
1265
1275
|
solanaClient: SVMProvider,
|
|
1266
1276
|
signer: KeyPairSigner,
|
|
1267
1277
|
nonce: number,
|
|
1268
|
-
sourceDomain: number
|
|
1278
|
+
sourceDomain: number,
|
|
1279
|
+
nRetries: number = 0,
|
|
1280
|
+
maxRetries: number = 2
|
|
1269
1281
|
): Promise<boolean> => {
|
|
1270
1282
|
let noncePda: Address;
|
|
1271
1283
|
try {
|
|
@@ -1283,7 +1295,19 @@ export const hasCCTPV1MessageBeenProcessed = async (
|
|
|
1283
1295
|
}
|
|
1284
1296
|
return Boolean(buf[0]);
|
|
1285
1297
|
};
|
|
1286
|
-
|
|
1298
|
+
// If the nonce PDA was found, we should be able to query the isNonceUsed parameter. If we can't then assume it is a transient RPC error
|
|
1299
|
+
// and retry, and throw if the error persists.
|
|
1300
|
+
try {
|
|
1301
|
+
return await simulateAndDecode(solanaClient, isNonceUsedIx, signer, parserFunction);
|
|
1302
|
+
} catch (e) {
|
|
1303
|
+
if (nRetries < maxRetries) {
|
|
1304
|
+
const delaySeconds = 2 ** nRetries + Math.random();
|
|
1305
|
+
await delay(delaySeconds);
|
|
1306
|
+
|
|
1307
|
+
return hasCCTPV1MessageBeenProcessed(solanaClient, signer, nonce, sourceDomain, ++nRetries);
|
|
1308
|
+
}
|
|
1309
|
+
throw e;
|
|
1310
|
+
}
|
|
1287
1311
|
};
|
|
1288
1312
|
|
|
1289
1313
|
/**
|
|
@@ -1347,6 +1371,73 @@ export async function getAccountMetasForTokenlessMessage(
|
|
|
1347
1371
|
];
|
|
1348
1372
|
}
|
|
1349
1373
|
|
|
1374
|
+
/**
|
|
1375
|
+
* Returns the required PDAs for a deposit message.
|
|
1376
|
+
* @param hubChainId The chain ID of the corresponding Across hub.
|
|
1377
|
+
* @param cctpSourceDomain The source chain (Solana) domain ID.
|
|
1378
|
+
* @param tokenMessengerMinter The token messenger minter address.
|
|
1379
|
+
* @param messageTransmitterAddress The message transmitter address.
|
|
1380
|
+
*/
|
|
1381
|
+
export async function getCCTPDepositAccounts(
|
|
1382
|
+
hubChainId: number,
|
|
1383
|
+
cctpSourceDomain: number,
|
|
1384
|
+
tokenMessengerMinterAddress: Address,
|
|
1385
|
+
messageTransmitterAddress: Address
|
|
1386
|
+
): Promise<CCTPDepositAccounts> {
|
|
1387
|
+
const l2Usdc = SvmAddress.from(
|
|
1388
|
+
TOKEN_SYMBOLS_MAP.USDC.addresses[chainIsProd(hubChainId) ? CHAIN_IDs.SOLANA : CHAIN_IDs.SOLANA_DEVNET]
|
|
1389
|
+
);
|
|
1390
|
+
|
|
1391
|
+
const [
|
|
1392
|
+
[tokenMessenger],
|
|
1393
|
+
[tokenMinter],
|
|
1394
|
+
[localToken],
|
|
1395
|
+
[cctpEventAuthority],
|
|
1396
|
+
[remoteTokenMessenger],
|
|
1397
|
+
[tokenMessengerMinterSenderAuthority],
|
|
1398
|
+
[messageTransmitter],
|
|
1399
|
+
] = await Promise.all([
|
|
1400
|
+
getProgramDerivedAddress({
|
|
1401
|
+
programAddress: tokenMessengerMinterAddress,
|
|
1402
|
+
seeds: ["token_messenger"],
|
|
1403
|
+
}),
|
|
1404
|
+
getProgramDerivedAddress({
|
|
1405
|
+
programAddress: tokenMessengerMinterAddress,
|
|
1406
|
+
seeds: ["token_minter"],
|
|
1407
|
+
}),
|
|
1408
|
+
getProgramDerivedAddress({
|
|
1409
|
+
programAddress: tokenMessengerMinterAddress,
|
|
1410
|
+
seeds: ["local_token", bs58.decode(l2Usdc.toBase58())],
|
|
1411
|
+
}),
|
|
1412
|
+
getProgramDerivedAddress({
|
|
1413
|
+
programAddress: tokenMessengerMinterAddress,
|
|
1414
|
+
seeds: ["__event_authority"],
|
|
1415
|
+
}),
|
|
1416
|
+
getProgramDerivedAddress({
|
|
1417
|
+
programAddress: tokenMessengerMinterAddress,
|
|
1418
|
+
seeds: ["remote_token_messenger", String(cctpSourceDomain)],
|
|
1419
|
+
}),
|
|
1420
|
+
getProgramDerivedAddress({
|
|
1421
|
+
programAddress: tokenMessengerMinterAddress,
|
|
1422
|
+
seeds: ["sender_authority"],
|
|
1423
|
+
}),
|
|
1424
|
+
getProgramDerivedAddress({
|
|
1425
|
+
programAddress: messageTransmitterAddress,
|
|
1426
|
+
seeds: ["message_transmitter"],
|
|
1427
|
+
}),
|
|
1428
|
+
]);
|
|
1429
|
+
|
|
1430
|
+
return {
|
|
1431
|
+
tokenMessenger,
|
|
1432
|
+
tokenMinter,
|
|
1433
|
+
localToken,
|
|
1434
|
+
cctpEventAuthority,
|
|
1435
|
+
remoteTokenMessenger,
|
|
1436
|
+
tokenMessengerMinterSenderAuthority,
|
|
1437
|
+
messageTransmitter,
|
|
1438
|
+
};
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1350
1441
|
/**
|
|
1351
1442
|
* Returns the account metas for a deposit message.
|
|
1352
1443
|
* @param message The CCTP message.
|
package/src/constants.ts
CHANGED
package/src/providers/alchemy.ts
CHANGED
|
@@ -13,6 +13,7 @@ const endpoints: { [chainId: number]: string } = {
|
|
|
13
13
|
[CHAIN_IDs.OPTIMISM_SEPOLIA]: "opt-sepolia",
|
|
14
14
|
[CHAIN_IDs.WORLD_CHAIN]: "worldchain",
|
|
15
15
|
[CHAIN_IDs.BSC]: "bnb",
|
|
16
|
+
[CHAIN_IDs.HYPEREVM]: "hyperliquid",
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
export function getURL(chainId: number, apiKey: string, transport: RPCTransport): string {
|
|
@@ -7,6 +7,7 @@ const SNOWFLAKES = {
|
|
|
7
7
|
[CHAIN_IDs.POLYGON]: "matic",
|
|
8
8
|
[CHAIN_IDs.OPTIMISM]: "optimism",
|
|
9
9
|
[CHAIN_IDs.WORLD_CHAIN]: "worldchain-mainnet",
|
|
10
|
+
[CHAIN_IDs.HYPEREVM]: "hype-mainnet",
|
|
10
11
|
};
|
|
11
12
|
const SNOWFLAKE_CHAIN_IDs = Object.keys(SNOWFLAKES).map(Number);
|
|
12
13
|
const MAINNET_CHAIN_IDs = Object.values(_MAINNET_CHAIN_IDs).map(Number);
|
|
@@ -1,22 +1,46 @@
|
|
|
1
|
+
import { isAddress } from "viem";
|
|
1
2
|
import { providers, utils } from "ethers";
|
|
2
3
|
import bs58 from "bs58";
|
|
3
4
|
import { BigNumber, chainIsEvm, chainIsSvm } from "./";
|
|
4
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Verify whether an address' bytecode resembles an EIP-7702 delegation.
|
|
8
|
+
* @param code Bytecode for a given address.
|
|
9
|
+
* @returns True if the bytecode resembles an EIP-7702 delegation, otherwise false.
|
|
10
|
+
*/
|
|
11
|
+
export function is7702Delegate(code: string): boolean {
|
|
12
|
+
// Sample 7702 delegation bytecode: 0xef010063c0c19a282a1b52b07dd5a65b58948a07dae32b
|
|
13
|
+
return code.length === 48 && code.startsWith("0xef0100") && isAddress(`0x${code.slice(8)}`);
|
|
14
|
+
}
|
|
15
|
+
|
|
5
16
|
/**
|
|
6
17
|
* Checks if a contract is deployed at the given address
|
|
7
18
|
* @param address The ETH address to check
|
|
8
19
|
* @param provider A valid Ethers.js provider
|
|
20
|
+
* @param ignore7702 A boolean to indicate whether EIP-7702 delegations should be considered as contract code.
|
|
9
21
|
* @returns A boolean indicating if a contract is deployed at the given address or not (true = contract, false = no contract)
|
|
10
22
|
*/
|
|
11
|
-
export async function isContractDeployedToAddress(
|
|
23
|
+
export async function isContractDeployedToAddress(
|
|
24
|
+
address: string,
|
|
25
|
+
provider: providers.Provider,
|
|
26
|
+
ignore7702 = false
|
|
27
|
+
): Promise<boolean> {
|
|
12
28
|
// A base case for if the address is null or malformed
|
|
13
|
-
if (!address || !
|
|
29
|
+
if (!address || !isAddress(address)) {
|
|
14
30
|
return false;
|
|
15
31
|
}
|
|
16
|
-
|
|
32
|
+
|
|
17
33
|
const code = await provider.getCode(address);
|
|
18
|
-
|
|
19
|
-
|
|
34
|
+
if (code === "0x") {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Ignore EIP-7702 delegations if ignore7702 was set.
|
|
39
|
+
if (ignore7702) {
|
|
40
|
+
return !is7702Delegate(code);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return true;
|
|
20
44
|
}
|
|
21
45
|
|
|
22
46
|
export function compareAddresses(addressA: string, addressB: string): 1 | -1 | 0 {
|
|
@@ -56,7 +80,7 @@ export function toEvmAddress(hexString: string): string {
|
|
|
56
80
|
}
|
|
57
81
|
|
|
58
82
|
export function isValidEvmAddress(address: string): boolean {
|
|
59
|
-
if (
|
|
83
|
+
if (isAddress(address)) {
|
|
60
84
|
return true;
|
|
61
85
|
}
|
|
62
86
|
// We may throw an error here if hexZeroPadFails. This will happen if the address to pad is greater than 20 bytes long, indicating
|
|
@@ -65,7 +89,7 @@ export function isValidEvmAddress(address: string): boolean {
|
|
|
65
89
|
// For both cases, this indicates that the address cannot be casted as a bytes20 EVM address, so we should return false.
|
|
66
90
|
try {
|
|
67
91
|
const evmAddress = utils.hexZeroPad(utils.hexStripZeros(address), 20);
|
|
68
|
-
return
|
|
92
|
+
return isAddress(utils.getAddress(evmAddress));
|
|
69
93
|
} catch (_e) {
|
|
70
94
|
return false;
|
|
71
95
|
}
|
package/src/utils/Multicall.ts
CHANGED
|
@@ -155,7 +155,7 @@ export function chainIsCCTPEnabled(chainId: number): boolean {
|
|
|
155
155
|
export function chainIsOFTEnabled(chainId: number): boolean {
|
|
156
156
|
// Add chainIds to oftEnabled as they are supported by the protocol.
|
|
157
157
|
// This is backwards vs. CCTP logic because Across support for OFTs is limited vs. OFT deployments.
|
|
158
|
-
const oftEnabled = [CHAIN_IDs.ARBITRUM];
|
|
158
|
+
const oftEnabled = [CHAIN_IDs.ARBITRUM, CHAIN_IDs.POLYGON];
|
|
159
159
|
return oftEnabled.includes(chainId) && PRODUCTION_NETWORKS[chainId]?.oftEid !== OFT_NO_EID;
|
|
160
160
|
}
|
|
161
161
|
|