@across-protocol/sdk 4.3.75-alpha.0 → 4.3.76

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 (51) hide show
  1. package/dist/cjs/relayFeeCalculator/chain-queries/factory.d.ts +18 -0
  2. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +18 -0
  3. package/dist/cjs/utils/CCTPUtils.d.ts +74 -0
  4. package/dist/cjs/utils/CCTPUtils.js +199 -0
  5. package/dist/cjs/utils/CCTPUtils.js.map +1 -0
  6. package/dist/cjs/utils/TokenUtils.d.ts +36 -0
  7. package/dist/cjs/utils/index.d.ts +1 -0
  8. package/dist/cjs/utils/index.js +1 -0
  9. package/dist/cjs/utils/index.js.map +1 -1
  10. package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +1 -1
  11. package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
  12. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +2 -2
  13. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  14. package/dist/esm/clients/SpokePoolClient/index.js +2 -2
  15. package/dist/esm/clients/SpokePoolClient/index.js.map +1 -1
  16. package/dist/esm/pool/uma/utils.js +1 -1
  17. package/dist/esm/pool/uma/utils.js.map +1 -1
  18. package/dist/esm/providers/types.js +1 -1
  19. package/dist/esm/providers/types.js.map +1 -1
  20. package/dist/esm/relayFeeCalculator/chain-queries/factory.d.ts +18 -0
  21. package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +18 -0
  22. package/dist/esm/utils/CCTPUtils.d.ts +169 -0
  23. package/dist/esm/utils/CCTPUtils.js +270 -0
  24. package/dist/esm/utils/CCTPUtils.js.map +1 -0
  25. package/dist/esm/utils/DepositUtils.js +1 -1
  26. package/dist/esm/utils/TokenUtils.d.ts +36 -0
  27. package/dist/esm/utils/index.d.ts +1 -0
  28. package/dist/esm/utils/index.js +1 -0
  29. package/dist/esm/utils/index.js.map +1 -1
  30. package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts +18 -0
  31. package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts.map +1 -1
  32. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +18 -0
  33. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
  34. package/dist/types/utils/CCTPUtils.d.ts +170 -0
  35. package/dist/types/utils/CCTPUtils.d.ts.map +1 -0
  36. package/dist/types/utils/TokenUtils.d.ts +36 -0
  37. package/dist/types/utils/TokenUtils.d.ts.map +1 -1
  38. package/dist/types/utils/index.d.ts +1 -0
  39. package/dist/types/utils/index.d.ts.map +1 -1
  40. package/package.json +4 -4
  41. package/src/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.ts +1 -1
  42. package/src/clients/BundleDataClient/BundleDataClient.ts +2 -2
  43. package/src/clients/HubPoolClient.ts +2 -2
  44. package/src/clients/SpokePoolClient/index.ts +2 -2
  45. package/src/pool/uma/clients/erc20/README.md +1 -1
  46. package/src/pool/uma/utils.ts +1 -1
  47. package/src/providers/cachedProvider.ts +1 -1
  48. package/src/providers/types.ts +1 -1
  49. package/src/utils/CCTPUtils.ts +329 -0
  50. package/src/utils/DepositUtils.ts +1 -1
  51. package/src/utils/index.ts +1 -0
@@ -186,6 +186,15 @@ export declare const resolveContractFromSymbol: (symbol: string, chainId: number
186
186
  };
187
187
  coingeckoId: string;
188
188
  };
189
+ POL: {
190
+ name: string;
191
+ symbol: string;
192
+ decimals: number;
193
+ addresses: {
194
+ [x: number]: string;
195
+ };
196
+ coingeckoId: string;
197
+ };
189
198
  POOL: {
190
199
  name: string;
191
200
  symbol: string;
@@ -434,6 +443,15 @@ export declare const resolveContractFromSymbol: (symbol: string, chainId: number
434
443
  };
435
444
  coingeckoId: string;
436
445
  };
446
+ WPOL: {
447
+ name: string;
448
+ symbol: string;
449
+ decimals: number;
450
+ addresses: {
451
+ [x: number]: string;
452
+ };
453
+ coingeckoId: string;
454
+ };
437
455
  WSOL: {
438
456
  name: string;
439
457
  symbol: string;
@@ -647,6 +665,15 @@ export declare function getTokenInfo(l2Token: Address, chainId: number, tokenMap
647
665
  };
648
666
  coingeckoId: string;
649
667
  };
668
+ POL: {
669
+ name: string;
670
+ symbol: string;
671
+ decimals: number;
672
+ addresses: {
673
+ [x: number]: string;
674
+ };
675
+ coingeckoId: string;
676
+ };
650
677
  POOL: {
651
678
  name: string;
652
679
  symbol: string;
@@ -895,6 +922,15 @@ export declare function getTokenInfo(l2Token: Address, chainId: number, tokenMap
895
922
  };
896
923
  coingeckoId: string;
897
924
  };
925
+ WPOL: {
926
+ name: string;
927
+ symbol: string;
928
+ decimals: number;
929
+ addresses: {
930
+ [x: number]: string;
931
+ };
932
+ coingeckoId: string;
933
+ };
898
934
  WSOL: {
899
935
  name: string;
900
936
  symbol: string;
@@ -1 +1 @@
1
- {"version":3,"file":"TokenUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/TokenUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TokenUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/TokenUtils.ts"],"names":[],"mappings":"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"}
@@ -27,4 +27,5 @@ export * from "./DepositUtils";
27
27
  export * from "./ValidatorUtils";
28
28
  export * from "./AddressUtils";
29
29
  export * from "./SpokeUtils";
30
+ export * from "./CCTPUtils";
30
31
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@across-protocol/sdk",
3
3
  "author": "UMA Team",
4
- "version": "4.3.75-alpha.0",
4
+ "version": "4.3.76",
5
5
  "license": "AGPL-3.0",
6
6
  "homepage": "https://docs.across.to/reference/sdk",
7
7
  "files": [
@@ -101,12 +101,12 @@
101
101
  "ts-node": "^10.9.1",
102
102
  "typechain": "^8.3.1",
103
103
  "typescript": "^5.9",
104
- "winston": "^3.17.0",
105
- "winston-transport": "^4.9.0"
104
+ "winston": "^3.10.0",
105
+ "winston-transport": "^4.5.0"
106
106
  },
107
107
  "dependencies": {
108
108
  "@across-protocol/across-token": "^1.0.0",
109
- "@across-protocol/constants": "^3.1.78",
109
+ "@across-protocol/constants": "^3.1.82",
110
110
  "@across-protocol/contracts": "^4.1.9",
111
111
  "@coral-xyz/anchor": "^0.30.1",
112
112
  "@eth-optimism/sdk": "^3.3.1",
@@ -498,7 +498,7 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
498
498
  }
499
499
  // Now check that we're only appending positive integers to the chainIndices array on each
500
500
  // update. If this isn't the case, skip the update & warn. If there is no previous update,
501
- // resolve an implcit chain ID list.
501
+ // resolve an implicit chain ID list.
502
502
  const previousUpdate = this.chainIdIndicesUpdates.at(-1)?.value ?? this.implicitChainIdIndices(chainId);
503
503
  // We should now check that previousUpdate is a subset of chainIndices.
504
504
  if (!previousUpdate.every((chainId, idx) => chainIndices[idx] === chainId)) {
@@ -1033,7 +1033,7 @@ export class BundleDataClient {
1033
1033
  fill?.relayExecutionInfo.fillType === FillType.ReplacedSlowFill,
1034
1034
  "Fill type should be ReplacedSlowFill."
1035
1035
  );
1036
- // Needed for TSC - are implicitely checking that deposit exists by making it to this point.
1036
+ // Needed for TSC - are implicitly checking that deposit exists by making it to this point.
1037
1037
  if (!deposits || deposits.length < 1) {
1038
1038
  throw new Error("Deposit should exist in relay hash dictionary.");
1039
1039
  }
@@ -1111,7 +1111,7 @@ export class BundleDataClient {
1111
1111
  // unexecutable. Mark this deposit as having created an unexecutable slow fill if there is no matching
1112
1112
  // slow fill request or the matching slow fill request took place in a previous bundle.
1113
1113
 
1114
- // If there is a slow fill request in this bundle, then the expired deposit refund will supercede
1114
+ // If there is a slow fill request in this bundle, then the expired deposit refund will supersede
1115
1115
  // the slow fill request. If there is no slow fill request seen or its older than this bundle, then we can
1116
1116
  // assume a slow fill leaf was created for it when the deposit was mined. Therefore, because the deposit
1117
1117
  // was in an older bundle, we can assume that a slow fill leaf was created at that time and therefore
@@ -359,7 +359,7 @@ export class HubPoolClient extends BaseAbstractClient {
359
359
  throw new Error("HubPoolClient has not set a currentTime");
360
360
  }
361
361
 
362
- // Map each HubPool token to an array of unqiue quoteTimestamps.
362
+ // Map each HubPool token to an array of unique quoteTimestamps.
363
363
  const utilizationTimestamps: { [hubPoolToken: string]: number[] } = {};
364
364
 
365
365
  // Map each HubPool token to utilization at a particular block number.
@@ -388,7 +388,7 @@ export class HubPoolClient extends BaseAbstractClient {
388
388
  .map((token) => token.toNative())
389
389
  ).map((token) => EvmAddress.from(token));
390
390
 
391
- // Helper to resolve the unqiue hubPoolToken & quoteTimestamp mappings.
391
+ // Helper to resolve the unique hubPoolToken & quoteTimestamp mappings.
392
392
  const resolveUniqueQuoteTimestamps = (deposit: LpFeeRequest): void => {
393
393
  const { quoteTimestamp } = deposit;
394
394
 
@@ -14,7 +14,7 @@ export { SpokePoolManager } from "./SpokePoolClientManager";
14
14
  * @returns True if the SpokePoolClient is an EVMSpokePoolClient, false otherwise.
15
15
  */
16
16
  export function isEVMSpokePoolClient(spokePoolClient: SpokePoolClient): spokePoolClient is EVMSpokePoolClient {
17
- // @TODO: Shoud we handle the case where spokePoolClient is undefined?
17
+ // @TODO: Should we handle the case where spokePoolClient is undefined?
18
18
  return spokePoolClient?.type === EVM_SPOKE_POOL_CLIENT_TYPE;
19
19
  }
20
20
 
@@ -24,6 +24,6 @@ export function isEVMSpokePoolClient(spokePoolClient: SpokePoolClient): spokePoo
24
24
  * @returns True if the SpokePoolClient is an SVMSpokePoolClient, false otherwise.
25
25
  */
26
26
  export function isSVMSpokePoolClient(spokePoolClient: SpokePoolClient): spokePoolClient is SVMSpokePoolClient {
27
- // @TODO: Shoud we handle the case where spokePoolClient is undefined?
27
+ // @TODO: Should we handle the case where spokePoolClient is undefined?
28
28
  return spokePoolClient?.type === SVM_SPOKE_POOL_CLIENT_TYPE;
29
29
  }
@@ -14,7 +14,7 @@ const provider = new ethers.providers.WebSocketProvider(env.CUSTOM_NODE_URL)
14
14
  const erc20Address:string = // assume you have an emp address you want to connect to
15
15
  const erc20Instance:uma.clients.erc20.Instance = uma.clients.erc20.connect(erc20Address,provider)
16
16
 
17
- // gets all emp events, see ethers queryFilter for details on contructing the query.
17
+ // gets all emp events, see ethers queryFilter for details on constructing the query.
18
18
  const events = await erc20Instance.queryFilter({})
19
19
 
20
20
  // returns EventState, defined in the emp client. This can contain user balances as well as approval limits.
@@ -42,7 +42,7 @@ export function Balances(balances: Balances = {}) {
42
42
  }
43
43
 
44
44
  // Loop forever but wait until execution is finished before starting next timer. Throw an error to break this
45
- // or add another utlity function if you need it to end on condition.
45
+ // or add another utility function if you need it to end on condition.
46
46
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
47
  export async function loop(fn: (...args: any[]) => any, delay: number, ...args: any[]) {
48
48
  do {
@@ -67,7 +67,7 @@ export class CacheProvider extends RateLimitedProvider {
67
67
  }
68
68
  }
69
69
 
70
- // Note: use swtich to ensure all enum cases are handled.
70
+ // Note: use switch to ensure all enum cases are handled.
71
71
  switch (cacheType) {
72
72
  case CacheType.WITH_TTL:
73
73
  {
@@ -4,7 +4,7 @@ export type RPCProvider = "ALCHEMY" | "DRPC" | "INFURA" | "INFURA_DIN" | "QUICKN
4
4
  export type RPCTransport = "https" | "wss";
5
5
 
6
6
  // JSON-RPC 2.0 Error object
7
- // See JSON-RPC 2.0 Specification section 5 Reponse object
7
+ // See JSON-RPC 2.0 Specification section 5 Response object
8
8
  // https://www.jsonrpc.org/specification
9
9
  export const JsonRpcError = type({
10
10
  jsonrpc: literal("2.0"),
@@ -0,0 +1,329 @@
1
+ import { PUBLIC_NETWORKS, CCTP_NO_DOMAIN, PRODUCTION_NETWORKS, TEST_NETWORKS } from "@across-protocol/constants";
2
+ import { BigNumber, ethers } from "ethers";
3
+
4
+ import { Log } from "@ethersproject/abstract-provider";
5
+ import { isDefined } from "./TypeGuards";
6
+ import axios from "axios";
7
+ import { chainIsProd } from "./NetworkUtils";
8
+ import assert from "assert";
9
+ import { bnZero } from "./BigNumberUtils";
10
+ /** ********************************************************************************************************************
11
+ *
12
+ * CONSTANTS
13
+ *
14
+ ******************************************************************************************************************* **/
15
+
16
+ export type CCTPMessageStatus = "finalized" | "ready" | "pending";
17
+ export const CCTPV2_FINALITY_THRESHOLD_STANDARD = 2000;
18
+ export const CCTPV2_FINALITY_THRESHOLD_FAST = 1000;
19
+ /** ********************************************************************************************************************
20
+ *
21
+ * CCTP SMART CONTRACT EVENT TYPES
22
+ *
23
+ ******************************************************************************************************************* **/
24
+
25
+ // Params shared by Message and DepositForBurn events.
26
+ type CommonMessageData = {
27
+ // `cctpVersion` is nuanced. cctpVersion returned from API are 1 or 2 (v1 and v2 accordingly). The bytes responsible for a version within the message itself though are 0 or 1 (v1 and v2 accordingly) :\
28
+ cctpVersion: number;
29
+ sourceDomain: number;
30
+ destinationDomain: number;
31
+ sender: string;
32
+ recipient: string;
33
+ messageHash: string;
34
+ messageBytes: string;
35
+ nonce: number; // This nonce makes sense only for v1 events, as it's emitted on src chain send
36
+ nonceHash: string;
37
+ };
38
+ type DepositForBurnMessageData = CommonMessageData & { amount: string; mintRecipient: string; burnToken: string };
39
+ type CommonMessageEvent = CommonMessageData & { log: Log };
40
+ type DepositForBurnMessageEvent = DepositForBurnMessageData & { log: Log };
41
+ type CCTPMessageEvent = CommonMessageEvent | DepositForBurnMessageEvent;
42
+
43
+ const CCTP_MESSAGE_SENT_TOPIC_HASH = ethers.utils.id("MessageSent(bytes)");
44
+ const CCTP_DEPOSIT_FOR_BURN_TOPIC_HASH_V1 = ethers.utils.id(
45
+ "DepositForBurn(uint64,address,uint256,address,bytes32,uint32,bytes32,bytes32)"
46
+ );
47
+ const CCTP_DEPOSIT_FOR_BURN_TOPIC_HASH_V2 = ethers.utils.id(
48
+ "DepositForBurn(address,uint256,address,bytes32,uint32,bytes32,bytes32,uint256,uint32,bytes)"
49
+ );
50
+
51
+ /** ********************************************************************************************************************
52
+ *
53
+ * CCTP API TYPES
54
+ *
55
+ ******************************************************************************************************************* **/
56
+
57
+ // CCTP V2 /burn/USDC/fees/{sourceDomainId}/{destDomainId} response
58
+ type CCTPV2APIGetFeesResponse = { finalityThreshold: number; minimumFee: number }[];
59
+
60
+ // CCTP V2 /fastBurn/USDC/allowance response
61
+ type CCTPV2APIGetFastBurnAllowanceResponse = { allowance: number };
62
+
63
+ // CCTP V2 /messages/{sourceDomainId} response
64
+ type CCTPV2APIAttestation = {
65
+ status: string;
66
+ attestation: string;
67
+ message: string;
68
+ eventNonce: string;
69
+ cctpVersion: number;
70
+ decodedMessage: {
71
+ recipient: string;
72
+ destinationDomain: number;
73
+ decodedMessageBody: {
74
+ amount: string;
75
+ mintRecipient: string;
76
+ messageSender: string;
77
+ };
78
+ };
79
+ };
80
+ type CCTPV2APIGetAttestationResponse = { messages: CCTPV2APIAttestation[] };
81
+
82
+ /** ********************************************************************************************************************
83
+ *
84
+ * Exported functions and constants:
85
+ *
86
+ ******************************************************************************************************************* **/
87
+
88
+ export type AttestedCCTPMessage = CCTPMessageEvent & { status: CCTPMessageStatus; attestation?: string };
89
+ export type AttestedCCTPDeposit = DepositForBurnMessageEvent & { status: CCTPMessageStatus; attestation?: string };
90
+
91
+ /**
92
+ * @notice Converts an ETH Address string to a 32-byte hex string.
93
+ * @param address The address to convert.
94
+ * @returns The 32-byte hex string representation of the address - required for CCTP messages.
95
+ */
96
+ export function cctpAddressToBytes32(address: string): string {
97
+ return ethers.utils.hexZeroPad(address, 32);
98
+ }
99
+
100
+ /**
101
+ * Converts a 32-byte hex string with padding to a standard ETH address.
102
+ * @param bytes32 The 32-byte hex string to convert.
103
+ * @returns The ETH address representation of the 32-byte hex string.
104
+ */
105
+ export function cctpBytes32ToAddress(bytes32: string): string {
106
+ // Grab the last 20 bytes of the 32-byte hex string
107
+ return ethers.utils.getAddress(ethers.utils.hexDataSlice(bytes32, 12));
108
+ }
109
+
110
+ /**
111
+ * @notice Returns the CCTP domain for a given chain ID. Throws if the chain ID is not a CCTP domain.
112
+ * @param chainId
113
+ * @returns CCTP Domain ID
114
+ */
115
+ export function getCctpDomainForChainId(chainId: number): number {
116
+ const cctpDomain = PUBLIC_NETWORKS[chainId]?.cctpDomain;
117
+ if (!isDefined(cctpDomain) || cctpDomain === CCTP_NO_DOMAIN) {
118
+ throw new Error(`No CCTP domain found for chainId: ${chainId}`);
119
+ }
120
+ return cctpDomain;
121
+ }
122
+
123
+ /**
124
+ * @notice Returns the chain ID for a given CCTP domain. Inverse functionof `getCctpDomainForChainId()`. However,
125
+ * since CCTP Domains are shared between production and test networks, we need to use the `productionNetworks` flag
126
+ * to determine whether to return the production or test network chain ID.
127
+ * @param domain CCTP domain ID.
128
+ * @param productionNetworks Whether to return the production or test network chain ID.
129
+ * @returns Chain ID.
130
+ */
131
+ export function getCctpDestinationChainFromDomain(domain: number, productionNetworks: boolean): number {
132
+ if (domain === CCTP_NO_DOMAIN) {
133
+ throw new Error("Cannot input CCTP_NO_DOMAIN to getCctpDestinationChainFromDomain");
134
+ }
135
+ // Test and Production networks use the same CCTP domain, so we need to use the flag passed in to
136
+ // determine whether to use the Test or Production networks.
137
+ const networks = productionNetworks ? PRODUCTION_NETWORKS : TEST_NETWORKS;
138
+ const otherNetworks = productionNetworks ? TEST_NETWORKS : PRODUCTION_NETWORKS;
139
+ const chainId = Object.keys(networks).find(
140
+ (key) => networks[Number(key)].cctpDomain.toString() === domain.toString()
141
+ );
142
+ if (!isDefined(chainId)) {
143
+ const chainId = Object.keys(otherNetworks).find(
144
+ (key) => otherNetworks[Number(key)].cctpDomain.toString() === domain.toString()
145
+ );
146
+ if (!isDefined(chainId)) {
147
+ throw new Error(`No chainId found for domain: ${domain}`);
148
+ }
149
+ return parseInt(chainId);
150
+ }
151
+ return parseInt(chainId);
152
+ }
153
+
154
+ /**
155
+ * @notice Typeguard. Returns whether the event is a CCTP deposit for burn event. Should work for V1 and V2
156
+ * @param event CCTP message event.
157
+ * @returns True if the event is a CCTP deposit for burn event.
158
+ */
159
+ export function isDepositForBurnEvent(event: CCTPMessageEvent): event is DepositForBurnMessageEvent {
160
+ return "amount" in event && "mintRecipient" in event && "burnToken" in event;
161
+ }
162
+
163
+ /**
164
+ * @notice Fetches CCTP V2 attestations for a given list of transaction hashes. If a transaction hash
165
+ * contains multiple CCTP messages, this will return an object where each key is a transaction hash and
166
+ * a value is an array of attestations.
167
+ * @param depositForBurnTxnHashes List of transaction hashes to fetch attestations for.
168
+ * @param sourceChainId Source chain ID of the transaction hashes.
169
+ * @returns Object with transaction hashes as keys and CCTP V2 attestations as values.
170
+ */
171
+ export async function fetchCctpV2Attestations(
172
+ depositForBurnTxnHashes: string[],
173
+ sourceChainId: number
174
+ ): Promise<{ [sourceTxnHash: string]: CCTPV2APIGetAttestationResponse }> {
175
+ // For v2, we fetch an API response for every txn hash we have. API returns an array of both v1 and v2 attestations
176
+ const sourceDomainId = getCctpDomainForChainId(sourceChainId);
177
+ const isMainnet = chainIsProd(sourceChainId);
178
+
179
+ // Circle rate limit is 35 requests / second. To avoid getting banned, batch calls into chunks with 1 second delay between chunks
180
+ // For v2, this is actually required because we don't know if message is finalized or not before hitting the API. Therefore as our
181
+ // CCTP v2 list of chains grows, we might require more than 35 calls here to fetch all attestations
182
+ const attestationResponses: { [sourceTxnHash: string]: CCTPV2APIGetAttestationResponse } = {};
183
+ const chunkSize = process.env.CCTP_API_REQUEST_CHUNK_SIZE ? parseInt(process.env.CCTP_API_REQUEST_CHUNK_SIZE) : 8;
184
+ for (let i = 0; i < depositForBurnTxnHashes.length; i += chunkSize) {
185
+ const chunk = depositForBurnTxnHashes.slice(i, i + chunkSize);
186
+
187
+ await Promise.all(
188
+ chunk.map(async (txHash) => {
189
+ const attestations = await fetchAttestationsForTxn(sourceDomainId, txHash, isMainnet);
190
+
191
+ // If multiple deposit for burn events, there will be multiple attestations.
192
+ attestationResponses[txHash] = attestations;
193
+ })
194
+ );
195
+
196
+ if (i + chunkSize < depositForBurnTxnHashes.length) {
197
+ await new Promise((resolve) => setTimeout(resolve, 1000));
198
+ }
199
+ }
200
+ return attestationResponses;
201
+ }
202
+
203
+ /**
204
+ * @notice Returns the status of a CCTP attestation.
205
+ * @param attestation Attestation to get the status of.
206
+ * @returns "finalized","pending" or "ready".
207
+ */
208
+ export function getPendingAttestationStatus(attestation: CCTPV2APIAttestation): CCTPMessageStatus {
209
+ if (!isDefined(attestation.attestation)) {
210
+ return "pending";
211
+ } else {
212
+ return attestation.status === "pending_confirmations" || attestation.attestation === "PENDING"
213
+ ? "pending"
214
+ : "ready";
215
+ }
216
+ }
217
+
218
+ /**
219
+ * @notice Checks if a CCTP message has been processed by a given contract.
220
+ * @param nonceHash Nonce hash to check.
221
+ * @param contract
222
+ * @returns True if the message has been processed, false otherwise.
223
+ */
224
+ export async function hasCCTPMessageBeenProcessedEvm(nonceHash: string, contract: ethers.Contract): Promise<boolean> {
225
+ const resultingCall: BigNumber = await contract.callStatic.usedNonces(nonceHash);
226
+ // If the resulting call is 1, the message has been processed. If it is 0, the message has not been processed.
227
+ return (resultingCall ?? bnZero).toNumber() === 1;
228
+ }
229
+
230
+ /**
231
+ * @notice The maximum amount of USDC that can be sent using a fast transfer.
232
+ * @param isMainnet Toggles whether to call CCTP API on mainnet or sandbox environment.
233
+ * @returns USDC amount in units of USDC.
234
+ * @link https://developers.circle.com/api-reference/cctp/all/get-fast-burn-usdc-allowance
235
+ */
236
+ export async function getV2FastBurnAllowance(isMainnet: boolean): Promise<string> {
237
+ const httpResponse = await axios.get<CCTPV2APIGetFastBurnAllowanceResponse>(
238
+ `https://iris-api${isMainnet ? "" : "-sandbox"}.circle.com/v2/fastBurn/USDC/allowance`
239
+ );
240
+ return httpResponse.data.allowance.toString();
241
+ }
242
+
243
+ /**
244
+ * Returns the minimum transfer fees required for a transfer to be relayed. When calling depositForBurn(), the maxFee
245
+ * parameter must be greater than or equal to the minimum fee.
246
+ * @param sourceChainId The source chain ID of the transfer.
247
+ * @param destinationChainId The destination chain ID of the transfer.
248
+ * @param isMainnet Toggles whether to call CCTP API on mainnet or sandbox environment.
249
+ * @returns The standard and fast transfer fees for the given source and destination chains.
250
+ * @link https://developers.circle.com/api-reference/cctp/all/get-burn-usdc-fees
251
+ */
252
+ export async function getV2MinTransferFees(
253
+ sourceChainId: number,
254
+ destinationChainId: number
255
+ ): Promise<{ standard: BigNumber; fast: BigNumber }> {
256
+ const isMainnet = chainIsProd(destinationChainId);
257
+ const sourceDomain = getCctpDomainForChainId(sourceChainId);
258
+ const destinationDomain = getCctpDomainForChainId(destinationChainId);
259
+ const endpoint = `https://iris-api${
260
+ isMainnet ? "" : "-sandbox"
261
+ }.circle.com/v2/burn/USDC/fees/${sourceDomain}/${destinationDomain}`;
262
+ const httpResponse = await axios.get<CCTPV2APIGetFeesResponse>(endpoint);
263
+ const standardFee = httpResponse.data.find((fee) => fee.finalityThreshold === CCTPV2_FINALITY_THRESHOLD_STANDARD);
264
+ assert(
265
+ isDefined(standardFee?.minimumFee),
266
+ `CCTPUtils#getTransferFees: Standard fee not found in API response: ${endpoint}`
267
+ );
268
+ const fastFee = httpResponse.data.find((fee) => fee.finalityThreshold === CCTPV2_FINALITY_THRESHOLD_FAST);
269
+ assert(isDefined(fastFee?.minimumFee), `CCTPUtils#getTransferFees: Fast fee not found in API response: ${endpoint}`);
270
+ return {
271
+ standard: BigNumber.from(standardFee.minimumFee),
272
+ fast: BigNumber.from(fastFee.minimumFee),
273
+ };
274
+ }
275
+
276
+ /**
277
+ * @notice Fetches attestations for a given transaction hash. If transaction hash contains multiple CCTP
278
+ * messages, this will return an array of attestations. Should work for both v1 and v2.
279
+ * @param sourceDomainId
280
+ * @param transactionHash
281
+ * @param isMainnet
282
+ * @returns Attestation response, list of messages with attestations.
283
+ */
284
+ export async function fetchAttestationsForTxn(
285
+ sourceDomainId: number,
286
+ transactionHash: string,
287
+ isMainnet: boolean
288
+ ): Promise<CCTPV2APIGetAttestationResponse> {
289
+ const httpResponse = await axios.get<CCTPV2APIGetAttestationResponse>(
290
+ `https://iris-api${
291
+ isMainnet ? "" : "-sandbox"
292
+ }.circle.com/v2/messages/${sourceDomainId}?transactionHash=${transactionHash}`
293
+ );
294
+
295
+ return httpResponse.data;
296
+ }
297
+
298
+ /**
299
+ * @notice Returns the CCTP version of the `MessageSent` event.
300
+ * @param log CCTP event log.
301
+ * @returns 0 for v1 `MessageSent` event, 1 for v2, -1 for other events
302
+ */
303
+ export function getMessageSentVersion(log: ethers.providers.Log): number {
304
+ if (log.topics[0] !== CCTP_MESSAGE_SENT_TOPIC_HASH) {
305
+ return -1;
306
+ }
307
+ // v1 and v2 have the same topic hash, so we have to do a bit of decoding here to understand the version
308
+ const messageBytes = ethers.utils.defaultAbiCoder.decode(["bytes"], log.data)[0];
309
+ // Source: https://developers.circle.com/stablecoins/message-format
310
+ const version = parseInt(messageBytes.slice(2, 10), 16); // read version: first 4 bytes (skipping '0x')
311
+ return version;
312
+ }
313
+
314
+ /**
315
+ * @notice Returns the CCTP version of the `DepositForBurn` event.
316
+ * @param log CCTP event log.
317
+ * @returns 0 for v1 `DepositForBurn` event, 1 for v2, -1 for other events
318
+ */
319
+ export function getDepositForBurnVersion(log: ethers.providers.Log): number {
320
+ const topic = log.topics[0];
321
+ switch (topic) {
322
+ case CCTP_DEPOSIT_FOR_BURN_TOPIC_HASH_V1:
323
+ return 0;
324
+ case CCTP_DEPOSIT_FOR_BURN_TOPIC_HASH_V2:
325
+ return 1;
326
+ default:
327
+ return -1;
328
+ }
329
+ }
@@ -192,7 +192,7 @@ export function validateFillForDeposit(
192
192
 
193
193
  // Note: this short circuits when a key is found where the comparison doesn't match.
194
194
  // TODO: if we turn on "strict" in the tsconfig, the elements of FILL_DEPOSIT_COMPARISON_KEYS will be automatically
195
- // validated against the fields in Fill and Deposit, generating an error if there is a discrepency.
195
+ // validated against the fields in Fill and Deposit, generating an error if there is a discrepancy.
196
196
  let invalidKey = RELAYDATA_KEYS.find((key) => relayData[key].toString() !== deposit[key].toString());
197
197
 
198
198
  // There should be no paths for `messageHash` to be unset, but mask it off anyway.
@@ -27,3 +27,4 @@ export * from "./DepositUtils";
27
27
  export * from "./ValidatorUtils";
28
28
  export * from "./AddressUtils";
29
29
  export * from "./SpokeUtils";
30
+ export * from "./CCTPUtils";