@across-protocol/sdk 4.3.2 → 4.3.4

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 (112) hide show
  1. package/dist/cjs/arch/svm/SpokeUtils.d.ts +13 -5
  2. package/dist/cjs/arch/svm/SpokeUtils.js +74 -5
  3. package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
  4. package/dist/cjs/arch/svm/utils.d.ts +4 -1
  5. package/dist/cjs/arch/svm/utils.js +15 -1
  6. package/dist/cjs/arch/svm/utils.js.map +1 -1
  7. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +13 -6
  8. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  9. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js +8 -5
  10. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  11. package/dist/cjs/clients/HubPoolClient.d.ts +1 -1
  12. package/dist/cjs/clients/HubPoolClient.js +3 -3
  13. package/dist/cjs/clients/HubPoolClient.js.map +1 -1
  14. package/dist/cjs/clients/mocks/MockSvmCpiEventsClient.d.ts +1 -1
  15. package/dist/cjs/clients/mocks/MockSvmCpiEventsClient.js +4 -3
  16. package/dist/cjs/clients/mocks/MockSvmCpiEventsClient.js.map +1 -1
  17. package/dist/cjs/clients/mocks/MockSvmSpokePoolClient.d.ts +1 -1
  18. package/dist/cjs/interfaces/SpokePool.d.ts +18 -0
  19. package/dist/cjs/interfaces/SpokePool.js.map +1 -1
  20. package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.d.ts +2 -1
  21. package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.js +7 -68
  22. package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.js.map +1 -1
  23. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js +5 -5
  24. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
  25. package/dist/cjs/typeguards/error.d.ts +2 -0
  26. package/dist/cjs/typeguards/error.js +4 -1
  27. package/dist/cjs/typeguards/error.js.map +1 -1
  28. package/dist/cjs/utils/AddressUtils.d.ts +2 -0
  29. package/dist/cjs/utils/AddressUtils.js +4 -0
  30. package/dist/cjs/utils/AddressUtils.js.map +1 -1
  31. package/dist/cjs/utils/DepositUtils.d.ts +3 -1
  32. package/dist/cjs/utils/DepositUtils.js +9 -1
  33. package/dist/cjs/utils/DepositUtils.js.map +1 -1
  34. package/dist/cjs/utils/TokenUtils.d.ts +5 -4
  35. package/dist/cjs/utils/TokenUtils.js +15 -23
  36. package/dist/cjs/utils/TokenUtils.js.map +1 -1
  37. package/dist/esm/arch/svm/SpokeUtils.d.ts +23 -5
  38. package/dist/esm/arch/svm/SpokeUtils.js +86 -5
  39. package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
  40. package/dist/esm/arch/svm/utils.d.ts +7 -1
  41. package/dist/esm/arch/svm/utils.js +14 -0
  42. package/dist/esm/arch/svm/utils.js.map +1 -1
  43. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +14 -7
  44. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  45. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js +9 -6
  46. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  47. package/dist/esm/clients/HubPoolClient.d.ts +1 -1
  48. package/dist/esm/clients/HubPoolClient.js +3 -4
  49. package/dist/esm/clients/HubPoolClient.js.map +1 -1
  50. package/dist/esm/clients/mocks/MockSvmCpiEventsClient.d.ts +1 -1
  51. package/dist/esm/clients/mocks/MockSvmCpiEventsClient.js +5 -4
  52. package/dist/esm/clients/mocks/MockSvmCpiEventsClient.js.map +1 -1
  53. package/dist/esm/clients/mocks/MockSvmSpokePoolClient.d.ts +1 -1
  54. package/dist/esm/interfaces/SpokePool.d.ts +18 -0
  55. package/dist/esm/interfaces/SpokePool.js.map +1 -1
  56. package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.d.ts +2 -1
  57. package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.js +9 -73
  58. package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.js.map +1 -1
  59. package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +11 -10
  60. package/dist/esm/relayFeeCalculator/relayFeeCalculator.js +6 -6
  61. package/dist/esm/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
  62. package/dist/esm/typeguards/error.d.ts +2 -0
  63. package/dist/esm/typeguards/error.js +2 -0
  64. package/dist/esm/typeguards/error.js.map +1 -1
  65. package/dist/esm/utils/AddressUtils.d.ts +2 -0
  66. package/dist/esm/utils/AddressUtils.js +4 -0
  67. package/dist/esm/utils/AddressUtils.js.map +1 -1
  68. package/dist/esm/utils/DepositUtils.d.ts +15 -1
  69. package/dist/esm/utils/DepositUtils.js +19 -1
  70. package/dist/esm/utils/DepositUtils.js.map +1 -1
  71. package/dist/esm/utils/TokenUtils.d.ts +31 -10
  72. package/dist/esm/utils/TokenUtils.js +20 -28
  73. package/dist/esm/utils/TokenUtils.js.map +1 -1
  74. package/dist/types/arch/svm/SpokeUtils.d.ts +23 -5
  75. package/dist/types/arch/svm/SpokeUtils.d.ts.map +1 -1
  76. package/dist/types/arch/svm/utils.d.ts +7 -1
  77. package/dist/types/arch/svm/utils.d.ts.map +1 -1
  78. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
  79. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts.map +1 -1
  80. package/dist/types/clients/HubPoolClient.d.ts +1 -1
  81. package/dist/types/clients/HubPoolClient.d.ts.map +1 -1
  82. package/dist/types/clients/mocks/MockSvmCpiEventsClient.d.ts +1 -1
  83. package/dist/types/clients/mocks/MockSvmCpiEventsClient.d.ts.map +1 -1
  84. package/dist/types/clients/mocks/MockSvmSpokePoolClient.d.ts +1 -1
  85. package/dist/types/interfaces/SpokePool.d.ts +18 -0
  86. package/dist/types/interfaces/SpokePool.d.ts.map +1 -1
  87. package/dist/types/relayFeeCalculator/chain-queries/svmQuery.d.ts +2 -1
  88. package/dist/types/relayFeeCalculator/chain-queries/svmQuery.d.ts.map +1 -1
  89. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +11 -10
  90. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
  91. package/dist/types/typeguards/error.d.ts +2 -0
  92. package/dist/types/typeguards/error.d.ts.map +1 -1
  93. package/dist/types/utils/AddressUtils.d.ts +2 -0
  94. package/dist/types/utils/AddressUtils.d.ts.map +1 -1
  95. package/dist/types/utils/DepositUtils.d.ts +15 -1
  96. package/dist/types/utils/DepositUtils.d.ts.map +1 -1
  97. package/dist/types/utils/TokenUtils.d.ts +31 -10
  98. package/dist/types/utils/TokenUtils.d.ts.map +1 -1
  99. package/package.json +4 -3
  100. package/src/arch/svm/SpokeUtils.ts +97 -6
  101. package/src/arch/svm/utils.ts +16 -0
  102. package/src/clients/BundleDataClient/BundleDataClient.ts +15 -6
  103. package/src/clients/BundleDataClient/utils/SuperstructUtils.ts +10 -6
  104. package/src/clients/HubPoolClient.ts +3 -4
  105. package/src/clients/mocks/MockSvmCpiEventsClient.ts +5 -3
  106. package/src/interfaces/SpokePool.ts +23 -0
  107. package/src/relayFeeCalculator/chain-queries/svmQuery.ts +7 -93
  108. package/src/relayFeeCalculator/relayFeeCalculator.ts +6 -5
  109. package/src/typeguards/error.ts +3 -0
  110. package/src/utils/AddressUtils.ts +5 -0
  111. package/src/utils/DepositUtils.ts +49 -1
  112. package/src/utils/TokenUtils.ts +30 -34
@@ -1,33 +1,11 @@
1
1
  import assert from "assert";
2
- import { SvmSpokeClient } from "@across-protocol/contracts";
3
- import { intToU8Array32 } from "@across-protocol/contracts/dist/src/svm/web3-v1/conversionUtils";
4
- import { SYSTEM_PROGRAM_ADDRESS } from "@solana-program/system";
5
- import { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, fetchMint } from "@solana-program/token";
6
- import { getComputeUnitEstimateForTransactionMessageFactory } from "@solana/kit";
7
- import {
8
- SVMProvider,
9
- SolanaVoidSigner,
10
- createFillInstruction,
11
- getAssociatedTokenAddress,
12
- getEventAuthority,
13
- getFillRelayDelegatePda,
14
- getFillStatusPda,
15
- getStatePda,
16
- toAddress,
17
- } from "../../arch/svm";
2
+ import { getComputeUnitEstimateForTransactionMessageFactory, TransactionSigner } from "@solana/kit";
3
+ import { SVMProvider, SolanaVoidSigner, getFillRelayTx } from "../../arch/svm";
18
4
  import { Coingecko } from "../../coingecko";
19
5
  import { CHAIN_IDs } from "../../constants";
20
6
  import { getGasPriceEstimate } from "../../gasPriceOracle";
21
7
  import { RelayData } from "../../interfaces";
22
- import {
23
- Address,
24
- BigNumber,
25
- BigNumberish,
26
- SvmAddress,
27
- TransactionCostEstimate,
28
- getRelayDataHash,
29
- toBN,
30
- } from "../../utils";
8
+ import { Address, BigNumber, BigNumberish, SvmAddress, TransactionCostEstimate, toBN } from "../../utils";
31
9
  import { Logger, QueryInterface, getDefaultRelayer } from "../relayFeeCalculator";
32
10
  import { SymbolMappingType } from "./";
33
11
 
@@ -93,7 +71,7 @@ export class SvmQuery implements QueryInterface {
93
71
  const [repaymentChainId, repaymentAddress] = [destinationChainId, relayer]; // These are not important for gas cost simulation.
94
72
  const fillRelayTx = await this.getFillRelayTx(
95
73
  { ...relayData, recipient, outputToken, exclusiveRelayer },
96
- relayer,
74
+ SolanaVoidSigner(relayer.toBase58()),
97
75
  repaymentChainId,
98
76
  repaymentAddress
99
77
  );
@@ -139,7 +117,7 @@ export class SvmQuery implements QueryInterface {
139
117
  const [repaymentChainId, repaymentAddress] = [destinationChainId, relayer]; // These are not important for gas cost simulation.
140
118
  const fillRelayTx = await this.getFillRelayTx(
141
119
  { ...deposit, recipient, outputToken, exclusiveRelayer },
142
- relayer,
120
+ SolanaVoidSigner(relayer.toBase58()),
143
121
  repaymentChainId,
144
122
  repaymentAddress
145
123
  );
@@ -158,75 +136,11 @@ export class SvmQuery implements QueryInterface {
158
136
  recipient: SvmAddress;
159
137
  outputToken: SvmAddress;
160
138
  },
161
- relayer: SvmAddress,
139
+ signer: TransactionSigner,
162
140
  repaymentChainId: number,
163
141
  repaymentAddress: Address
164
142
  ) {
165
- const { depositor, recipient, inputToken, outputToken, exclusiveRelayer, destinationChainId } = relayData;
166
-
167
- // tsc appeasement...should be unnecessary, but isn't. @todo Identify why.
168
- assert(recipient.isSVM(), `getFillRelayTx: recipient not an SVM address (${recipient})`);
169
- assert(
170
- repaymentAddress.isValidOn(repaymentChainId),
171
- `getFillRelayTx: repayment address ${repaymentAddress} not valid on chain ${repaymentChainId})`
172
- );
173
-
174
- const program = toAddress(this.spokePool);
175
- const _relayDataHash = getRelayDataHash(relayData, destinationChainId);
176
- const relayDataHash = new Uint8Array(Buffer.from(_relayDataHash.slice(2), "hex"));
177
-
178
- const [state, delegate] = await Promise.all([
179
- getStatePda(program),
180
- getFillRelayDelegatePda(relayDataHash, BigInt(repaymentChainId), toAddress(repaymentAddress), program),
181
- ]);
182
-
183
- const mint = toAddress(outputToken);
184
- const mintInfo = await fetchMint(this.provider, mint);
185
-
186
- const [recipientAta, relayerAta, fillStatus, eventAuthority] = await Promise.all([
187
- getAssociatedTokenAddress(recipient, outputToken, mintInfo.programAddress),
188
- getAssociatedTokenAddress(SvmAddress.from(relayer.toBase58()), outputToken, mintInfo.programAddress),
189
- getFillStatusPda(program, relayData, destinationChainId),
190
- getEventAuthority(program),
191
- ]);
192
-
193
- const svmRelayData: SvmSpokeClient.FillRelayInput["relayData"] = {
194
- depositor: toAddress(depositor),
195
- recipient: toAddress(recipient),
196
- exclusiveRelayer: toAddress(exclusiveRelayer),
197
- inputToken: toAddress(inputToken),
198
- outputToken: mint,
199
- inputAmount: relayData.inputAmount.toBigInt(),
200
- outputAmount: relayData.outputAmount.toBigInt(),
201
- originChainId: relayData.originChainId,
202
- depositId: new Uint8Array(intToU8Array32(relayData.depositId.toNumber())),
203
- fillDeadline: relayData.fillDeadline,
204
- exclusivityDeadline: relayData.exclusivityDeadline,
205
- message: new Uint8Array(Buffer.from(relayData.message, "hex")),
206
- };
207
-
208
- const simulatedSigner = SolanaVoidSigner(relayer.toBase58());
209
- const fillInput: SvmSpokeClient.FillRelayInput = {
210
- signer: simulatedSigner,
211
- state,
212
- delegate,
213
- mint,
214
- relayerTokenAccount: relayerAta,
215
- recipientTokenAccount: recipientAta,
216
- fillStatus,
217
- tokenProgram: mintInfo.programAddress,
218
- associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
219
- systemProgram: SYSTEM_PROGRAM_ADDRESS,
220
- eventAuthority,
221
- program,
222
- relayHash: relayDataHash,
223
- relayData: svmRelayData,
224
- repaymentChainId: BigInt(repaymentChainId),
225
- repaymentAddress: toAddress(repaymentAddress),
226
- };
227
- // Pass createRecipientAtaIfNeeded =true to the createFillInstruction function to create the recipient token account
228
- // if it doesn't exist.
229
- return createFillInstruction(simulatedSigner, this.provider, fillInput, mintInfo.data.decimals, true);
143
+ return await getFillRelayTx(this.spokePool, this.provider, relayData, signer, repaymentChainId, repaymentAddress);
230
144
  }
231
145
 
232
146
  /**
@@ -27,6 +27,7 @@ import {
27
27
  Address,
28
28
  EvmAddress,
29
29
  SvmAddress,
30
+ toAddressType,
30
31
  } from "../utils";
31
32
 
32
33
  // This needs to be implemented for every chain and passed into RelayFeeCalculator
@@ -277,10 +278,10 @@ export class RelayFeeCalculator {
277
278
  isDefined(details.addresses[destinationChainId])
278
279
  );
279
280
  const outputToken = deposit.outputToken.isZeroAddress()
280
- ? destinationChainTokenDetails!.addresses[destinationChainId]
281
- : deposit.outputToken.toNative();
281
+ ? toAddressType(destinationChainTokenDetails!.addresses[destinationChainId], destinationChainId)
282
+ : deposit.outputToken;
282
283
  const outputTokenInfo = getTokenInfo(outputToken, destinationChainId, tokenMapping);
283
- const inputTokenInfo = getTokenInfo(inputToken.toNative(), originChainId, tokenMapping);
284
+ const inputTokenInfo = getTokenInfo(inputToken, originChainId, tokenMapping);
284
285
  if (!isDefined(outputTokenInfo) || !isDefined(inputTokenInfo)) {
285
286
  throw new Error(`Could not find token information for ${inputToken} or ${outputToken}`);
286
287
  }
@@ -507,8 +508,8 @@ export class RelayFeeCalculator {
507
508
  const { inputToken, originChainId, outputToken, destinationChainId } = deposit;
508
509
  // We can perform a simple lookup with `getTokenInfo` here without resolving the exact token to resolve since we only need to
509
510
  // resolve the L1 token symbol and not the L2 token decimals.
510
- const inputTokenInfo = getTokenInfo(inputToken.toNative(), originChainId);
511
- const outputTokenInfo = getTokenInfo(outputToken.toNative(), destinationChainId);
511
+ const inputTokenInfo = getTokenInfo(inputToken, originChainId);
512
+ const outputTokenInfo = getTokenInfo(outputToken, destinationChainId);
512
513
  if (!isDefined(inputTokenInfo) || !isDefined(outputTokenInfo)) {
513
514
  throw new Error(`Could not find token information for ${inputToken} or ${outputToken}`);
514
515
  }
@@ -1,7 +1,10 @@
1
1
  import { ethers } from "ethers";
2
2
  import { EthersError } from "../interfaces";
3
+ import { BaseError } from "viem";
3
4
 
4
5
  export const isError = (error: unknown): error is Error => error instanceof Error;
5
6
 
6
7
  export const isEthersError = (error?: unknown): error is EthersError =>
7
8
  (error as EthersError)?.code in ethers.utils.Logger.errors;
9
+
10
+ export const isViemError = (error?: unknown): error is BaseError => error instanceof BaseError;
@@ -90,6 +90,7 @@ export function toAddressType(address: string, chainId: number): Address {
90
90
  // The Address class can contain any address type. It is up to the subclasses to determine how to format the address's internal representation,
91
91
  // which for this class, is a bytes32 hex string.
92
92
  export abstract class Address {
93
+ readonly __address_type_brand = true;
93
94
  readonly rawAddress: Uint8Array;
94
95
 
95
96
  // Keep all address types in cache so that we may lazily evaluate them when necessary.
@@ -109,6 +110,10 @@ export abstract class Address {
109
110
  this.rawAddress = utils.zeroPad(_rawAddress, 32);
110
111
  }
111
112
 
113
+ static isAddress(obj: unknown): obj is Address {
114
+ return "__address_type_brand" in (obj as { __address_type_brand: boolean });
115
+ }
116
+
112
117
  // Converts the address into a bytes32 string. Note that the output bytes will be lowercase so that it matches ethers event data. This function will never
113
118
  // throw since address length validation was done at construction time.
114
119
  toBytes32(): string {
@@ -1,7 +1,16 @@
1
1
  import assert from "assert";
2
2
  import { SpokePoolClient } from "../clients";
3
3
  import { DEFAULT_CACHING_TTL, EMPTY_MESSAGE, UNDEFINED_MESSAGE_HASH, ZERO_BYTES } from "../constants";
4
- import { CachingMechanismInterface, Deposit, DepositWithBlock, Fill, RelayData, SlowFillRequest } from "../interfaces";
4
+ import {
5
+ CachingMechanismInterface,
6
+ Deposit,
7
+ DepositWithBlock,
8
+ Fill,
9
+ RelayData,
10
+ SlowFillRequest,
11
+ ConvertedRelayData,
12
+ ConvertedFill,
13
+ } from "../interfaces";
5
14
  import { getMessageHash, isUnsafeDepositId } from "./SpokeUtils";
6
15
  import { getNetworkName } from "./NetworkUtils";
7
16
  import { bnZero } from "./BigNumberUtils";
@@ -251,3 +260,42 @@ export function resolveDepositMessage(deposit: Deposit): string {
251
260
  assert(isDefined(message)); // Appease tsc about the updatedMessage being possibly undefined.
252
261
  return message;
253
262
  }
263
+
264
+ /**
265
+ * Converts a RelayData object with `Address` types as address fields to a `RelayData`-like object with
266
+ * strings as address fields.
267
+ * @param relayData RelayData type.
268
+ * @returns a RelayData-like type which has strings as fields.
269
+ */
270
+ export function convertRelayDataParamsToBytes32(relayData: RelayData): ConvertedRelayData {
271
+ return {
272
+ ...relayData,
273
+ depositor: relayData.depositor.toBytes32(),
274
+ recipient: relayData.recipient.toBytes32(),
275
+ inputToken: relayData.inputToken.toBytes32(),
276
+ outputToken: relayData.outputToken.toBytes32(),
277
+ exclusiveRelayer: relayData.exclusiveRelayer.toBytes32(),
278
+ };
279
+ }
280
+
281
+ /**
282
+ * Converts a Fill object with `Address` types as address fields to a `RelayData`-like object with
283
+ * strings as address fields.
284
+ * @param relayData RelayData type.
285
+ * @returns a RelayData-like type which has strings as fields.
286
+ */
287
+ export function convertFillParamsToBytes32(fill: Fill): ConvertedFill {
288
+ return {
289
+ ...fill,
290
+ depositor: fill.depositor.toBytes32(),
291
+ recipient: fill.recipient.toBytes32(),
292
+ inputToken: fill.inputToken.toBytes32(),
293
+ outputToken: fill.outputToken.toBytes32(),
294
+ exclusiveRelayer: fill.exclusiveRelayer.toBytes32(),
295
+ relayer: fill.relayer.toBytes32(),
296
+ relayExecutionInfo: {
297
+ ...fill.relayExecutionInfo,
298
+ updatedRecipient: fill.relayExecutionInfo.updatedRecipient.toBytes32(),
299
+ },
300
+ };
301
+ }
@@ -7,7 +7,7 @@ import { ERC20__factory } from "../typechain";
7
7
  import { BigNumber } from "./BigNumberUtils";
8
8
  import { getNetworkName, chainIsL1, chainIsProd } from "./NetworkUtils";
9
9
  import { isDefined } from "./TypeGuards";
10
- import { compareAddressesSimple, EvmAddress, toAddressType } from "./AddressUtils";
10
+ import { Address, EvmAddress, toAddressType } from "./AddressUtils";
11
11
  const { TOKEN_SYMBOLS_MAP, CHAIN_IDs, TOKEN_EQUIVALENCE_REMAPPING } = constants;
12
12
 
13
13
  type SignerOrProvider = providers.Provider | Signer;
@@ -66,11 +66,8 @@ export const resolveContractFromSymbol = (
66
66
  })?.addresses[Number(chainId)];
67
67
  };
68
68
 
69
- export function getCoingeckoTokenIdByAddress(contractAddress: string, chainId: number): string {
70
- const token = getTokenInfo(contractAddress, chainId);
71
- if (!token) {
72
- throw new Error(`Token with address ${contractAddress} not found in token mapping`);
73
- }
69
+ export function getCoingeckoTokenIdByAddress(address: string, chainId: number): string {
70
+ const token = getTokenInfo(toAddressType(address, chainId), chainId);
74
71
  return TOKEN_SYMBOLS_MAP[token.symbol as keyof typeof TOKEN_SYMBOLS_MAP].coingeckoId;
75
72
  }
76
73
 
@@ -108,31 +105,26 @@ export function isStablecoin(tokenSymbol: string): boolean {
108
105
  * @notice Returns the Token info for the token mapping in TOKEN_SYMBOLS_MAP matching the given l2TokenAddress
109
106
  * and chainId. If the chain is the hub chain, then will remap the L1 token to its equivalent L1 token symbol for example
110
107
  * it will always return a token info with symbol USDC and never USDC.e if chainId = mainnet.
111
- * @param l2TokenAddress
112
- * @param chainId
113
- * @param tokenMapping
114
- * @returns
108
+ * @param l2Token Address instance.
109
+ * @param chainId ChainId for l2Token address.
110
+ * @param tokenMapping Optional custom token mapping.
111
+ * @returns TokenInfo object.
115
112
  */
116
- export function getTokenInfo(l2TokenAddress: string, chainId: number, tokenMapping = TOKEN_SYMBOLS_MAP): TokenInfo {
117
- const parsedAddress = toAddressType(l2TokenAddress, chainId).toNative();
113
+ export function getTokenInfo(l2Token: Address, chainId: number, tokenMapping = TOKEN_SYMBOLS_MAP): TokenInfo {
114
+ const address = l2Token.toNative();
118
115
 
119
116
  // @dev This might give false positives if tokens on different networks have the same address. I'm not sure how
120
117
  // to get around this...
121
- let tokenObject = Object.values(tokenMapping).find(({ addresses }) => addresses[chainId] === parsedAddress);
118
+ let tokenObject = Object.values(tokenMapping).find(({ addresses }) => addresses[chainId] === address);
122
119
  if (!tokenObject) {
123
- throw new Error(
124
- `TokenUtils#getTokenInfo: Unable to resolve token in TOKEN_SYMBOLS_MAP for ${l2TokenAddress} on chain ${chainId}`
125
- );
120
+ throw new Error(`Unable to resolve token info for ${address} on chain ${chainId}`);
126
121
  }
127
122
  if (chainIsL1(chainId)) {
128
123
  const l1TokenSymbol = TOKEN_EQUIVALENCE_REMAPPING[tokenObject.symbol] ?? tokenObject.symbol;
129
124
  tokenObject = tokenMapping[l1TokenSymbol as keyof typeof tokenMapping];
130
125
  }
131
- return {
132
- address: toAddressType(l2TokenAddress, chainId),
133
- symbol: tokenObject.symbol,
134
- decimals: tokenObject.decimals,
135
- };
126
+
127
+ return { address: l2Token, symbol: tokenObject.symbol, decimals: tokenObject.decimals };
136
128
  }
137
129
 
138
130
  /**
@@ -141,26 +133,30 @@ export function getTokenInfo(l2TokenAddress: string, chainId: number, tokenMappi
141
133
  * @param chainId A chain Id to reference
142
134
  * @returns Either USDC (if native) or USDbC/USDC.e (if bridged) or undefined if the token address is not recognized.
143
135
  */
144
- export function getUsdcSymbol(l2Token: string, chainId: number): string | undefined {
145
- const compareToken = (token?: string) => isDefined(token) && compareAddressesSimple(l2Token, token);
146
- return ["USDC", "USDbC", "USDC.e"].find((token) =>
147
- compareToken(
148
- (TOKEN_SYMBOLS_MAP as Record<string, { addresses?: Record<number, string> }>)[token]?.addresses?.[chainId]
149
- )
136
+ export function getUsdcSymbol(l2Token: Address, chainId: number): string | undefined {
137
+ type TokenRecord = Record<string, { addresses?: Record<number, string> }>;
138
+ const IterableTokenSymbolsMap = TOKEN_SYMBOLS_MAP as TokenRecord;
139
+ return ["USDC", "USDbC", "USDC.e"].find(
140
+ (token) => IterableTokenSymbolsMap[token]?.addresses?.[chainId] === l2Token.toNative()
150
141
  );
151
142
  }
152
143
 
153
144
  /**
154
145
  * @notice Returns the l1 token address matching the given l2TokenAddress and chainId.
155
146
  */
156
- export function getL1TokenAddress(l2TokenAddress: string, chainId: number): string {
157
- if (chainIsL1(chainId)) return l2TokenAddress;
158
- const tokenObject = Object.values(TOKEN_SYMBOLS_MAP).find(({ addresses }) => addresses[chainId] === l2TokenAddress);
147
+ export function getL1TokenAddress(l2TokenAddress: Address, chainId: number): EvmAddress {
148
+ if (chainIsL1(chainId)) {
149
+ assert(l2TokenAddress.isEVM());
150
+ return l2TokenAddress;
151
+ }
152
+
153
+ const tokenObject = Object.values(TOKEN_SYMBOLS_MAP).find(
154
+ ({ addresses }) => l2TokenAddress.toNative() === addresses[chainId]
155
+ );
159
156
  const l1TokenAddress = tokenObject?.addresses[chainIsProd(chainId) ? CHAIN_IDs.MAINNET : CHAIN_IDs.SEPOLIA];
160
157
  if (!l1TokenAddress) {
161
- throw new Error(
162
- `TokenUtils#getL1TokenInfo: Unable to resolve l1 token address in TOKEN_SYMBOLS_MAP for L2 token ${l2TokenAddress} on chain ${chainId}`
163
- );
158
+ throw new Error(`getL1TokenAddress: Unable to resolve l1 token for L2 token ${l2TokenAddress} on chain ${chainId}`);
164
159
  }
165
- return l1TokenAddress;
160
+
161
+ return EvmAddress.from(l1TokenAddress);
166
162
  }