@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.
Files changed (63) hide show
  1. package/dist/cjs/arch/svm/SpokeUtils.d.ts +11 -1
  2. package/dist/cjs/arch/svm/SpokeUtils.js +102 -27
  3. package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
  4. package/dist/cjs/constants.d.ts +1 -0
  5. package/dist/cjs/constants.js +1 -0
  6. package/dist/cjs/constants.js.map +1 -1
  7. package/dist/cjs/providers/alchemy.js +1 -0
  8. package/dist/cjs/providers/alchemy.js.map +1 -1
  9. package/dist/cjs/providers/quicknode.js +1 -0
  10. package/dist/cjs/providers/quicknode.js.map +1 -1
  11. package/dist/cjs/relayFeeCalculator/chain-queries/factory.d.ts +18 -0
  12. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +18 -0
  13. package/dist/cjs/utils/AddressUtils.d.ts +2 -1
  14. package/dist/cjs/utils/AddressUtils.js +18 -6
  15. package/dist/cjs/utils/AddressUtils.js.map +1 -1
  16. package/dist/cjs/utils/Multicall.js +1 -0
  17. package/dist/cjs/utils/Multicall.js.map +1 -1
  18. package/dist/cjs/utils/NetworkUtils.js +1 -1
  19. package/dist/cjs/utils/NetworkUtils.js.map +1 -1
  20. package/dist/cjs/utils/TokenUtils.d.ts +36 -0
  21. package/dist/esm/arch/svm/SpokeUtils.d.ts +18 -1
  22. package/dist/esm/arch/svm/SpokeUtils.js +108 -27
  23. package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
  24. package/dist/esm/constants.d.ts +1 -0
  25. package/dist/esm/constants.js +1 -0
  26. package/dist/esm/constants.js.map +1 -1
  27. package/dist/esm/providers/alchemy.js +1 -0
  28. package/dist/esm/providers/alchemy.js.map +1 -1
  29. package/dist/esm/providers/quicknode.js +1 -0
  30. package/dist/esm/providers/quicknode.js.map +1 -1
  31. package/dist/esm/relayFeeCalculator/chain-queries/factory.d.ts +18 -0
  32. package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +18 -0
  33. package/dist/esm/utils/AddressUtils.d.ts +8 -1
  34. package/dist/esm/utils/AddressUtils.js +25 -7
  35. package/dist/esm/utils/AddressUtils.js.map +1 -1
  36. package/dist/esm/utils/Multicall.js +1 -0
  37. package/dist/esm/utils/Multicall.js.map +1 -1
  38. package/dist/esm/utils/NetworkUtils.js +1 -1
  39. package/dist/esm/utils/NetworkUtils.js.map +1 -1
  40. package/dist/esm/utils/TokenUtils.d.ts +36 -0
  41. package/dist/types/arch/svm/SpokeUtils.d.ts +18 -1
  42. package/dist/types/arch/svm/SpokeUtils.d.ts.map +1 -1
  43. package/dist/types/constants.d.ts +1 -0
  44. package/dist/types/constants.d.ts.map +1 -1
  45. package/dist/types/providers/alchemy.d.ts.map +1 -1
  46. package/dist/types/providers/quicknode.d.ts.map +1 -1
  47. package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts +18 -0
  48. package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts.map +1 -1
  49. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +18 -0
  50. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
  51. package/dist/types/utils/AddressUtils.d.ts +8 -1
  52. package/dist/types/utils/AddressUtils.d.ts.map +1 -1
  53. package/dist/types/utils/Multicall.d.ts.map +1 -1
  54. package/dist/types/utils/TokenUtils.d.ts +36 -0
  55. package/dist/types/utils/TokenUtils.d.ts.map +1 -1
  56. package/package.json +3 -3
  57. package/src/arch/svm/SpokeUtils.ts +93 -2
  58. package/src/constants.ts +1 -0
  59. package/src/providers/alchemy.ts +1 -0
  60. package/src/providers/quicknode.ts +1 -0
  61. package/src/utils/AddressUtils.ts +31 -7
  62. package/src/utils/Multicall.ts +1 -0
  63. 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
- return simulateAndDecode(solanaClient, isNonceUsedIx, signer, parserFunction);
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
@@ -88,6 +88,7 @@ export const STABLE_COIN_SYMBOLS = [
88
88
 
89
89
  export const CUSTOM_GAS_TOKENS = {
90
90
  [CHAIN_IDs.BSC]: "BNB",
91
+ [CHAIN_IDs.HYPEREVM]: "HYPE",
91
92
  [CHAIN_IDs.POLYGON]: "MATIC",
92
93
  [CHAIN_IDs.POLYGON_AMOY]: "MATIC",
93
94
  [CHAIN_IDs.ALEPH_ZERO]: "AZERO",
@@ -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(address: string, provider: providers.Provider): Promise<boolean> {
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 || !utils.isAddress(address)) {
29
+ if (!address || !isAddress(address)) {
14
30
  return false;
15
31
  }
16
- // Retrieve the code at the address
32
+
17
33
  const code = await provider.getCode(address);
18
- // If the code is not empty, then there is a contract at this address
19
- return code !== "0x";
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 (utils.isAddress(address)) {
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 utils.isAddress(utils.getAddress(evmAddress));
92
+ return isAddress(utils.getAddress(evmAddress));
69
93
  } catch (_e) {
70
94
  return false;
71
95
  }
@@ -30,6 +30,7 @@ const DETERMINISTIC_MULTICALL_CHAINS = [
30
30
  CHAIN_IDs.ALEPH_ZERO,
31
31
  CHAIN_IDs.ARBITRUM,
32
32
  CHAIN_IDs.BSC,
33
+ CHAIN_IDs.HYPEREVM,
33
34
  CHAIN_IDs.LINEA,
34
35
  CHAIN_IDs.MAINNET,
35
36
  CHAIN_IDs.POLYGON,
@@ -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