@across-protocol/sdk 4.3.53 → 4.3.54

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 (55) hide show
  1. package/dist/cjs/arch/evm/SpokeUtils.js +2 -3
  2. package/dist/cjs/arch/evm/SpokeUtils.js.map +1 -1
  3. package/dist/cjs/arch/svm/SpokeUtils.d.ts +1 -1
  4. package/dist/cjs/arch/svm/SpokeUtils.js +24 -23
  5. package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
  6. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.d.ts +60 -60
  7. package/dist/cjs/clients/HubPoolClient.js +28 -32
  8. package/dist/cjs/clients/HubPoolClient.js.map +1 -1
  9. package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js +12 -17
  10. package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
  11. package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.js +4 -3
  12. package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.js.map +1 -1
  13. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.d.ts +4 -4
  14. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js +15 -23
  15. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  16. package/dist/cjs/utils/SpokeUtils.d.ts +3 -1
  17. package/dist/cjs/utils/SpokeUtils.js +12 -1
  18. package/dist/cjs/utils/SpokeUtils.js.map +1 -1
  19. package/dist/esm/arch/evm/SpokeUtils.js +5 -6
  20. package/dist/esm/arch/evm/SpokeUtils.js.map +1 -1
  21. package/dist/esm/arch/svm/SpokeUtils.d.ts +1 -1
  22. package/dist/esm/arch/svm/SpokeUtils.js +26 -26
  23. package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
  24. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.d.ts +60 -60
  25. package/dist/esm/clients/HubPoolClient.js +29 -34
  26. package/dist/esm/clients/HubPoolClient.js.map +1 -1
  27. package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js +13 -18
  28. package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
  29. package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.js +4 -6
  30. package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.js.map +1 -1
  31. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.d.ts +4 -4
  32. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +16 -24
  33. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  34. package/dist/esm/utils/SpokeUtils.d.ts +16 -1
  35. package/dist/esm/utils/SpokeUtils.js +24 -2
  36. package/dist/esm/utils/SpokeUtils.js.map +1 -1
  37. package/dist/types/arch/evm/SpokeUtils.d.ts.map +1 -1
  38. package/dist/types/arch/svm/SpokeUtils.d.ts +1 -1
  39. package/dist/types/arch/svm/SpokeUtils.d.ts.map +1 -1
  40. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts +60 -60
  41. package/dist/types/clients/HubPoolClient.d.ts.map +1 -1
  42. package/dist/types/clients/SpokePoolClient/EVMSpokePoolClient.d.ts.map +1 -1
  43. package/dist/types/clients/SpokePoolClient/SVMSpokePoolClient.d.ts.map +1 -1
  44. package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts +4 -4
  45. package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts.map +1 -1
  46. package/dist/types/utils/SpokeUtils.d.ts +16 -1
  47. package/dist/types/utils/SpokeUtils.d.ts.map +1 -1
  48. package/package.json +2 -2
  49. package/src/arch/evm/SpokeUtils.ts +4 -35
  50. package/src/arch/svm/SpokeUtils.ts +26 -59
  51. package/src/clients/HubPoolClient.ts +34 -28
  52. package/src/clients/SpokePoolClient/EVMSpokePoolClient.ts +12 -31
  53. package/src/clients/SpokePoolClient/SVMSpokePoolClient.ts +5 -4
  54. package/src/clients/SpokePoolClient/SpokePoolClient.ts +31 -92
  55. package/src/utils/SpokeUtils.ts +98 -2
@@ -193,14 +193,14 @@ export class HubPoolClient extends BaseAbstractClient {
193
193
  destinationChainId: number,
194
194
  latestHubBlock = Number.MAX_SAFE_INTEGER
195
195
  ): Address {
196
- if (!this.l1TokensToDestinationTokensWithBlock?.[l1Token.toEvmAddress()]?.[destinationChainId]) {
196
+ if (!this.l1TokensToDestinationTokensWithBlock?.[l1Token.toNative()]?.[destinationChainId]) {
197
197
  const chain = getNetworkName(destinationChainId);
198
198
  const { symbol } = this.l1Tokens.find(({ address }) => address.eq(l1Token)) ?? { symbol: l1Token.toString() };
199
199
  throw new Error(`Could not find SpokePool mapping for ${symbol} on ${chain} and L1 token ${l1Token}`);
200
200
  }
201
201
  // Find the last mapping published before the target block.
202
202
  const l2Token: DestinationTokenWithBlock | undefined = sortEventsDescending(
203
- this.l1TokensToDestinationTokensWithBlock[l1Token.toEvmAddress()][destinationChainId]
203
+ this.l1TokensToDestinationTokensWithBlock[l1Token.toNative()][destinationChainId]
204
204
  ).find((mapping: DestinationTokenWithBlock) => mapping.blockNumber <= latestHubBlock);
205
205
  if (!l2Token) {
206
206
  const chain = getNetworkName(destinationChainId);
@@ -250,13 +250,13 @@ export class HubPoolClient extends BaseAbstractClient {
250
250
  }
251
251
 
252
252
  l2TokenEnabledForL1Token(l1Token: EvmAddress, destinationChainId: number): boolean {
253
- return this.l1TokensToDestinationTokens?.[l1Token.toEvmAddress()]?.[destinationChainId] != undefined;
253
+ return this.l1TokensToDestinationTokens?.[l1Token.toNative()]?.[destinationChainId] != undefined;
254
254
  }
255
255
 
256
256
  l2TokenEnabledForL1TokenAtBlock(l1Token: EvmAddress, destinationChainId: number, hubBlockNumber: number): boolean {
257
257
  // Find the last mapping published before the target block.
258
258
  const l2Token: DestinationTokenWithBlock | undefined = sortEventsDescending(
259
- this.l1TokensToDestinationTokensWithBlock?.[l1Token.toEvmAddress()]?.[destinationChainId] ?? []
259
+ this.l1TokensToDestinationTokensWithBlock?.[l1Token.toNative()]?.[destinationChainId] ?? []
260
260
  ).find((mapping: DestinationTokenWithBlock) => mapping.blockNumber <= hubBlockNumber);
261
261
  return l2Token !== undefined;
262
262
  }
@@ -340,18 +340,14 @@ export class HubPoolClient extends BaseAbstractClient {
340
340
  timeToCache: number
341
341
  ): Promise<BigNumber> {
342
342
  // Resolve this function call as an async anonymous function
343
- const resolver = async () => {
343
+ const resolver = () => {
344
344
  const overrides = { blockTag: blockNumber };
345
- if (depositAmount.eq(0)) {
346
- // For zero amount, just get the utilisation at `blockNumber`.
347
- return await this.hubPool.callStatic.liquidityUtilizationCurrent(hubPoolToken.toEvmAddress(), overrides);
348
- }
345
+ const token = hubPoolToken.toNative();
349
346
 
350
- return await this.hubPool.callStatic.liquidityUtilizationPostRelay(
351
- hubPoolToken.toEvmAddress(),
352
- depositAmount,
353
- overrides
354
- );
347
+ // For zero amount, just get the utilisation at `blockNumber`.
348
+ return depositAmount.eq(bnZero)
349
+ ? this.hubPool.callStatic.liquidityUtilizationCurrent(token, overrides)
350
+ : this.hubPool.callStatic.liquidityUtilizationPostRelay(token, depositAmount, overrides);
355
351
  };
356
352
 
357
353
  // Resolve the cache locally so that we can appease typescript
@@ -363,11 +359,9 @@ export class HubPoolClient extends BaseAbstractClient {
363
359
  }
364
360
 
365
361
  // Otherwise, let's resolve the key
366
- // @note Avoid collisions with pre-existing cache keys by appending an underscore (_) for post-relay utilization.
367
- // @fixme This can be removed once the existing keys have been ejected from the cache (i.e. 7 days).
368
- const key = depositAmount.eq(0)
369
- ? `utilization_${hubPoolToken.toEvmAddress()}_${blockNumber}`
370
- : `utilization_${hubPoolToken.toEvmAddress()}_${blockNumber}_${depositAmount.toString()}_`;
362
+ const key = depositAmount.eq(bnZero)
363
+ ? `utilization_${hubPoolToken.toNative()}_${blockNumber}`
364
+ : `utilization_${hubPoolToken.toNative()}_${blockNumber}_${depositAmount.toString()}`;
371
365
  const result = await cache.get<string>(key);
372
366
  if (isDefined(result)) {
373
367
  return BigNumber.from(result);
@@ -409,9 +403,19 @@ export class HubPoolClient extends BaseAbstractClient {
409
403
  const tokenKey = `${deposit.originChainId}-${deposit.inputToken}`;
410
404
  if (this.l2TokenHasPoolRebalanceRoute(deposit.inputToken, deposit.originChainId, quoteBlockNumber)) {
411
405
  return (hubPoolTokens[tokenKey] ??= this.getL1TokenForDeposit({ ...deposit, quoteBlockNumber }));
412
- } else return undefined;
406
+ }
407
+
408
+ return undefined;
413
409
  };
414
- const getHubPoolTokens = (): EvmAddress[] => dedupArray(Object.values(hubPoolTokens).filter(isDefined));
410
+
411
+ // Filter hubPoolTokens for duplicates by reverting to their native string
412
+ // representation. This is required for deduplication to work reliably.
413
+ const getHubPoolTokens = (): EvmAddress[] =>
414
+ dedupArray(
415
+ Object.values(hubPoolTokens)
416
+ .filter(isDefined)
417
+ .map((token) => token.toNative())
418
+ ).map((token) => EvmAddress.from(token));
415
419
 
416
420
  // Helper to resolve the unqiue hubPoolToken & quoteTimestamp mappings.
417
421
  const resolveUniqueQuoteTimestamps = (deposit: LpFeeRequest): void => {
@@ -425,9 +429,10 @@ export class HubPoolClient extends BaseAbstractClient {
425
429
  }
426
430
 
427
431
  // Append the quoteTimestamp for this HubPool token, if it isn't already enqueued.
428
- utilizationTimestamps[hubPoolToken.toEvmAddress()] ??= [];
429
- if (!utilizationTimestamps[hubPoolToken.toEvmAddress()].includes(quoteTimestamp)) {
430
- utilizationTimestamps[hubPoolToken.toEvmAddress()].push(quoteTimestamp);
432
+ const token = hubPoolToken.toNative();
433
+ utilizationTimestamps[token] ??= [];
434
+ if (!utilizationTimestamps[token].includes(quoteTimestamp)) {
435
+ utilizationTimestamps[token].push(quoteTimestamp);
431
436
  }
432
437
  };
433
438
 
@@ -435,7 +440,7 @@ export class HubPoolClient extends BaseAbstractClient {
435
440
  // Produces a mapping of blockNumber -> utilization for a specific token.
436
441
  const resolveUtilization = async (hubPoolToken: EvmAddress): Promise<Record<number, BigNumber>> => {
437
442
  return Object.fromEntries(
438
- await mapAsync(utilizationTimestamps[hubPoolToken.toEvmAddress()], async (quoteTimestamp) => {
443
+ await mapAsync(utilizationTimestamps[hubPoolToken.toNative()], async (quoteTimestamp) => {
439
444
  const blockNumber = quoteBlocks[quoteTimestamp];
440
445
  const utilization = await this.getUtilization(
441
446
  hubPoolToken,
@@ -471,7 +476,7 @@ export class HubPoolClient extends BaseAbstractClient {
471
476
  quoteBlock
472
477
  );
473
478
 
474
- const preUtilization = utilization[hubPoolToken.toEvmAddress()][quoteBlock];
479
+ const preUtilization = utilization[hubPoolToken.toNative()][quoteBlock];
475
480
  const postUtilization = await this.getUtilization(
476
481
  hubPoolToken,
477
482
  quoteBlock,
@@ -500,7 +505,7 @@ export class HubPoolClient extends BaseAbstractClient {
500
505
  // This can be reused for each deposit with the same HubPool token and quoteTimestamp pair.
501
506
  utilization = Object.fromEntries(
502
507
  await mapAsync(getHubPoolTokens(), async (hubPoolToken) => [
503
- hubPoolToken.toEvmAddress(),
508
+ hubPoolToken.toNative(),
504
509
  await resolveUtilization(hubPoolToken),
505
510
  ])
506
511
  );
@@ -529,7 +534,7 @@ export class HubPoolClient extends BaseAbstractClient {
529
534
  }
530
535
 
531
536
  getLpTokenInfoForL1Token(l1Token: EvmAddress): LpToken | undefined {
532
- return this.lpTokens[l1Token.toEvmAddress()];
537
+ return this.lpTokens[l1Token.toNative()];
533
538
  }
534
539
 
535
540
  areTokensEquivalent(
@@ -925,6 +930,7 @@ export class HubPoolClient extends BaseAbstractClient {
925
930
  if (!this.configStoreClient.isUpdated) {
926
931
  throw new Error("ConfigStoreClient not updated");
927
932
  }
933
+
928
934
  const update = await this._update(eventsToQuery);
929
935
  if (!update.success) {
930
936
  if (update.reason !== UpdateFailureReason.AlreadyUpdated) {
@@ -11,13 +11,12 @@ import { DepositWithBlock, FillStatus, RelayData } from "../../interfaces";
11
11
  import {
12
12
  BigNumber,
13
13
  DepositSearchResult,
14
- getMessageHash,
15
14
  getNetworkName,
16
15
  InvalidFill,
17
16
  MakeOptional,
18
17
  toBN,
19
18
  EvmAddress,
20
- toAddressType,
19
+ unpackDepositEvent,
21
20
  } from "../../utils";
22
21
  import {
23
22
  EventSearchConfig,
@@ -195,37 +194,19 @@ export class EVMSpokePoolClient extends SpokePoolClient {
195
194
  };
196
195
  }
197
196
 
198
- const spreadEvent = spreadEventWithBlockNumber(event) as Omit<
199
- DepositWithBlock,
200
- "originChainId" | "inputToken" | "outputToken" | "depositor" | "recipient" | "exclusiveRelayer"
201
- > & {
202
- inputToken: string;
203
- outputToken: string;
204
- depositor: string;
205
- recipient: string;
206
- exclusiveRelayer: string;
207
- };
197
+ const partialDeposit = unpackDepositEvent(spreadEventWithBlockNumber(event), this.chainId);
198
+ const quoteBlockNumber = await this.getBlockNumber(partialDeposit.quoteTimestamp);
199
+ const outputToken = partialDeposit.outputToken.isZeroAddress()
200
+ ? this.getDestinationTokenForDeposit({ ...partialDeposit, quoteBlockNumber })
201
+ : partialDeposit.outputToken;
208
202
 
209
- const originChainId = this.chainId;
210
203
  deposit = {
211
- ...spreadEvent,
212
- originChainId: this.chainId,
213
- inputToken: toAddressType(spreadEvent.inputToken, originChainId),
214
- outputToken: toAddressType(spreadEvent.outputToken, spreadEvent.destinationChainId),
215
- depositor: toAddressType(spreadEvent.depositor, originChainId),
216
- recipient: toAddressType(spreadEvent.recipient, spreadEvent.destinationChainId),
217
- exclusiveRelayer: toAddressType(spreadEvent.exclusiveRelayer, spreadEvent.destinationChainId),
218
- quoteBlockNumber: await this.getBlockNumber(spreadEvent.quoteTimestamp),
219
- messageHash: getMessageHash(spreadEvent.message),
220
- fromLiteChain: true, // To be updated immediately afterwards.
221
- toLiteChain: true, // To be updated immediately afterwards.
222
- };
223
-
224
- if (deposit.outputToken.isZeroAddress()) {
225
- deposit.outputToken = this.getDestinationTokenForDeposit(deposit);
226
- }
227
- deposit.fromLiteChain = this.isOriginLiteChain(deposit);
228
- deposit.toLiteChain = this.isDestinationLiteChain(deposit);
204
+ ...partialDeposit,
205
+ outputToken,
206
+ quoteBlockNumber,
207
+ fromLiteChain: this.isOriginLiteChain(partialDeposit),
208
+ toLiteChain: this.isDestinationLiteChain(partialDeposit),
209
+ } satisfies DepositWithBlock;
229
210
 
230
211
  this.logger.debug({
231
212
  at: "SpokePoolClient#findDeposit",
@@ -227,15 +227,16 @@ export class SVMSpokePoolClient extends SpokePoolClient {
227
227
  };
228
228
  }
229
229
 
230
- // Because we have additional context about this deposit, we can enrich it
231
- // with additional information.
230
+ // Because we have additional context about this deposit, we can enrich it with additional information.
231
+ // outputToken is known to not be 0x0 on SVM SpokePool implementations.
232
+ const originChainId = this.chainId;
232
233
  return {
233
234
  found: true,
234
235
  deposit: {
235
236
  ...deposit,
237
+ originChainId,
236
238
  quoteBlockNumber: await this.getBlockNumber(Number(deposit.quoteTimestamp)),
237
- originChainId: this.chainId,
238
- fromLiteChain: this.isOriginLiteChain(deposit),
239
+ fromLiteChain: this.isOriginLiteChain({ ...deposit, originChainId }),
239
240
  toLiteChain: this.isDestinationLiteChain(deposit),
240
241
  },
241
242
  };
@@ -13,13 +13,14 @@ import {
13
13
  assign,
14
14
  getRelayEventKey,
15
15
  isDefined,
16
- getMessageHash,
17
16
  isSlowFill,
18
17
  validateFillForDeposit,
19
18
  chainIsEvm,
20
19
  chainIsProd,
21
20
  Address,
22
21
  toAddressType,
22
+ unpackDepositEvent,
23
+ unpackFillEvent,
23
24
  } from "../../utils";
24
25
  import { duplicateEvent, sortEventsAscendingInPlace } from "../../utils/EventUtils";
25
26
  import { CHAIN_IDs, ZERO_ADDRESS } from "../../constants";
@@ -39,7 +40,6 @@ import {
39
40
  SortableEvent,
40
41
  SpeedUpWithBlock,
41
42
  TokensBridged,
42
- RelayExecutionEventInfo,
43
43
  } from "../../interfaces";
44
44
  import { BaseAbstractClient, UpdateFailureReason } from "../BaseAbstractClient";
45
45
  import { AcrossConfigStoreClient } from "../AcrossConfigStoreClient";
@@ -463,7 +463,9 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
463
463
  return `${event.depositId.toString()}-${event.originChainId}`;
464
464
  }
465
465
 
466
- protected canResolveZeroAddressOutputToken(deposit: DepositWithBlock): boolean {
466
+ protected canResolveZeroAddressOutputToken(
467
+ deposit: Pick<DepositWithBlock, "originChainId" | "inputToken" | "quoteBlockNumber" | "destinationChainId">
468
+ ): boolean {
467
469
  if (
468
470
  !this.hubPoolClient?.l2TokenHasPoolRebalanceRoute(
469
471
  deposit.inputToken,
@@ -519,39 +521,10 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
519
521
  }
520
522
 
521
523
  // Performs the indexing of a deposit-like spoke pool event.
522
- const originChainId = this.chainId;
523
524
  const queryDepositEvents = async (eventName: string) => {
524
- const depositEvents = (queryResults[eventsToQuery.indexOf(eventName)] ?? []).map((_event) => {
525
- const event = _event as Omit<
526
- DepositWithBlock,
527
- "originChainId" | "depositor" | "recipient" | "inputToken" | "outputToken" | "exclusiveRelayer"
528
- > & {
529
- depositor: string;
530
- recipient: string;
531
- inputToken: string;
532
- outputToken: string;
533
- exclusiveRelayer: string;
534
- };
535
- return {
536
- ...event,
537
- originChainId,
538
- depositor: toAddressType(event.depositor, originChainId),
539
- recipient: toAddressType(event.recipient, event.destinationChainId),
540
- inputToken: toAddressType(event.inputToken, originChainId),
541
- outputToken: toAddressType(event.outputToken, event.destinationChainId),
542
- exclusiveRelayer: toAddressType(event.exclusiveRelayer, event.destinationChainId),
543
- messageHash: getMessageHash(event.message),
544
- } satisfies Omit<DepositWithBlock, "quoteBlockNumber" | "fromLiteChain" | "toLiteChain">;
545
- });
546
- if (depositEvents.length > 0) {
547
- this.log(
548
- "debug",
549
- `Using ${depositEvents.length} newly queried ${eventName} deposit events for chain ${this.chainId}`,
550
- {
551
- earliestEvent: depositEvents[0].blockNumber,
552
- }
553
- );
554
- }
525
+ const depositEvents = (queryResults[eventsToQuery.indexOf(eventName)] ?? []).map((event) =>
526
+ unpackDepositEvent(event, this.chainId)
527
+ );
555
528
 
556
529
  // For each deposit, resolve its quoteTimestamp to a block number on the HubPool.
557
530
  // Don't bother filtering for uniqueness; the HubPoolClient handles this efficienctly.
@@ -560,16 +533,17 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
560
533
  const quoteBlockNumber = quoteBlockNumbers[Number(event.quoteTimestamp)];
561
534
 
562
535
  // Derive and append the common properties that are not part of the onchain event.
536
+ const outputToken = event.outputToken.isZeroAddress()
537
+ ? this.getDestinationTokenForDeposit({ ...event, quoteBlockNumber })
538
+ : event.outputToken;
539
+
563
540
  const deposit = {
564
541
  ...event,
542
+ outputToken,
565
543
  quoteBlockNumber,
566
544
  fromLiteChain: this.isOriginLiteChain(event),
567
545
  toLiteChain: this.isDestinationLiteChain(event),
568
- };
569
-
570
- if (deposit.outputToken.isZeroAddress()) {
571
- deposit.outputToken = this.getDestinationTokenForDeposit(deposit);
572
- }
546
+ } satisfies DepositWithBlock;
573
547
 
574
548
  if (this.depositHashes[getRelayEventKey(deposit)] !== undefined) {
575
549
  // Sanity check that this event is not a duplicate, even though the relay data hash is a duplicate.
@@ -645,6 +619,7 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
645
619
 
646
620
  // Performs indexing of "requested slow fill"-like events.
647
621
  const queryRequestedSlowFillEvents = (eventName: string) => {
622
+ const destinationChainId = this.chainId;
648
623
  const slowFillRequests = (queryResults[eventsToQuery.indexOf(eventName)] ?? []).map((_event) => {
649
624
  const event = _event as Omit<
650
625
  SlowFillRequestWithBlock,
@@ -658,24 +633,21 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
658
633
  };
659
634
  return {
660
635
  ...event,
636
+ destinationChainId,
661
637
  depositor: toAddressType(event.depositor, event.originChainId),
662
- recipient: toAddressType(event.recipient, this.chainId),
638
+ recipient: toAddressType(event.recipient, destinationChainId),
663
639
  inputToken: toAddressType(event.inputToken, event.originChainId),
664
- outputToken: toAddressType(event.outputToken, this.chainId),
665
- exclusiveRelayer: toAddressType(event.exclusiveRelayer, this.chainId),
666
- } as SlowFillRequestWithBlock;
640
+ outputToken: toAddressType(event.outputToken, destinationChainId),
641
+ exclusiveRelayer: toAddressType(event.exclusiveRelayer, destinationChainId),
642
+ } satisfies SlowFillRequestWithBlock;
667
643
  });
668
- for (const event of slowFillRequests) {
669
- const slowFillRequest = {
670
- ...event,
671
- destinationChainId: this.chainId,
672
- };
673
644
 
674
- const depositHash = getRelayEventKey({ ...slowFillRequest, destinationChainId: this.chainId });
645
+ for (const slowFillRequest of slowFillRequests) {
646
+ const depositHash = getRelayEventKey(slowFillRequest);
675
647
 
676
648
  // Sanity check that this event is not a duplicate.
677
649
  if (this.slowFillRequests[depositHash] !== undefined) {
678
- duplicateEvents.push(event);
650
+ duplicateEvents.push(slowFillRequest);
679
651
  continue;
680
652
  }
681
653
 
@@ -690,45 +662,10 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
690
662
  });
691
663
 
692
664
  // Performs indexing of filled relay-like events.
693
- const destinationChainId = this.chainId;
694
665
  const queryFilledRelayEvents = (eventName: string) => {
695
- const fillEvents = (queryResults[eventsToQuery.indexOf(eventName)] ?? []).map((_event) => {
696
- const event = _event as Omit<
697
- FillWithBlock,
698
- | "destinationChainId"
699
- | "depositor"
700
- | "recipient"
701
- | "inputToken"
702
- | "outputToken"
703
- | "exclusiveRelayer"
704
- | "relayer"
705
- | "relayExecutionInfo"
706
- > & {
707
- depositor: string;
708
- recipient: string;
709
- inputToken: string;
710
- outputToken: string;
711
- exclusiveRelayer: string;
712
- relayer: string;
713
- relayExecutionInfo: Omit<RelayExecutionEventInfo, "updatedRecipient"> & { updatedRecipient: string };
714
- };
715
-
716
- return {
717
- ...event,
718
- destinationChainId,
719
- depositor: toAddressType(event.depositor, event.originChainId),
720
- recipient: toAddressType(event.recipient, destinationChainId),
721
- inputToken: toAddressType(event.inputToken, event.originChainId),
722
- outputToken: toAddressType(event.outputToken, destinationChainId),
723
- exclusiveRelayer: toAddressType(event.exclusiveRelayer, destinationChainId),
724
- relayer: toAddressType(event.relayer, event.repaymentChainId),
725
- relayExecutionInfo: {
726
- ...event.relayExecutionInfo,
727
- updatedRecipient: toAddressType(event.relayExecutionInfo.updatedRecipient, this.chainId),
728
- },
729
- } satisfies FillWithBlock;
730
- });
731
-
666
+ const fillEvents = (queryResults[eventsToQuery.indexOf(eventName)] ?? []).map((event) =>
667
+ unpackFillEvent(event, this.chainId)
668
+ );
732
669
  if (fillEvents.length > 0) {
733
670
  this.log("debug", `Using ${fillEvents.length} newly queried ${eventName} events for chain ${this.chainId}`, {
734
671
  earliestEvent: fillEvents[0].blockNumber,
@@ -858,7 +795,9 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
858
795
  * @param deposit The deposit to retrieve the destination token for.
859
796
  * @returns The destination token.
860
797
  */
861
- protected getDestinationTokenForDeposit(deposit: DepositWithBlock): Address {
798
+ protected getDestinationTokenForDeposit(
799
+ deposit: Pick<DepositWithBlock, "originChainId" | "inputToken" | "quoteBlockNumber" | "destinationChainId">
800
+ ): Address {
862
801
  if (!this.canResolveZeroAddressOutputToken(deposit)) {
863
802
  return toAddressType(ZERO_ADDRESS, CHAIN_IDs.MAINNET);
864
803
  }
@@ -900,7 +839,7 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
900
839
  * @returns True if the deposit originates from a lite chain, false otherwise. If the hub pool client is not defined,
901
840
  * this method will return false.
902
841
  */
903
- protected isOriginLiteChain(deposit: DepositWithBlock): boolean {
842
+ protected isOriginLiteChain(deposit: Pick<DepositWithBlock, "originChainId" | "quoteTimestamp">): boolean {
904
843
  return this.configStoreClient?.isChainLiteChainAtTimestamp(deposit.originChainId, deposit.quoteTimestamp) ?? false;
905
844
  }
906
845
 
@@ -910,7 +849,7 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
910
849
  * @returns True if the deposit is destined to a lite chain, false otherwise. If the hub pool client is not defined,
911
850
  * this method will return false.
912
851
  */
913
- protected isDestinationLiteChain(deposit: DepositWithBlock): boolean {
852
+ protected isDestinationLiteChain(deposit: Pick<DepositWithBlock, "destinationChainId" | "quoteTimestamp">): boolean {
914
853
  return (
915
854
  this.configStoreClient?.isChainLiteChainAtTimestamp(deposit.destinationChainId, deposit.quoteTimestamp) ?? false
916
855
  );
@@ -1,11 +1,21 @@
1
1
  import { encodeAbiParameters, Hex, keccak256 } from "viem";
2
2
  import { fixedPointAdjustment as fixedPoint } from "./common";
3
3
  import { MAX_SAFE_DEPOSIT_ID, ZERO_BYTES } from "../constants";
4
- import { Fill, FillType, RelayData, SlowFillLeaf } from "../interfaces";
4
+ import {
5
+ DepositWithBlock,
6
+ Fill,
7
+ FillWithBlock,
8
+ FillType,
9
+ RelayData,
10
+ RelayExecutionEventInfo,
11
+ SlowFillLeaf,
12
+ SortableEvent,
13
+ } from "../interfaces";
14
+ import { svm } from "../arch";
5
15
  import { BigNumber } from "./BigNumberUtils";
6
16
  import { isMessageEmpty } from "./DepositUtils";
7
17
  import { chainIsSvm } from "./NetworkUtils";
8
- import { svm } from "../arch";
18
+ import { toAddressType } from "./AddressUtils";
9
19
 
10
20
  export function isSlowFill(fill: Fill): boolean {
11
21
  return fill.relayExecutionInfo.fillType === FillType.SlowFill;
@@ -15,6 +25,92 @@ export function getSlowFillLeafLpFeePct(leaf: SlowFillLeaf): BigNumber {
15
25
  const { relayData, updatedOutputAmount } = leaf;
16
26
  return relayData.inputAmount.sub(updatedOutputAmount).mul(fixedPoint).div(relayData.inputAmount);
17
27
  }
28
+
29
+ /**
30
+ * Given a SortableEvent type, unpack the available FundsDeposited fields.
31
+ * @note Some fields cannot be evaluated without additional context - i.e. quoteBlockNumber, {from,to}LiteChain.
32
+ * @param rawEvent emitted by FundsDeposited event.
33
+ * @param originChainId Deposit originChainId
34
+ * @returns A mostly-populated DepositWithBlock event.
35
+ */
36
+ export function unpackDepositEvent(
37
+ rawEvent: SortableEvent,
38
+ originChainId: number
39
+ ): Omit<DepositWithBlock, "quoteBlockNumber" | "fromLiteChain" | "toLiteChain"> {
40
+ const event = rawEvent as Omit<
41
+ DepositWithBlock,
42
+ | "originChainId"
43
+ | "depositor"
44
+ | "recipient"
45
+ | "inputToken"
46
+ | "outputToken"
47
+ | "exclusiveRelayer"
48
+ | "quoteBlockNumber"
49
+ | "fromLiteChain"
50
+ | "toLiteChain"
51
+ > & {
52
+ depositor: string;
53
+ recipient: string;
54
+ inputToken: string;
55
+ outputToken: string;
56
+ exclusiveRelayer: string;
57
+ };
58
+
59
+ return {
60
+ ...event,
61
+ originChainId,
62
+ depositor: toAddressType(event.depositor, originChainId),
63
+ recipient: toAddressType(event.recipient, event.destinationChainId),
64
+ inputToken: toAddressType(event.inputToken, originChainId),
65
+ outputToken: toAddressType(event.outputToken, event.destinationChainId),
66
+ exclusiveRelayer: toAddressType(event.exclusiveRelayer, event.destinationChainId),
67
+ messageHash: getMessageHash(event.message),
68
+ } satisfies Omit<DepositWithBlock, "quoteBlockNumber" | "fromLiteChain" | "toLiteChain">;
69
+ }
70
+
71
+ /**
72
+ * Given a SortableEvent type, unpack the complete set of FilledRelay fields.
73
+ * @param rawEvent emitted by FundsDeposited event.
74
+ * @param originChainId Deposit originChainId
75
+ * @returns A mostly-populated DepositWithBlock event.
76
+ */
77
+ export function unpackFillEvent(rawEvent: SortableEvent, destinationChainId: number): FillWithBlock {
78
+ const event = rawEvent as Omit<
79
+ FillWithBlock,
80
+ | "destinationChainId"
81
+ | "depositor"
82
+ | "recipient"
83
+ | "inputToken"
84
+ | "outputToken"
85
+ | "exclusiveRelayer"
86
+ | "relayer"
87
+ | "relayerExecutionInfo"
88
+ > & {
89
+ depositor: string;
90
+ recipient: string;
91
+ inputToken: string;
92
+ outputToken: string;
93
+ exclusiveRelayer: string;
94
+ relayer: string;
95
+ relayExecutionInfo: Omit<RelayExecutionEventInfo, "updatedRecipient"> & { updatedRecipient: string };
96
+ };
97
+
98
+ return {
99
+ ...event,
100
+ destinationChainId,
101
+ depositor: toAddressType(event.depositor, event.originChainId),
102
+ recipient: toAddressType(event.recipient, destinationChainId),
103
+ inputToken: toAddressType(event.inputToken, event.originChainId),
104
+ outputToken: toAddressType(event.outputToken, destinationChainId),
105
+ exclusiveRelayer: toAddressType(event.exclusiveRelayer, destinationChainId),
106
+ relayer: toAddressType(event.relayer, event.repaymentChainId),
107
+ relayExecutionInfo: {
108
+ ...event.relayExecutionInfo,
109
+ updatedRecipient: toAddressType(event.relayExecutionInfo.updatedRecipient, destinationChainId),
110
+ },
111
+ } satisfies FillWithBlock;
112
+ }
113
+
18
114
  /**
19
115
  * Compute the RelayData hash for a fill. This can be used to determine the fill status.
20
116
  * @param relayData RelayData information that is used to complete a fill.