@across-protocol/sdk 4.2.9-alpha.0 → 4.2.9-alpha.2

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 (120) hide show
  1. package/dist/cjs/arch/evm/SpokeUtils.d.ts +5 -2
  2. package/dist/cjs/arch/evm/SpokeUtils.js +1 -0
  3. package/dist/cjs/arch/evm/SpokeUtils.js.map +1 -1
  4. package/dist/cjs/arch/svm/SpokeUtils.d.ts +16 -1
  5. package/dist/cjs/arch/svm/SpokeUtils.js +128 -27
  6. package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
  7. package/dist/cjs/arch/svm/utils.d.ts +4 -0
  8. package/dist/cjs/arch/svm/utils.js +13 -1
  9. package/dist/cjs/arch/svm/utils.js.map +1 -1
  10. package/dist/cjs/clients/BundleDataClient/BundleDataClient.d.ts +2 -2
  11. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +3 -3
  12. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  13. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js +5 -5
  14. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
  15. package/dist/cjs/clients/BundleDataClient/utils/MerkleTreeUtils.js +5 -1
  16. package/dist/cjs/clients/BundleDataClient/utils/MerkleTreeUtils.js.map +1 -1
  17. package/dist/cjs/clients/HubPoolClient.d.ts +1 -1
  18. package/dist/cjs/clients/HubPoolClient.js +9 -6
  19. package/dist/cjs/clients/HubPoolClient.js.map +1 -1
  20. package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js +1 -1
  21. package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
  22. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js +28 -28
  23. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  24. package/dist/cjs/clients/mocks/MockSpokePoolClient.js +3 -1
  25. package/dist/cjs/clients/mocks/MockSpokePoolClient.js.map +1 -1
  26. package/dist/cjs/interfaces/HubPool.d.ts +1 -1
  27. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js +4 -4
  28. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
  29. package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.d.ts +7 -8
  30. package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.js +70 -62
  31. package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.js.map +1 -1
  32. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +1 -1
  33. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js +2 -2
  34. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
  35. package/dist/cjs/utils/AddressUtils.d.ts +3 -3
  36. package/dist/cjs/utils/AddressUtils.js +24 -9
  37. package/dist/cjs/utils/AddressUtils.js.map +1 -1
  38. package/dist/cjs/utils/TokenUtils.js +3 -3
  39. package/dist/cjs/utils/TokenUtils.js.map +1 -1
  40. package/dist/esm/arch/evm/SpokeUtils.d.ts +5 -2
  41. package/dist/esm/arch/evm/SpokeUtils.js +1 -0
  42. package/dist/esm/arch/evm/SpokeUtils.js.map +1 -1
  43. package/dist/esm/arch/svm/SpokeUtils.d.ts +46 -6
  44. package/dist/esm/arch/svm/SpokeUtils.js +157 -36
  45. package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
  46. package/dist/esm/arch/svm/utils.d.ts +10 -0
  47. package/dist/esm/arch/svm/utils.js +18 -1
  48. package/dist/esm/arch/svm/utils.js.map +1 -1
  49. package/dist/esm/clients/BundleDataClient/BundleDataClient.d.ts +2 -2
  50. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +3 -3
  51. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  52. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js +5 -5
  53. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
  54. package/dist/esm/clients/BundleDataClient/utils/MerkleTreeUtils.js +5 -1
  55. package/dist/esm/clients/BundleDataClient/utils/MerkleTreeUtils.js.map +1 -1
  56. package/dist/esm/clients/HubPoolClient.d.ts +1 -1
  57. package/dist/esm/clients/HubPoolClient.js +9 -6
  58. package/dist/esm/clients/HubPoolClient.js.map +1 -1
  59. package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js +1 -1
  60. package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
  61. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +28 -28
  62. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  63. package/dist/esm/clients/mocks/MockSpokePoolClient.js +3 -1
  64. package/dist/esm/clients/mocks/MockSpokePoolClient.js.map +1 -1
  65. package/dist/esm/interfaces/HubPool.d.ts +1 -1
  66. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js +4 -4
  67. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
  68. package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.d.ts +8 -9
  69. package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.js +74 -64
  70. package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.js.map +1 -1
  71. package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +1 -1
  72. package/dist/esm/relayFeeCalculator/relayFeeCalculator.js +3 -3
  73. package/dist/esm/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
  74. package/dist/esm/utils/AddressUtils.d.ts +4 -3
  75. package/dist/esm/utils/AddressUtils.js +30 -12
  76. package/dist/esm/utils/AddressUtils.js.map +1 -1
  77. package/dist/esm/utils/TokenUtils.d.ts +14 -0
  78. package/dist/esm/utils/TokenUtils.js +3 -3
  79. package/dist/esm/utils/TokenUtils.js.map +1 -1
  80. package/dist/types/arch/evm/SpokeUtils.d.ts +5 -2
  81. package/dist/types/arch/evm/SpokeUtils.d.ts.map +1 -1
  82. package/dist/types/arch/svm/SpokeUtils.d.ts +46 -6
  83. package/dist/types/arch/svm/SpokeUtils.d.ts.map +1 -1
  84. package/dist/types/arch/svm/utils.d.ts +10 -0
  85. package/dist/types/arch/svm/utils.d.ts.map +1 -1
  86. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts +2 -2
  87. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
  88. package/dist/types/clients/BundleDataClient/utils/MerkleTreeUtils.d.ts.map +1 -1
  89. package/dist/types/clients/HubPoolClient.d.ts +1 -1
  90. package/dist/types/clients/HubPoolClient.d.ts.map +1 -1
  91. package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts.map +1 -1
  92. package/dist/types/clients/mocks/MockSpokePoolClient.d.ts.map +1 -1
  93. package/dist/types/interfaces/HubPool.d.ts +1 -1
  94. package/dist/types/interfaces/HubPool.d.ts.map +1 -1
  95. package/dist/types/relayFeeCalculator/chain-queries/baseQuery.d.ts.map +1 -1
  96. package/dist/types/relayFeeCalculator/chain-queries/svmQuery.d.ts +8 -9
  97. package/dist/types/relayFeeCalculator/chain-queries/svmQuery.d.ts.map +1 -1
  98. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +1 -1
  99. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
  100. package/dist/types/utils/AddressUtils.d.ts +4 -3
  101. package/dist/types/utils/AddressUtils.d.ts.map +1 -1
  102. package/dist/types/utils/TokenUtils.d.ts +14 -0
  103. package/dist/types/utils/TokenUtils.d.ts.map +1 -1
  104. package/package.json +1 -1
  105. package/src/arch/evm/SpokeUtils.ts +9 -1
  106. package/src/arch/svm/SpokeUtils.ts +149 -42
  107. package/src/arch/svm/utils.ts +19 -0
  108. package/src/clients/BundleDataClient/BundleDataClient.ts +5 -5
  109. package/src/clients/BundleDataClient/utils/DataworkerUtils.ts +5 -5
  110. package/src/clients/BundleDataClient/utils/MerkleTreeUtils.ts +7 -1
  111. package/src/clients/HubPoolClient.ts +13 -7
  112. package/src/clients/SpokePoolClient/EVMSpokePoolClient.ts +5 -5
  113. package/src/clients/SpokePoolClient/SpokePoolClient.ts +32 -29
  114. package/src/clients/mocks/MockSpokePoolClient.ts +3 -1
  115. package/src/interfaces/HubPool.ts +1 -1
  116. package/src/relayFeeCalculator/chain-queries/baseQuery.ts +4 -4
  117. package/src/relayFeeCalculator/chain-queries/svmQuery.ts +85 -89
  118. package/src/relayFeeCalculator/relayFeeCalculator.ts +10 -4
  119. package/src/utils/AddressUtils.ts +31 -14
  120. package/src/utils/TokenUtils.ts +3 -3
@@ -1,38 +1,34 @@
1
- import { pipe } from "@solana/functional";
1
+ import { SvmSpokeClient } from "@across-protocol/contracts";
2
+ import { intToU8Array32 } from "@across-protocol/contracts/dist/src/svm/web3-v1/conversionUtils";
3
+ import { SYSTEM_PROGRAM_ADDRESS } from "@solana-program/system";
4
+ import { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, fetchMint } from "@solana-program/token";
5
+ import { getComputeUnitEstimateForTransactionMessageFactory } from "@solana/kit";
6
+ import {
7
+ SVMProvider,
8
+ SolanaVoidSigner,
9
+ createFillInstruction,
10
+ getAssociatedTokenAddress,
11
+ getEventAuthority,
12
+ getFillRelayDelegatePda,
13
+ getFillStatusPda,
14
+ getStatePda,
15
+ } from "../../arch/svm";
2
16
  import { Coingecko } from "../../coingecko";
3
- import { SymbolMappingType } from "./";
4
17
  import { CHAIN_IDs } from "../../constants";
18
+ import { SvmGasPriceEstimate, getGasPriceEstimate } from "../../gasPriceOracle";
5
19
  import { Deposit } from "../../interfaces";
6
- import { getGasPriceEstimate, SvmGasPriceEstimate } from "../../gasPriceOracle";
7
20
  import {
8
- BigNumberish,
9
- TransactionCostEstimate,
10
21
  BigNumber,
22
+ BigNumberish,
11
23
  SvmAddress,
12
- toBN,
13
- isDefined,
24
+ TransactionCostEstimate,
25
+ getRelayDataHash,
14
26
  toAddressType,
27
+ toBN,
28
+ Address,
15
29
  } from "../../utils";
16
- import { getDefaultSimulatedRelayerAddress, Logger, QueryInterface } from "../relayFeeCalculator";
17
- import {
18
- fillRelayInstruction,
19
- createApproveInstruction,
20
- createTokenAccountsInstruction,
21
- SVMProvider,
22
- SolanaVoidSigner,
23
- getAssociatedTokenAddress,
24
- } from "../../arch/svm";
25
- import {
26
- createTransactionMessage,
27
- setTransactionMessageFeePayer,
28
- setTransactionMessageLifetimeUsingBlockhash,
29
- appendTransactionMessageInstructions,
30
- getComputeUnitEstimateForTransactionMessageFactory,
31
- fetchEncodedAccount,
32
- IInstruction,
33
- } from "@solana/kit";
34
- import { TOKEN_PROGRAM_ADDRESS, getMintSize, getInitializeMintInstruction, fetchMint } from "@solana-program/token";
35
- import { getCreateAccountInstruction } from "@solana-program/system";
30
+ import { Logger, QueryInterface, getDefaultSimulatedRelayerAddress } from "../relayFeeCalculator";
31
+ import { SymbolMappingType } from "./";
36
32
 
37
33
  /**
38
34
  * A special QueryBase implementation for SVM used for querying gas costs, token prices, and decimals of various tokens
@@ -70,7 +66,7 @@ export class SvmQuery implements QueryInterface {
70
66
  /**
71
67
  * Retrieves the current gas costs of performing a fillRelay contract at the referenced SpokePool.
72
68
  * @param deposit V3 deposit instance.
73
- * @param relayerAddress Relayer address to simulate with.
69
+ * @param _relayer Relayer address to simulate with.
74
70
  * @param options
75
71
  * @param options.gasPrice Optional gas price to use for the simulation.
76
72
  * @param options.gasUnits Optional gas units to use for the simulation.
@@ -79,7 +75,7 @@ export class SvmQuery implements QueryInterface {
79
75
  */
80
76
  async getGasCosts(
81
77
  deposit: Omit<Deposit, "messageHash">,
82
- _relayer = toAddressType(getDefaultSimulatedRelayerAddress(deposit.destinationChainId)),
78
+ _relayer = toAddressType(getDefaultSimulatedRelayerAddress(deposit.destinationChainId), deposit.destinationChainId),
83
79
  options: Partial<{
84
80
  gasPrice: BigNumberish;
85
81
  gasUnits: BigNumberish;
@@ -88,7 +84,6 @@ export class SvmQuery implements QueryInterface {
88
84
  }> = {}
89
85
  ): Promise<TransactionCostEstimate> {
90
86
  const relayer = _relayer ? _relayer.forceSvmAddress() : this.simulatedRelayerAddress;
91
-
92
87
  const fillRelayTx = await this.getFillRelayTx(deposit, relayer);
93
88
 
94
89
  const [computeUnitsConsumed, _gasPriceEstimate] = await Promise.all([
@@ -122,11 +117,10 @@ export class SvmQuery implements QueryInterface {
122
117
  */
123
118
  async getNativeGasCost(
124
119
  deposit: Omit<Deposit, "messageHash">,
125
- _relayer = toAddressType(getDefaultSimulatedRelayerAddress(deposit.destinationChainId))
120
+ _relayer = toAddressType(getDefaultSimulatedRelayerAddress(deposit.destinationChainId), deposit.destinationChainId)
126
121
  ): Promise<BigNumber> {
127
122
  const fillRelayTx = await this.getFillRelayTx(deposit, _relayer);
128
- const computeUnitsConsumed = toBN(await this.computeUnitEstimator(fillRelayTx));
129
- return computeUnitsConsumed;
123
+ return toBN(await this.computeUnitEstimator(fillRelayTx));
130
124
  }
131
125
 
132
126
  /**
@@ -137,65 +131,67 @@ export class SvmQuery implements QueryInterface {
137
131
  */
138
132
  async getFillRelayTx(
139
133
  deposit: Omit<Deposit, "messageHash">,
140
- _relayer = toAddressType(getDefaultSimulatedRelayerAddress(deposit.destinationChainId))
134
+ relayer = toAddressType(getDefaultSimulatedRelayerAddress(deposit.destinationChainId), deposit.destinationChainId),
135
+ repaymentChainId = deposit.destinationChainId,
136
+ repaymentAddress = toAddressType(
137
+ getDefaultSimulatedRelayerAddress(deposit.destinationChainId),
138
+ deposit.destinationChainId
139
+ )
141
140
  ) {
142
- const relayer = isDefined(_relayer) ? _relayer : this.simulatedRelayerAddress;
143
- // If the user did not have a token account created on destination, then we need to include this as a gas cost.
144
- const mint = deposit.outputToken.forceSvmAddress();
145
- const owner = deposit.recipient.forceSvmAddress();
146
- const associatedToken = await getAssociatedTokenAddress(owner, mint);
147
- const simulatedSigner = SolanaVoidSigner(relayer.toBase58());
148
-
149
- // If the recipient has an associated token account on destination, then skip generating the instruction for creating a new token account.
150
- let recipientCreateTokenAccountInstructions: IInstruction[] | undefined = undefined;
151
- const [associatedTokenAccountExists, mintInfo] = await Promise.all([
152
- (await fetchEncodedAccount(this.provider, associatedToken)).exists,
153
- fetchMint(this.provider, mint.toV2Address()),
154
- ]);
155
- if (!associatedTokenAccountExists) {
156
- const space = BigInt(getMintSize());
157
- const rent = await this.provider.getMinimumBalanceForRentExemption(space).send();
158
- const createAccountIx = getCreateAccountInstruction({
159
- payer: simulatedSigner,
160
- newAccount: SolanaVoidSigner(mint.toBase58()),
161
- lamports: rent,
162
- space,
163
- programAddress: TOKEN_PROGRAM_ADDRESS,
164
- });
165
-
166
- const initializeMintIx = getInitializeMintInstruction({
167
- mint: mint.toV2Address(),
168
- decimals: mintInfo.data.decimals,
169
- mintAuthority: owner.toV2Address(),
170
- });
171
- recipientCreateTokenAccountInstructions = [createAccountIx, initializeMintIx];
172
- }
141
+ const toSvmAddress = (address: Address) => address.toV2Address();
142
+ const state = await getStatePda(this.spokePoolAddress.toV2Address());
143
+ const _relayDataHash = getRelayDataHash(deposit, deposit.destinationChainId);
144
+ const relayDataHash = new Uint8Array(Buffer.from(_relayDataHash.slice(2), "hex"));
145
+ const delegate = await getFillRelayDelegatePda(
146
+ relayDataHash,
147
+ BigInt(repaymentChainId),
148
+ repaymentAddress.toV2Address(),
149
+ this.spokePoolAddress.toV2Address()
150
+ );
151
+ const mint = deposit.outputToken;
152
+ const mintInfo = await fetchMint(this.provider, mint.toV2Address());
153
+ const recipientAta = await getAssociatedTokenAddress(deposit.recipient, mint, mintInfo.programAddress);
154
+ const relayerAta = await getAssociatedTokenAddress(relayer, mint, mintInfo.programAddress);
155
+ const fillStatus = await getFillStatusPda(this.spokePoolAddress.toV2Address(), deposit, deposit.destinationChainId);
156
+ const eventAuthority = await getEventAuthority(this.spokePoolAddress.toV2Address());
173
157
 
174
- const [createTokenAccountsIx, approveIx, fillIx] = await Promise.all([
175
- createTokenAccountsInstruction(mint, simulatedSigner),
176
- createApproveInstruction(
177
- mint.forceSvmAddress(),
178
- deposit.outputAmount,
179
- this.simulatedRelayerAddress,
180
- this.spokePoolAddress,
181
- mintInfo.data.decimals
182
- ),
183
- fillRelayInstruction(this.spokePoolAddress, deposit, simulatedSigner, associatedToken),
184
- ]);
158
+ const relayData: SvmSpokeClient.FillRelayInput["relayData"] = {
159
+ depositor: toSvmAddress(deposit.depositor),
160
+ recipient: toSvmAddress(deposit.recipient),
161
+ exclusiveRelayer: toSvmAddress(deposit.exclusiveRelayer),
162
+ inputToken: toSvmAddress(deposit.inputToken),
163
+ outputToken: mint.toV2Address(),
164
+ inputAmount: deposit.inputAmount.toBigInt(),
165
+ outputAmount: deposit.outputAmount.toBigInt(),
166
+ originChainId: deposit.originChainId,
167
+ depositId: new Uint8Array(intToU8Array32(deposit.depositId.toNumber())),
168
+ fillDeadline: deposit.fillDeadline,
169
+ exclusivityDeadline: deposit.exclusivityDeadline,
170
+ message: new Uint8Array(Buffer.from(deposit.message, "hex")),
171
+ };
185
172
 
186
- // Get the most recent confirmed blockhash.
187
- const recentBlockhash = await this.provider.getLatestBlockhash().send();
188
- const fillRelayTx = pipe(
189
- createTransactionMessage({ version: 0 }),
190
- (tx) => setTransactionMessageFeePayer(relayer.forceSvmAddress().toV2Address(), tx),
191
- (tx) => setTransactionMessageLifetimeUsingBlockhash(recentBlockhash.value, tx),
192
- (tx) =>
193
- isDefined(recipientCreateTokenAccountInstructions)
194
- ? appendTransactionMessageInstructions(recipientCreateTokenAccountInstructions, tx)
195
- : tx,
196
- (tx) => appendTransactionMessageInstructions([createTokenAccountsIx, approveIx, fillIx], tx)
197
- );
198
- return fillRelayTx;
173
+ const simulatedSigner = SolanaVoidSigner(relayer.toBase58());
174
+ const fillInput: SvmSpokeClient.FillRelayInput = {
175
+ signer: simulatedSigner,
176
+ state,
177
+ delegate,
178
+ mint: mint.toV2Address(),
179
+ relayerTokenAccount: relayerAta,
180
+ recipientTokenAccount: recipientAta,
181
+ fillStatus,
182
+ tokenProgram: mintInfo.programAddress,
183
+ associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
184
+ systemProgram: SYSTEM_PROGRAM_ADDRESS,
185
+ eventAuthority: eventAuthority,
186
+ program: this.spokePoolAddress.toV2Address(),
187
+ relayHash: relayDataHash,
188
+ relayData,
189
+ repaymentChainId: BigInt(repaymentChainId),
190
+ repaymentAddress: toSvmAddress(repaymentAddress),
191
+ };
192
+ // Pass createRecipientAtaIfNeeded =true to the createFillInstruction function to create the recipient token account
193
+ // if it doesn't exist.
194
+ return createFillInstruction(simulatedSigner, this.provider, fillInput, mintInfo.data.decimals, true);
199
195
  }
200
196
 
201
197
  /**
@@ -1,4 +1,5 @@
1
1
  import assert from "assert";
2
+ import { Transport } from "viem";
2
3
  import {
3
4
  DEFAULT_SIMULATED_RELAYER_ADDRESS,
4
5
  DEFAULT_SIMULATED_RELAYER_ADDRESS_SVM,
@@ -14,20 +15,19 @@ import {
14
15
  fixedPointAdjustment,
15
16
  getTokenInfo,
16
17
  isDefined,
18
+ isZeroAddress,
17
19
  max,
18
20
  min,
19
21
  nativeToToken,
20
22
  percent,
21
23
  toBN,
22
24
  toBNWei,
23
- isZeroAddress,
24
25
  compareAddressesSimple,
25
26
  ConvertDecimals,
26
27
  chainIsSvm,
27
28
  toAddressType,
28
29
  Address,
29
30
  } from "../utils";
30
- import { Transport } from "viem";
31
31
 
32
32
  // This needs to be implemented for every chain and passed into RelayFeeCalculator
33
33
  export interface QueryInterface {
@@ -256,7 +256,10 @@ export class RelayFeeCalculator {
256
256
  deposit: Deposit,
257
257
  outputAmount: BigNumberish,
258
258
  simulateZeroFill = false,
259
- relayerAddress = toAddressType(getDefaultSimulatedRelayerAddress(deposit.destinationChainId)),
259
+ relayerAddress = toAddressType(
260
+ getDefaultSimulatedRelayerAddress(deposit.destinationChainId),
261
+ deposit.destinationChainId
262
+ ),
260
263
  _tokenPrice?: number,
261
264
  tokenMapping = TOKEN_SYMBOLS_MAP,
262
265
  gasPrice?: BigNumberish,
@@ -495,7 +498,10 @@ export class RelayFeeCalculator {
495
498
  deposit: Deposit,
496
499
  outputAmount?: BigNumberish,
497
500
  simulateZeroFill = false,
498
- relayerAddress = toAddressType(getDefaultSimulatedRelayerAddress(deposit.destinationChainId)),
501
+ relayerAddress = toAddressType(
502
+ getDefaultSimulatedRelayerAddress(deposit.destinationChainId),
503
+ deposit.destinationChainId
504
+ ),
499
505
  _tokenPrice?: number,
500
506
  gasPrice?: BigNumberish,
501
507
  gasUnits?: BigNumberish,
@@ -2,7 +2,7 @@ import { providers, utils } from "ethers";
2
2
  import assert from "assert";
3
3
  import bs58 from "bs58";
4
4
  import { Address as V2Address } from "@solana/kit";
5
- import { BigNumber, chainIsEvm } from "./";
5
+ import { BigNumber, chainIsEvm, isDefined } from "./";
6
6
 
7
7
  /**
8
8
  * Checks if a contract is deployed at the given address
@@ -76,22 +76,39 @@ export function isValidEvmAddress(address: string): boolean {
76
76
  * Creates the proper address type given the input chain ID corresponding to the address's origin network.
77
77
  * @param address Stringified address type to convert. Can be either hex encoded or base58 encoded.
78
78
  * @param chainId Network ID corresponding to the input address, used to determine which address type to output.
79
+ * If no chain ID is specified, then fallback to inference via the structure of the address string.
79
80
  * @returns a child `Address` type most fitting for the chain ID.
80
81
  * @todo: Change this to `toAddress` once we remove the other `toAddress` function.
81
82
  */
82
- export function toAddressType(address: string): Address | EvmAddress | SvmAddress {
83
- try {
84
- if (utils.isHexString(address)) {
85
- return EvmAddress.from(address);
83
+ export function toAddressType(address: string, chainId?: number): Address | EvmAddress | SvmAddress {
84
+ const parseAddress = (address: string) => {
85
+ try {
86
+ if (utils.isHexString(address)) {
87
+ return EvmAddress.from(address);
88
+ }
89
+ return SvmAddress.from(address);
90
+ } catch (e) {
91
+ // If we hit this block, then the validation for one of the child address classes failed. We still may want to keep this address in our state, so
92
+ // return an unchecked address type.
93
+ assert(utils.isHexString(address));
94
+ assert(utils.hexDataLength(address) === 32);
95
+ return Address.__unsafeConstruct(utils.arrayify(address));
96
+ }
97
+ };
98
+ // If there is no network ID, then infer the address by the string format.
99
+ const addressType = parseAddress(address);
100
+ if (!isDefined(chainId)) {
101
+ return addressType;
102
+ }
103
+ // Wrap this in a try/catch in case we are trying to force an invalid EVM address to an EvmAddress type.
104
+ if (chainIsEvm(chainId)) {
105
+ try {
106
+ return addressType.forceEvmAddress();
107
+ } catch {
108
+ return addressType;
86
109
  }
87
- return SvmAddress.from(address);
88
- } catch (e) {
89
- // If we hit this block, then the validation for one of the child address classes failed. We still may want to keep this address in our state, so
90
- // return an unchecked address type.
91
- assert(utils.isHexString(address));
92
- assert(utils.hexDataLength(address) === 32);
93
- return Address.__unsafeConstruct(utils.arrayify(address));
94
110
  }
111
+ return addressType.forceSvmAddress();
95
112
  }
96
113
 
97
114
  // The Address class can contain any address type. It is up to the subclasses to determine how to format the address's internal representation,
@@ -253,7 +270,7 @@ export class Address {
253
270
  // Subclass of address which strictly deals with 20-byte addresses. These addresses are guaranteed to be valid EVM addresses, so `toAddress` will always succeed.
254
271
  export class EvmAddress extends Address {
255
272
  // On construction, validate that the address can indeed be coerced into an EVM address. Throw immediately if it cannot.
256
- private constructor(rawAddress: Uint8Array) {
273
+ constructor(rawAddress: Uint8Array) {
257
274
  super(rawAddress);
258
275
  const hexString = utils.hexlify(rawAddress);
259
276
  if (!this.isValidEvmAddress()) {
@@ -287,7 +304,7 @@ export class EvmAddress extends Address {
287
304
  // Subclass of address which strictly deals SVM addresses. These addresses are guaranteed to be valid SVM addresses, so `toBase58` will always produce a valid Solana address.
288
305
  export class SvmAddress extends Address {
289
306
  // On construction, validate that the address is a point on Curve25519. Throw immediately if it is not.
290
- private constructor(rawAddress: Uint8Array) {
307
+ constructor(rawAddress: Uint8Array) {
291
308
  super(rawAddress);
292
309
  }
293
310
 
@@ -14,7 +14,7 @@ type SignerOrProvider = providers.Provider | Signer;
14
14
  export async function fetchTokenInfo(address: string, signerOrProvider: SignerOrProvider): Promise<TokenInfo> {
15
15
  const token = new Contract(address, ERC20__factory.abi, signerOrProvider);
16
16
  const [symbol, decimals] = await Promise.all([token.symbol(), token.decimals()]);
17
- return { address: toAddressType(address), symbol, decimals };
17
+ return { address: toAddressType(address).forceEvmAddress(), symbol, decimals };
18
18
  }
19
19
 
20
20
  export const getL2TokenAddresses = (
@@ -44,7 +44,7 @@ export function resolveSymbolOnChain(chainId: number, symbol: string): TokenInfo
44
44
  const { decimals, addresses } = token;
45
45
  const address = addresses[chainId];
46
46
 
47
- return { symbol, decimals, address: toAddressType(address) };
47
+ return { symbol, decimals, address: toAddressType(address, chainId) };
48
48
  }
49
49
 
50
50
  /**
@@ -128,7 +128,7 @@ export function getTokenInfo(l2TokenAddress: string, chainId: number, tokenMappi
128
128
  tokenObject = tokenMapping[l1TokenSymbol as keyof typeof tokenMapping];
129
129
  }
130
130
  return {
131
- address: toAddressType(l2TokenAddress),
131
+ address: toAddressType(l2TokenAddress, chainId),
132
132
  symbol: tokenObject.symbol,
133
133
  decimals: tokenObject.decimals,
134
134
  };