@across-protocol/sdk 4.3.58 → 4.3.59-alpha.1

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 (52) hide show
  1. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +39 -39
  2. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  3. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js +6 -4
  4. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
  5. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +5 -0
  6. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  7. package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts +1 -1
  8. package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js +4 -3
  9. package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
  10. package/dist/cjs/clients/HubPoolClient.d.ts +3 -9
  11. package/dist/cjs/clients/HubPoolClient.js +44 -68
  12. package/dist/cjs/clients/HubPoolClient.js.map +1 -1
  13. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js +4 -3
  14. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  15. package/dist/cjs/clients/mocks/MockHubPoolClient.d.ts +2 -2
  16. package/dist/cjs/clients/mocks/MockHubPoolClient.js +1 -1
  17. package/dist/cjs/clients/mocks/MockHubPoolClient.js.map +1 -1
  18. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +40 -40
  19. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  20. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js +6 -4
  21. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
  22. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +6 -1
  23. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  24. package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts +1 -1
  25. package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js +3 -2
  26. package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
  27. package/dist/esm/clients/HubPoolClient.d.ts +3 -9
  28. package/dist/esm/clients/HubPoolClient.js +48 -74
  29. package/dist/esm/clients/HubPoolClient.js.map +1 -1
  30. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +4 -3
  31. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  32. package/dist/esm/clients/mocks/MockHubPoolClient.d.ts +2 -2
  33. package/dist/esm/clients/mocks/MockHubPoolClient.js +1 -1
  34. package/dist/esm/clients/mocks/MockHubPoolClient.js.map +1 -1
  35. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
  36. package/dist/types/clients/BundleDataClient/utils/DataworkerUtils.d.ts.map +1 -1
  37. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
  38. package/dist/types/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts +1 -1
  39. package/dist/types/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts.map +1 -1
  40. package/dist/types/clients/HubPoolClient.d.ts +3 -9
  41. package/dist/types/clients/HubPoolClient.d.ts.map +1 -1
  42. package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts.map +1 -1
  43. package/dist/types/clients/mocks/MockHubPoolClient.d.ts +2 -2
  44. package/dist/types/clients/mocks/MockHubPoolClient.d.ts.map +1 -1
  45. package/package.json +2 -2
  46. package/src/clients/BundleDataClient/BundleDataClient.ts +12 -10
  47. package/src/clients/BundleDataClient/utils/DataworkerUtils.ts +13 -20
  48. package/src/clients/BundleDataClient/utils/FillUtils.ts +7 -1
  49. package/src/clients/BundleDataClient/utils/PoolRebalanceUtils.ts +8 -2
  50. package/src/clients/HubPoolClient.ts +49 -80
  51. package/src/clients/SpokePoolClient/SpokePoolClient.ts +15 -11
  52. package/src/clients/mocks/MockHubPoolClient.ts +3 -3
@@ -34,7 +34,6 @@ import {
34
34
  fetchTokenInfo,
35
35
  getCachedBlockForTimestamp,
36
36
  getCurrentTime,
37
- getNetworkName,
38
37
  isDefined,
39
38
  mapAsync,
40
39
  paginatedEventQuery,
@@ -75,17 +74,11 @@ type HubPoolEvent =
75
74
  | "RootBundleExecuted"
76
75
  | "CrossChainContractsSet";
77
76
 
78
- type L1TokensToDestinationTokens = {
79
- [l1Token: string]: { [destinationChainId: number]: Address };
80
- };
81
-
82
77
  export type LpFeeRequest = Pick<Deposit, "originChainId" | "inputToken" | "inputAmount" | "quoteTimestamp"> & {
83
78
  paymentChainId?: number;
84
79
  };
85
80
 
86
81
  export class HubPoolClient extends BaseAbstractClient {
87
- // L1Token -> destinationChainId -> destinationToken
88
- protected l1TokensToDestinationTokens: L1TokensToDestinationTokens = {};
89
82
  protected l1Tokens: L1TokenInfo[] = []; // L1Tokens and their associated info.
90
83
  // @dev `token` here is a 20-byte hex sting
91
84
  protected lpTokens: { [token: string]: LpToken } = {};
@@ -192,24 +185,16 @@ export class HubPoolClient extends BaseAbstractClient {
192
185
  l1Token: EvmAddress,
193
186
  destinationChainId: number,
194
187
  latestHubBlock = Number.MAX_SAFE_INTEGER
195
- ): Address {
188
+ ): Address | undefined {
196
189
  if (!this.l1TokensToDestinationTokensWithBlock?.[l1Token.toNative()]?.[destinationChainId]) {
197
- const chain = getNetworkName(destinationChainId);
198
- const { symbol } = this.l1Tokens.find(({ address }) => address.eq(l1Token)) ?? { symbol: l1Token.toString() };
199
- throw new Error(`Could not find SpokePool mapping for ${symbol} on ${chain} and L1 token ${l1Token}`);
190
+ return undefined;
200
191
  }
201
192
  // Find the last mapping published before the target block.
202
- const l2Token: DestinationTokenWithBlock | undefined = sortEventsDescending(
203
- this.l1TokensToDestinationTokensWithBlock[l1Token.toNative()][destinationChainId]
204
- ).find((mapping: DestinationTokenWithBlock) => mapping.blockNumber <= latestHubBlock);
205
- if (!l2Token) {
206
- const chain = getNetworkName(destinationChainId);
207
- const { symbol } = this.l1Tokens.find(({ address }) => address.eq(l1Token)) ?? { symbol: l1Token.toString() };
208
- throw new Error(
209
- `Could not find SpokePool mapping for ${symbol} on ${chain} at or before HubPool block ${latestHubBlock}!`
210
- );
211
- }
212
- return l2Token.l2Token;
193
+ const l2Token: DestinationTokenWithBlock | undefined = this.l1TokensToDestinationTokensWithBlock[
194
+ l1Token.toNative()
195
+ ][destinationChainId].find((mapping: DestinationTokenWithBlock) => mapping.blockNumber <= latestHubBlock);
196
+
197
+ return !isDefined(l2Token) || l2Token.l2Token.isZeroAddress() ? undefined : l2Token.l2Token;
213
198
  }
214
199
 
215
200
  // Returns the latest L1 token to use for an L2 token as of the input hub block.
@@ -217,32 +202,27 @@ export class HubPoolClient extends BaseAbstractClient {
217
202
  l2Token: Address,
218
203
  destinationChainId: number,
219
204
  latestHubBlock = Number.MAX_SAFE_INTEGER
220
- ): EvmAddress {
221
- const l2Tokens = Object.keys(this.l1TokensToDestinationTokensWithBlock)
222
- .filter((l1Token) => this.l2TokenEnabledForL1Token(EvmAddress.from(l1Token), destinationChainId))
223
- .map((l1Token) => {
224
- // Return all matching L2 token mappings that are equal to or earlier than the target block.
225
- // @dev Since tokens on L2s (like Solana) can have 32 byte addresses, filter on the lower 20 bytes of the token only.
226
- return this.l1TokensToDestinationTokensWithBlock[l1Token][destinationChainId].filter(
227
- (dstTokenWithBlock) =>
228
- dstTokenWithBlock.l2Token.truncateToBytes20() === l2Token.truncateToBytes20() &&
229
- dstTokenWithBlock.blockNumber <= latestHubBlock
230
- );
231
- })
232
- .flat();
233
- if (l2Tokens.length === 0) {
234
- const chain = getNetworkName(destinationChainId);
235
- throw new Error(
236
- `Could not find HubPool mapping for ${l2Token} on ${chain} at or before HubPool block ${latestHubBlock}!`
205
+ ): EvmAddress | undefined {
206
+ const l2Tokens = Object.keys(this.l1TokensToDestinationTokensWithBlock).flatMap((l1Token) => {
207
+ // Get the latest L2 token mapping for the given L1 token.
208
+ // @dev Since tokens on L2s (like Solana) can have 32 byte addresses, filter on the lower 20 bytes of the token only.
209
+ const sortedL2Tokens = sortEventsDescending(
210
+ (this.l1TokensToDestinationTokensWithBlock[l1Token][destinationChainId] ?? []).filter(
211
+ (dstTokenWithBlock) => dstTokenWithBlock.blockNumber <= latestHubBlock
212
+ )
237
213
  );
238
- }
239
- // Find the last mapping published before the target block.
240
- return sortEventsDescending(l2Tokens)[0].l1Token;
214
+ // If the latest L2 token mapping is equal to the target L2 token, return it.
215
+ return sortedL2Tokens.length > 0 && sortedL2Tokens[0].l2Token.truncateToBytes20() === l2Token.truncateToBytes20()
216
+ ? sortedL2Tokens[0]
217
+ : [];
218
+ });
219
+
220
+ return l2Tokens.length === 0 ? undefined : sortEventsDescending(l2Tokens)[0].l1Token;
241
221
  }
242
222
 
243
223
  protected getL1TokenForDeposit(
244
224
  deposit: Pick<DepositWithBlock, "originChainId" | "inputToken" | "quoteBlockNumber">
245
- ): EvmAddress {
225
+ ): EvmAddress | undefined {
246
226
  // L1-->L2 token mappings are set via PoolRebalanceRoutes which occur on mainnet,
247
227
  // so we use the latest token mapping. This way if a very old deposit is filled, the relayer can use the
248
228
  // latest L2 token mapping to find the L1 token counterpart.
@@ -250,7 +230,7 @@ export class HubPoolClient extends BaseAbstractClient {
250
230
  }
251
231
 
252
232
  l2TokenEnabledForL1Token(l1Token: EvmAddress, destinationChainId: number): boolean {
253
- return this.l1TokensToDestinationTokens?.[l1Token.toNative()]?.[destinationChainId] != undefined;
233
+ return this.l2TokenEnabledForL1TokenAtBlock(l1Token, destinationChainId, Number.MAX_SAFE_INTEGER);
254
234
  }
255
235
 
256
236
  l2TokenEnabledForL1TokenAtBlock(l1Token: EvmAddress, destinationChainId: number, hubBlockNumber: number): boolean {
@@ -258,21 +238,12 @@ export class HubPoolClient extends BaseAbstractClient {
258
238
  const l2Token: DestinationTokenWithBlock | undefined = sortEventsDescending(
259
239
  this.l1TokensToDestinationTokensWithBlock?.[l1Token.toNative()]?.[destinationChainId] ?? []
260
240
  ).find((mapping: DestinationTokenWithBlock) => mapping.blockNumber <= hubBlockNumber);
261
- return l2Token !== undefined;
241
+ return isDefined(l2Token) && !l2Token.l2Token.isZeroAddress();
262
242
  }
263
243
 
264
244
  l2TokenHasPoolRebalanceRoute(l2Token: Address, l2ChainId: number, hubPoolBlock = this.latestHeightSearched): boolean {
265
- return Object.values(this.l1TokensToDestinationTokensWithBlock).some((destinationTokenMapping) => {
266
- return Object.entries(destinationTokenMapping).some(([_l2ChainId, setPoolRebalanceRouteEvents]) => {
267
- return setPoolRebalanceRouteEvents.some((e) => {
268
- return (
269
- e.blockNumber <= hubPoolBlock &&
270
- e.l2Token.truncateToBytes20() === l2Token.truncateToBytes20() &&
271
- Number(_l2ChainId) === l2ChainId
272
- );
273
- });
274
- });
275
- });
245
+ const l1Token = this.getL1TokenForL2TokenAtBlock(l2Token, l2ChainId, hubPoolBlock);
246
+ return isDefined(l1Token);
276
247
  }
277
248
 
278
249
  /**
@@ -401,11 +372,11 @@ export class HubPoolClient extends BaseAbstractClient {
401
372
  const hubPoolTokens: { [k: string]: EvmAddress } = {};
402
373
  const getHubPoolToken = (deposit: LpFeeRequest, quoteBlockNumber: number): EvmAddress | undefined => {
403
374
  const tokenKey = `${deposit.originChainId}-${deposit.inputToken}`;
404
- if (this.l2TokenHasPoolRebalanceRoute(deposit.inputToken, deposit.originChainId, quoteBlockNumber)) {
405
- return (hubPoolTokens[tokenKey] ??= this.getL1TokenForDeposit({ ...deposit, quoteBlockNumber }));
375
+ const l1Token = this.getL1TokenForDeposit({ ...deposit, quoteBlockNumber });
376
+ if (!isDefined(l1Token)) {
377
+ return undefined;
406
378
  }
407
-
408
- return undefined;
379
+ return (hubPoolTokens[tokenKey] ??= l1Token);
409
380
  };
410
381
 
411
382
  // Filter hubPoolTokens for duplicates by reverting to their native string
@@ -553,14 +524,14 @@ export class HubPoolClient extends BaseAbstractClient {
553
524
  // Resolve both SpokePool tokens back to their respective HubPool tokens and verify that they match.
554
525
  const l1TokenA = this.getL1TokenForL2TokenAtBlock(tokenA, chainIdA, hubPoolBlock);
555
526
  const l1TokenB = this.getL1TokenForL2TokenAtBlock(tokenB, chainIdB, hubPoolBlock);
556
- if (!l1TokenA.eq(l1TokenB)) {
527
+ if (!isDefined(l1TokenA) || !isDefined(l1TokenB) || !l1TokenA.eq(l1TokenB)) {
557
528
  return false;
558
529
  }
559
530
 
560
531
  // Resolve both HubPool tokens back to a current SpokePool token and verify that they match.
561
532
  const _tokenA = this.getL2TokenForL1TokenAtBlock(l1TokenA, chainIdA, hubPoolBlock);
562
533
  const _tokenB = this.getL2TokenForL1TokenAtBlock(l1TokenB, chainIdB, hubPoolBlock);
563
- return tokenA.eq(_tokenA) && tokenB.eq(_tokenB);
534
+ return isDefined(_tokenA) && isDefined(_tokenB) && tokenA.eq(_tokenA) && tokenB.eq(_tokenB);
564
535
  }
565
536
 
566
537
  getSpokeActivationBlockForChain(chainId: number): number {
@@ -1001,24 +972,22 @@ export class HubPoolClient extends BaseAbstractClient {
1001
972
  destinationToken = svmUsdc;
1002
973
  }
1003
974
 
1004
- // If the destination token is set to the zero address in an event, then this means Across should no longer
1005
- // rebalance to this chain.
1006
- if (!destinationToken.isZeroAddress()) {
1007
- assign(this.l1TokensToDestinationTokens, [args.l1Token, args.destinationChainId], destinationToken);
1008
- assign(
1009
- this.l1TokensToDestinationTokensWithBlock,
1010
- [args.l1Token, args.destinationChainId],
1011
- [
1012
- {
1013
- l1Token: EvmAddress.from(args.l1Token),
1014
- l2Token: destinationToken,
1015
- blockNumber: args.blockNumber,
1016
- txnIndex: args.txnIndex,
1017
- logIndex: args.logIndex,
1018
- txnRef: args.txnRef,
1019
- },
1020
- ]
1021
- );
975
+ const newRoute: DestinationTokenWithBlock = {
976
+ l1Token: EvmAddress.from(args.l1Token),
977
+ l2Token: destinationToken,
978
+ blockNumber: args.blockNumber,
979
+ txnIndex: args.txnIndex,
980
+ logIndex: args.logIndex,
981
+ txnRef: args.txnRef,
982
+ };
983
+ if (this.l1TokensToDestinationTokensWithBlock[args.l1Token]?.[args.destinationChainId]) {
984
+ // Events are most likely coming in descending orders already but just in case we sort them again.
985
+ this.l1TokensToDestinationTokensWithBlock[args.l1Token][args.destinationChainId] = sortEventsDescending([
986
+ ...this.l1TokensToDestinationTokensWithBlock[args.l1Token][args.destinationChainId],
987
+ newRoute,
988
+ ]);
989
+ } else {
990
+ assign(this.l1TokensToDestinationTokensWithBlock, [args.l1Token, args.destinationChainId], [newRoute]);
1022
991
  }
1023
992
  }
1024
993
  }
@@ -474,18 +474,22 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
474
474
  )
475
475
  ) {
476
476
  return false;
477
- } else {
478
- const l1Token = this.hubPoolClient?.getL1TokenForL2TokenAtBlock(
479
- deposit.inputToken,
480
- deposit.originChainId,
481
- deposit.quoteBlockNumber
482
- );
483
- return this.hubPoolClient.l2TokenEnabledForL1TokenAtBlock(
484
- l1Token,
485
- deposit.destinationChainId,
486
- deposit.quoteBlockNumber
487
- );
488
477
  }
478
+
479
+ const l1Token = this.hubPoolClient?.getL1TokenForL2TokenAtBlock(
480
+ deposit.inputToken,
481
+ deposit.originChainId,
482
+ deposit.quoteBlockNumber
483
+ );
484
+ if (!l1Token) {
485
+ return false;
486
+ }
487
+
488
+ return this.hubPoolClient.l2TokenEnabledForL1TokenAtBlock(
489
+ l1Token,
490
+ deposit.destinationChainId,
491
+ deposit.quoteBlockNumber
492
+ );
489
493
  }
490
494
 
491
495
  /**
@@ -118,9 +118,9 @@ export class MockHubPoolClient extends HubPoolClient {
118
118
  delete this.spokePoolTokens[l1Token]?.[chainId];
119
119
  }
120
120
 
121
- getL1TokenForL2TokenAtBlock(l2Token: Address, chainId: number, blockNumber: number): EvmAddress {
121
+ getL1TokenForL2TokenAtBlock(l2Token: Address, chainId: number, blockNumber: number): EvmAddress | undefined {
122
122
  const l1Token = Object.keys(this.spokePoolTokens).find(
123
- (l1Token) => this.spokePoolTokens[l1Token]?.[chainId].eq(l2Token)
123
+ (l1Token) => this.spokePoolTokens[l1Token]?.[chainId]?.eq(l2Token)
124
124
  );
125
125
  if (isDefined(l1Token)) {
126
126
  return EvmAddress.from(l1Token);
@@ -129,7 +129,7 @@ export class MockHubPoolClient extends HubPoolClient {
129
129
  }
130
130
  }
131
131
 
132
- getL2TokenForL1TokenAtBlock(l1Token: EvmAddress, chainId: number, blockNumber: number): Address {
132
+ getL2TokenForL1TokenAtBlock(l1Token: EvmAddress, chainId: number, blockNumber: number): Address | undefined {
133
133
  const l2Token = this.spokePoolTokens[l1Token.toEvmAddress()]?.[chainId];
134
134
  return l2Token ?? super.getL2TokenForL1TokenAtBlock(l1Token, chainId, blockNumber);
135
135
  }