@across-protocol/sdk 4.1.45 → 4.1.46-beta.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 (116) hide show
  1. package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts +3 -3
  2. package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +15 -11
  3. package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
  4. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +52 -6
  5. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  6. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +1 -1
  7. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  8. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.d.ts +48 -20
  9. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js +8 -6
  10. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  11. package/dist/cjs/clients/HubPoolClient.d.ts +0 -3
  12. package/dist/cjs/clients/HubPoolClient.js +38 -27
  13. package/dist/cjs/clients/HubPoolClient.js.map +1 -1
  14. package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js +1 -1
  15. package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
  16. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js +1 -1
  17. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  18. package/dist/cjs/clients/mocks/MockConfigStoreClient.js +2 -2
  19. package/dist/cjs/clients/mocks/MockConfigStoreClient.js.map +1 -1
  20. package/dist/cjs/clients/mocks/MockHubPoolClient.d.ts +2 -1
  21. package/dist/cjs/clients/mocks/MockHubPoolClient.js +18 -1
  22. package/dist/cjs/clients/mocks/MockHubPoolClient.js.map +1 -1
  23. package/dist/cjs/clients/mocks/MockSpokePoolClient.js +5 -5
  24. package/dist/cjs/clients/mocks/MockSpokePoolClient.js.map +1 -1
  25. package/dist/cjs/interfaces/Common.d.ts +2 -2
  26. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.d.ts +0 -1
  27. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js +0 -5
  28. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
  29. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +0 -1
  30. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
  31. package/dist/cjs/utils/AddressUtils.d.ts +1 -0
  32. package/dist/cjs/utils/AddressUtils.js +3 -0
  33. package/dist/cjs/utils/AddressUtils.js.map +1 -1
  34. package/dist/cjs/utils/EventUtils.d.ts +2 -1
  35. package/dist/cjs/utils/EventUtils.js +21 -12
  36. package/dist/cjs/utils/EventUtils.js.map +1 -1
  37. package/dist/cjs/utils/TokenUtils.js +2 -0
  38. package/dist/cjs/utils/TokenUtils.js.map +1 -1
  39. package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts +3 -3
  40. package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +15 -11
  41. package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
  42. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +58 -7
  43. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  44. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +1 -1
  45. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  46. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.d.ts +48 -20
  47. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js +5 -3
  48. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  49. package/dist/esm/clients/HubPoolClient.d.ts +0 -10
  50. package/dist/esm/clients/HubPoolClient.js +46 -36
  51. package/dist/esm/clients/HubPoolClient.js.map +1 -1
  52. package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js +2 -2
  53. package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
  54. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +1 -1
  55. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  56. package/dist/esm/clients/mocks/MockConfigStoreClient.js +3 -3
  57. package/dist/esm/clients/mocks/MockConfigStoreClient.js.map +1 -1
  58. package/dist/esm/clients/mocks/MockHubPoolClient.d.ts +2 -1
  59. package/dist/esm/clients/mocks/MockHubPoolClient.js +18 -1
  60. package/dist/esm/clients/mocks/MockHubPoolClient.js.map +1 -1
  61. package/dist/esm/clients/mocks/MockSpokePoolClient.js +5 -5
  62. package/dist/esm/clients/mocks/MockSpokePoolClient.js.map +1 -1
  63. package/dist/esm/interfaces/Common.d.ts +2 -2
  64. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.d.ts +0 -6
  65. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js +0 -10
  66. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
  67. package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +0 -1
  68. package/dist/esm/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
  69. package/dist/esm/utils/AddressUtils.d.ts +1 -0
  70. package/dist/esm/utils/AddressUtils.js +3 -0
  71. package/dist/esm/utils/AddressUtils.js.map +1 -1
  72. package/dist/esm/utils/EventUtils.d.ts +2 -1
  73. package/dist/esm/utils/EventUtils.js +18 -10
  74. package/dist/esm/utils/EventUtils.js.map +1 -1
  75. package/dist/esm/utils/TokenUtils.js +2 -0
  76. package/dist/esm/utils/TokenUtils.js.map +1 -1
  77. package/dist/types/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts +3 -3
  78. package/dist/types/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts.map +1 -1
  79. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
  80. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
  81. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts +48 -20
  82. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts.map +1 -1
  83. package/dist/types/clients/HubPoolClient.d.ts +0 -10
  84. package/dist/types/clients/HubPoolClient.d.ts.map +1 -1
  85. package/dist/types/clients/SpokePoolClient/EVMSpokePoolClient.d.ts.map +1 -1
  86. package/dist/types/clients/mocks/MockConfigStoreClient.d.ts.map +1 -1
  87. package/dist/types/clients/mocks/MockHubPoolClient.d.ts +2 -1
  88. package/dist/types/clients/mocks/MockHubPoolClient.d.ts.map +1 -1
  89. package/dist/types/interfaces/Common.d.ts +2 -2
  90. package/dist/types/interfaces/Common.d.ts.map +1 -1
  91. package/dist/types/relayFeeCalculator/chain-queries/baseQuery.d.ts +0 -6
  92. package/dist/types/relayFeeCalculator/chain-queries/baseQuery.d.ts.map +1 -1
  93. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +0 -1
  94. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
  95. package/dist/types/utils/AddressUtils.d.ts +1 -0
  96. package/dist/types/utils/AddressUtils.d.ts.map +1 -1
  97. package/dist/types/utils/EventUtils.d.ts +2 -1
  98. package/dist/types/utils/EventUtils.d.ts.map +1 -1
  99. package/dist/types/utils/TokenUtils.d.ts.map +1 -1
  100. package/package.json +1 -1
  101. package/src/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.ts +17 -15
  102. package/src/clients/BundleDataClient/BundleDataClient.ts +107 -5
  103. package/src/clients/BundleDataClient/utils/FillUtils.ts +1 -3
  104. package/src/clients/BundleDataClient/utils/SuperstructUtils.ts +7 -3
  105. package/src/clients/HubPoolClient.ts +56 -47
  106. package/src/clients/SpokePoolClient/EVMSpokePoolClient.ts +2 -1
  107. package/src/clients/SpokePoolClient/SpokePoolClient.ts +1 -1
  108. package/src/clients/mocks/MockConfigStoreClient.ts +10 -3
  109. package/src/clients/mocks/MockHubPoolClient.ts +26 -2
  110. package/src/clients/mocks/MockSpokePoolClient.ts +5 -5
  111. package/src/interfaces/Common.ts +2 -2
  112. package/src/relayFeeCalculator/chain-queries/baseQuery.ts +0 -10
  113. package/src/relayFeeCalculator/relayFeeCalculator.ts +0 -1
  114. package/src/utils/AddressUtils.ts +4 -0
  115. package/src/utils/EventUtils.ts +19 -13
  116. package/src/utils/TokenUtils.ts +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"TokenUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/TokenUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAC5D,OAAO,EAAY,SAAS,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAM7C,KAAK,gBAAgB,GAAG,SAAS,CAAC,QAAQ,GAAG,MAAM,CAAC;AAEpD,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAI1G;AAED,eAAO,MAAM,mBAAmB,mBACd,MAAM;;aAMvB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAY7E;AAED;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,WAC5B,MAAM,WACL,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAEd,MAAM,GAAG,SAIX,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAoB,GAAG,OAAO,GAAG,SAAS,CAWrH;AAED,wBAAgB,4BAA4B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAM5E;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,gBAAgB,EAClC,QAAQ,GAAE,QAAmB,GAC5B,OAAO,CAAC,SAAS,CAAC,CAGpB;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAI1D;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAIzD;AAED,wBAAgB,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAc7E;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOlF;AAED,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAa/E"}
1
+ {"version":3,"file":"TokenUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/TokenUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAC5D,OAAO,EAAY,SAAS,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAM7C,KAAK,gBAAgB,GAAG,SAAS,CAAC,QAAQ,GAAG,MAAM,CAAC;AAEpD,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAI1G;AAED,eAAO,MAAM,mBAAmB,mBACd,MAAM;;aAMvB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAY7E;AAED;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,WAC5B,MAAM,WACL,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAEd,MAAM,GAAG,SAIX,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAoB,GAAG,OAAO,GAAG,SAAS,CAWrH;AAED,wBAAgB,4BAA4B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAM5E;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,gBAAgB,EAClC,QAAQ,GAAE,QAAmB,GAC5B,OAAO,CAAC,SAAS,CAAC,CAGpB;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAI1D;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAIzD;AAED,wBAAgB,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAc7E;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOlF;AAED,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAe/E"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@across-protocol/sdk",
3
3
  "author": "UMA Team",
4
- "version": "4.1.45",
4
+ "version": "4.1.46-beta.1",
5
5
  "license": "AGPL-3.0",
6
6
  "homepage": "https://docs.across.to/reference/sdk",
7
7
  "files": [
@@ -24,7 +24,6 @@ import {
24
24
  DisabledChainsUpdate,
25
25
  GlobalConfigUpdate,
26
26
  LiteChainsIdListUpdate,
27
- Log,
28
27
  ParsedTokenConfig,
29
28
  RateModelUpdate,
30
29
  RouteRateModelUpdate,
@@ -43,8 +42,8 @@ type ConfigStoreUpdateSuccess = {
43
42
  chainId: number;
44
43
  searchEndBlock: number;
45
44
  events: {
46
- updatedTokenConfigEvents: Log[];
47
- updatedGlobalConfigEvents: Log[];
45
+ updatedTokenConfigEvents: SortableEvent[];
46
+ updatedGlobalConfigEvents: SortableEvent[];
48
47
  globalConfigUpdateTimes: number[];
49
48
  };
50
49
  };
@@ -341,8 +340,13 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
341
340
  paginatedEventQuery(this.configStore, this.configStore.filters.UpdatedGlobalConfig(), searchConfig),
342
341
  ]);
343
342
 
343
+ const updatedTokenConfigSortableEvents = updatedTokenConfigEvents.map(spreadEventWithBlockNumber);
344
+ const updatedGlobalConfigSortableEvents = updatedGlobalConfigEvents.map(spreadEventWithBlockNumber);
345
+
344
346
  // Events *should* normally be received in ascending order, but explicitly enforce the ordering.
345
- [updatedTokenConfigEvents, updatedGlobalConfigEvents].forEach((events) => sortEventsAscendingInPlace(events));
347
+ [updatedTokenConfigSortableEvents, updatedGlobalConfigSortableEvents].forEach((events) =>
348
+ sortEventsAscendingInPlace(events)
349
+ );
346
350
 
347
351
  const globalConfigUpdateTimes = (
348
352
  await Promise.all(updatedGlobalConfigEvents.map((event) => this.configStore.provider.getBlock(event.blockNumber)))
@@ -353,8 +357,8 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
353
357
  chainId,
354
358
  searchEndBlock: searchConfig.toBlock,
355
359
  events: {
356
- updatedTokenConfigEvents,
357
- updatedGlobalConfigEvents,
360
+ updatedTokenConfigEvents: updatedTokenConfigSortableEvents,
361
+ updatedGlobalConfigEvents: updatedGlobalConfigSortableEvents,
358
362
  globalConfigUpdateTimes,
359
363
  },
360
364
  };
@@ -380,13 +384,11 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
380
384
  // Save new TokenConfig updates.
381
385
  for (const event of updatedTokenConfigEvents) {
382
386
  // If transaction hash is known to be invalid, skip it immediately to avoid creating extra logs.
383
- if (KNOWN_INVALID_TOKEN_CONFIG_UPDATE_HASHES.includes(event.transactionHash.toLowerCase())) {
387
+ if (KNOWN_INVALID_TOKEN_CONFIG_UPDATE_HASHES.includes(event.txnRef.toLowerCase())) {
384
388
  continue;
385
389
  }
386
390
 
387
- const args = {
388
- ...(spreadEventWithBlockNumber(event) as TokenConfig),
389
- };
391
+ const args = event as TokenConfig;
390
392
 
391
393
  try {
392
394
  const { rateModel, routeRateModel, spokeTargetBalances } = this.validateTokenConfigUpdate(args);
@@ -418,7 +420,7 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
418
420
  this.logger.debug({
419
421
  at: "ConfigStoreClient::update",
420
422
  message: `Skipping invalid historical update at block ${event.blockNumber}`,
421
- transactionHash: event.transactionHash,
423
+ txnRef: event.txnRef,
422
424
  });
423
425
  }
424
426
  continue;
@@ -427,7 +429,7 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
427
429
 
428
430
  // Save new Global config updates.
429
431
  for (let i = 0; i < updatedGlobalConfigEvents.length; i++) {
430
- const args = spreadEventWithBlockNumber(updatedGlobalConfigEvents[i]) as SortableEvent & {
432
+ const args = updatedGlobalConfigEvents[i] as SortableEvent & {
431
433
  key: string;
432
434
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
433
435
  value: any;
@@ -562,7 +564,7 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
562
564
  rateModel: string | undefined;
563
565
  routeRateModel: RouteRateModelUpdate["routeRateModel"];
564
566
  } {
565
- const { value, key, transactionHash } = args;
567
+ const { value, key, txnRef } = args;
566
568
  const parsedValue = parseJSONWithNumericString(value) as ParsedTokenConfig;
567
569
  const l1Token = key;
568
570
 
@@ -578,7 +580,7 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
578
580
  const rateModel = parsedValue.rateModel;
579
581
  assert(
580
582
  this.isValidRateModel(rateModel),
581
- `Invalid rateModel UBar for ${l1Token} at transaction ${transactionHash}, ${JSON.stringify(rateModel)}`
583
+ `Invalid rateModel UBar for ${l1Token} at transaction ${txnRef}, ${JSON.stringify(rateModel)}`
582
584
  );
583
585
  rateModelForToken = JSON.stringify(rateModel);
584
586
 
@@ -601,7 +603,7 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
601
603
  Object.entries(parsedValue.routeRateModel).map(([path, routeRateModel]) => {
602
604
  assert(
603
605
  this.isValidRateModel(routeRateModel) &&
604
- `Invalid routeRateModel UBar for ${path} for ${l1Token} at transaction ${transactionHash}, ${JSON.stringify(
606
+ `Invalid routeRateModel UBar for ${path} for ${l1Token} at transaction ${txnRef}, ${JSON.stringify(
605
607
  routeRateModel
606
608
  )}`
607
609
  );
@@ -237,13 +237,115 @@ export class BundleDataClient {
237
237
  {} as Record<number, Record<string, UnderlyingType>>
238
238
  );
239
239
 
240
+ const convertSortableEventFieldsIntoRequiredFields = <
241
+ T extends {
242
+ txnIndex?: number;
243
+ transactionIndex?: number;
244
+ txnRef?: string;
245
+ transactionHash?: string;
246
+ },
247
+ >(
248
+ data: T[]
249
+ ): Array<
250
+ Omit<T, "txnIndex" | "transactionIndex" | "txnRef" | "transactionHash"> & {
251
+ txnIndex: number;
252
+ txnRef: string;
253
+ }
254
+ > => {
255
+ return data.map((item) => {
256
+ // For txnIndex/transactionIndex: throw if both are defined or both are missing.
257
+ if (
258
+ (item.txnIndex !== undefined && item.transactionIndex !== undefined) ||
259
+ (item.txnIndex === undefined && item.transactionIndex === undefined)
260
+ ) {
261
+ throw new Error("Either txnIndex or transactionIndex must be defined, but not both.");
262
+ }
263
+
264
+ // For txnRef/transactionHash: throw if both are defined or both are missing.
265
+ if (
266
+ (item.txnRef !== undefined && item.transactionHash !== undefined) ||
267
+ (item.txnRef === undefined && item.transactionHash === undefined)
268
+ ) {
269
+ throw new Error("Either txnRef or transactionHash must be defined, but not both.");
270
+ }
271
+
272
+ // Destructure the fields we don't need anymore
273
+ const { txnIndex, transactionIndex, txnRef, transactionHash, ...rest } = item;
274
+
275
+ // Return a new object with normalized fields.
276
+ // The non-null assertion (!) is safe here because our conditions ensure that one of each pair is defined.
277
+ return {
278
+ ...rest,
279
+ txnIndex: txnIndex ?? transactionIndex!,
280
+ txnRef: txnRef ?? transactionHash!,
281
+ };
282
+ });
283
+ };
284
+
285
+ const convertEmbeddedSortableEventFieldsIntoRequiredFields = <
286
+ T extends {
287
+ txnIndex?: number;
288
+ transactionIndex?: number;
289
+ txnRef?: string;
290
+ transactionHash?: string;
291
+ },
292
+ >(
293
+ data: Record<string, Record<string, T[]>>
294
+ ) => {
295
+ return Object.fromEntries(
296
+ Object.entries(data).map(([chainId, tokenData]) => [
297
+ chainId,
298
+ Object.fromEntries(
299
+ Object.entries(tokenData).map(([token, data]) => [
300
+ token,
301
+ convertSortableEventFieldsIntoRequiredFields(data),
302
+ ])
303
+ ),
304
+ ])
305
+ );
306
+ };
307
+
240
308
  const data = persistedData[0].data;
309
+
310
+ // This section processes and transforms bundle data loaded from Arweave storage into the correct format:
311
+ // 1. Each field (bundleFillsV3, expiredDepositsToRefundV3, etc.) contains nested records keyed by chainId and token
312
+ // 2. The chainId keys are converted from strings to numbers using convertTypedStringRecordIntoNumericRecord
313
+ // 3. For arrays of events (fills, deposits, etc.), the transaction fields are normalized:
314
+ // - txnIndex/transactionIndex -> txnIndex
315
+ // - txnRef/transactionHash -> txnRef
316
+ // This ensures consistent field names across all event objects
317
+ // 4. The data structure maintains all other fields like refunds, totalRefundAmount, and realizedLpFees
241
318
  const bundleData = {
242
- bundleFillsV3: convertTypedStringRecordIntoNumericRecord(data.bundleFillsV3),
243
- expiredDepositsToRefundV3: convertTypedStringRecordIntoNumericRecord(data.expiredDepositsToRefundV3),
244
- bundleDepositsV3: convertTypedStringRecordIntoNumericRecord(data.bundleDepositsV3),
245
- unexecutableSlowFills: convertTypedStringRecordIntoNumericRecord(data.unexecutableSlowFills),
246
- bundleSlowFillsV3: convertTypedStringRecordIntoNumericRecord(data.bundleSlowFillsV3),
319
+ bundleFillsV3: convertTypedStringRecordIntoNumericRecord(
320
+ Object.fromEntries(
321
+ Object.entries(data.bundleFillsV3).map(([chainId, tokenData]) => [
322
+ chainId,
323
+ Object.fromEntries(
324
+ Object.entries(tokenData).map(([token, data]) => [
325
+ token,
326
+ {
327
+ refunds: data.refunds,
328
+ totalRefundAmount: data.totalRefundAmount,
329
+ realizedLpFees: data.realizedLpFees,
330
+ fills: convertSortableEventFieldsIntoRequiredFields(data.fills),
331
+ },
332
+ ])
333
+ ),
334
+ ])
335
+ )
336
+ ),
337
+ expiredDepositsToRefundV3: convertTypedStringRecordIntoNumericRecord(
338
+ convertEmbeddedSortableEventFieldsIntoRequiredFields(data.expiredDepositsToRefundV3)
339
+ ),
340
+ bundleDepositsV3: convertTypedStringRecordIntoNumericRecord(
341
+ convertEmbeddedSortableEventFieldsIntoRequiredFields(data.bundleDepositsV3)
342
+ ),
343
+ unexecutableSlowFills: convertTypedStringRecordIntoNumericRecord(
344
+ convertEmbeddedSortableEventFieldsIntoRequiredFields(data.unexecutableSlowFills)
345
+ ),
346
+ bundleSlowFillsV3: convertTypedStringRecordIntoNumericRecord(
347
+ convertEmbeddedSortableEventFieldsIntoRequiredFields(data.bundleSlowFillsV3)
348
+ ),
247
349
  };
248
350
  this.logger.debug({
249
351
  at: "BundleDataClient#loadPersistedDataFromArweave",
@@ -87,9 +87,7 @@ export async function verifyFillRepayment(
87
87
  if (_repaymentAddressNeedsToBeOverwritten(fill)) {
88
88
  // TODO: Handle case where fill was sent on non-EVM chain, in which case the following call would fail
89
89
  // or return something unexpected. We'd want to return undefined here.
90
-
91
- // @todo: If chainIsEvm:
92
- const fillTransaction = await destinationChainProvider.getTransaction(fill.transactionHash);
90
+ const fillTransaction = await destinationChainProvider.getTransaction(fill.txnRef);
93
91
  const destinationRelayer = fillTransaction?.from;
94
92
  // Repayment chain is still an EVM chain, but the msg.sender is a bytes32 address, so the fill is invalid.
95
93
  if (!isDefined(destinationRelayer) || !isValidEvmAddress(destinationRelayer)) {
@@ -48,11 +48,15 @@ const V3RelayDataSS = {
48
48
  message: string(),
49
49
  };
50
50
 
51
- const SortableEventSS = {
51
+ export const SortableEventSS = {
52
52
  blockNumber: number(),
53
- transactionIndex: number(),
54
53
  logIndex: number(),
55
- transactionHash: string(),
54
+
55
+ txnRef: optional(string()),
56
+ txnIndex: optional(number()),
57
+
58
+ transactionHash: optional(string()),
59
+ transactionIndex: optional(number()),
56
60
  };
57
61
 
58
62
  const V3DepositSS = {
@@ -2,7 +2,7 @@ import assert from "assert";
2
2
  import { Contract, EventFilter } from "ethers";
3
3
  import _ from "lodash";
4
4
  import winston from "winston";
5
- import { DEFAULT_CACHING_SAFE_LAG, DEFAULT_CACHING_TTL, ZERO_ADDRESS } from "../constants";
5
+ import { DEFAULT_CACHING_SAFE_LAG, DEFAULT_CACHING_TTL, TOKEN_SYMBOLS_MAP, ZERO_ADDRESS } from "../constants";
6
6
  import {
7
7
  CachingMechanismInterface,
8
8
  CancelledRootBundle,
@@ -43,8 +43,10 @@ import {
43
43
  toBN,
44
44
  getTokenInfo,
45
45
  getUsdcSymbol,
46
- getL1TokenInfo,
47
46
  compareAddressesSimple,
47
+ chainIsSvm,
48
+ getDeployedAddress,
49
+ SvmAddress,
48
50
  } from "../utils";
49
51
  import { AcrossConfigStoreClient as ConfigStoreClient } from "./AcrossConfigStoreClient/AcrossConfigStoreClient";
50
52
  import { BaseAbstractClient, isUpdateFailureReason, UpdateFailureReason } from "./BaseAbstractClient";
@@ -282,17 +284,6 @@ export class HubPoolClient extends BaseAbstractClient {
282
284
  return tokenInfo;
283
285
  }
284
286
 
285
- /**
286
- * @dev If tokenAddress + chain do not exist in TOKEN_SYMBOLS_MAP then this will throw.
287
- * @dev if the token matched in TOKEN_SYMBOLS_MAP does not have an L1 token address then this will throw.
288
- * @param tokenAddress Token address on `chain`
289
- * @param chain Chain where the `tokenAddress` exists in TOKEN_SYMBOLS_MAP.
290
- * @returns Token info for the given token address on the Hub chain including symbol and decimal and L1 address.
291
- */
292
- getL1TokenInfoForAddress(tokenAddress: string, chain: number): L1Token {
293
- return getL1TokenInfo(tokenAddress, chain);
294
- }
295
-
296
287
  /**
297
288
  * Resolve a given timestamp to a block number on the HubPool chain.
298
289
  * @param timestamp A single timestamp to be resolved to a block number on the HubPool chain.
@@ -512,17 +503,6 @@ export class HubPoolClient extends BaseAbstractClient {
512
503
  return this.getTokenInfoForL1Token(l1TokenCounterpart);
513
504
  }
514
505
 
515
- getTokenInfoForDeposit(deposit: Pick<Deposit, "inputToken" | "originChainId">): L1Token | undefined {
516
- return this.getTokenInfoForL1Token(
517
- this.getL1TokenForL2TokenAtBlock(deposit.inputToken, deposit.originChainId, this.latestBlockSearched)
518
- );
519
- }
520
-
521
- getTokenInfo(chainId: number | string, tokenAddress: string): L1Token | undefined {
522
- const deposit = { originChainId: parseInt(chainId.toString()), inputToken: tokenAddress };
523
- return this.getTokenInfoForDeposit(deposit);
524
- }
525
-
526
506
  areTokensEquivalent(
527
507
  tokenA: string,
528
508
  chainIdA: number,
@@ -904,39 +884,73 @@ export class HubPoolClient extends BaseAbstractClient {
904
884
  if (eventsToQuery.includes("CrossChainContractsSet")) {
905
885
  for (const event of events["CrossChainContractsSet"]) {
906
886
  const args = spreadEventWithBlockNumber(event) as CrossChainContractsSet;
907
- assign(
908
- this.crossChainContracts,
909
- [args.l2ChainId],
910
- [
911
- {
912
- spokePool: args.spokePool,
913
- blockNumber: args.blockNumber,
914
- transactionIndex: args.transactionIndex,
915
- logIndex: args.logIndex,
916
- },
917
- ]
918
- );
887
+ const dataToAdd: CrossChainContractsSet = {
888
+ spokePool: args.spokePool,
889
+ blockNumber: args.blockNumber,
890
+ txnRef: args.txnRef,
891
+ logIndex: args.logIndex,
892
+ txnIndex: args.txnIndex,
893
+ l2ChainId: args.l2ChainId,
894
+ };
895
+ // If the chain is SVM then our `args.spokePool` will be set to the `solanaSpokePool.toAddressUnchecked()` in the
896
+ // hubpool event because our hub deals with `address` types and not byte32. Therefore, we should confirm that the
897
+ // `args.spokePool` is the same as the `solanaSpokePool.toAddressUnchecked()`. We can derive the `solanaSpokePool`
898
+ // address by using the `getDeployedAddress` function.
899
+ if (chainIsSvm(args.l2ChainId)) {
900
+ const solanaSpokePool = getDeployedAddress("SvmSpoke", args.l2ChainId);
901
+ if (!solanaSpokePool) {
902
+ throw new Error(`SVM spoke pool not found for chain ${args.l2ChainId}`);
903
+ }
904
+ const truncatedAddress = SvmAddress.from(solanaSpokePool).toEvmAddress();
905
+ // Verify the event address matches our expected truncated address
906
+ if (args.spokePool.toLowerCase() !== truncatedAddress.toLowerCase()) {
907
+ throw new Error(
908
+ `SVM spoke pool address mismatch for chain ${args.l2ChainId}. ` +
909
+ `Expected ${truncatedAddress}, got ${args.spokePool}`
910
+ );
911
+ }
912
+ // Store the full Solana address
913
+ dataToAdd.spokePool = SvmAddress.from(solanaSpokePool).toBytes32();
914
+ }
915
+ assign(this.crossChainContracts, [args.l2ChainId], [dataToAdd]);
919
916
  }
920
917
  }
921
918
 
922
919
  if (eventsToQuery.includes("SetPoolRebalanceRoute")) {
923
920
  for (const event of events["SetPoolRebalanceRoute"]) {
924
921
  const args = spreadEventWithBlockNumber(event) as SetPoolRebalanceRoot;
922
+
923
+ // If the destination chain is SVM, then we need to convert the destination token to the Solana address.
924
+ // This is because the HubPool contract only holds a truncated address for the USDC token and currently
925
+ // only supports USDC as a destination token for Solana.
926
+ let destinationToken = args.destinationToken;
927
+ if (chainIsSvm(args.destinationChainId)) {
928
+ const usdcTokenSol = TOKEN_SYMBOLS_MAP.USDC.addresses[args.destinationChainId];
929
+ const truncatedAddress = SvmAddress.from(usdcTokenSol).toEvmAddress();
930
+ if (destinationToken.toLowerCase() !== truncatedAddress.toLowerCase()) {
931
+ throw new Error(
932
+ `SVM USDC address mismatch for chain ${args.destinationChainId}. ` +
933
+ `Expected ${truncatedAddress}, got ${destinationToken}`
934
+ );
935
+ }
936
+ destinationToken = SvmAddress.from(usdcTokenSol).toBytes32();
937
+ }
938
+
925
939
  // If the destination token is set to the zero address in an event, then this means Across should no longer
926
940
  // rebalance to this chain.
927
- if (args.destinationToken !== ZERO_ADDRESS) {
928
- assign(this.l1TokensToDestinationTokens, [args.l1Token, args.destinationChainId], args.destinationToken);
941
+ if (destinationToken !== ZERO_ADDRESS) {
942
+ assign(this.l1TokensToDestinationTokens, [args.l1Token, args.destinationChainId], destinationToken);
929
943
  assign(
930
944
  this.l1TokensToDestinationTokensWithBlock,
931
945
  [args.l1Token, args.destinationChainId],
932
946
  [
933
947
  {
934
948
  l1Token: args.l1Token,
935
- l2Token: args.destinationToken,
949
+ l2Token: destinationToken,
936
950
  blockNumber: args.blockNumber,
937
- transactionIndex: args.transactionIndex,
951
+ txnIndex: args.txnIndex,
938
952
  logIndex: args.logIndex,
939
- transactionHash: args.transactionHash,
953
+ txnRef: args.txnRef,
940
954
  },
941
955
  ]
942
956
  );
@@ -982,12 +996,7 @@ export class HubPoolClient extends BaseAbstractClient {
982
996
  this.proposedRootBundles.push(
983
997
  ...events["ProposeRootBundle"]
984
998
  .filter((event) => !this.configOverride.ignoredHubProposedBundles.includes(event.blockNumber))
985
- .map((event) => {
986
- return {
987
- ...spreadEventWithBlockNumber(event),
988
- transactionHash: event.transactionHash,
989
- } as ProposedRootBundle;
990
- })
999
+ .map((event) => spreadEventWithBlockNumber(event) as ProposedRootBundle)
991
1000
  );
992
1001
  }
993
1002
 
@@ -19,6 +19,7 @@ import {
19
19
  } from "../../utils";
20
20
  import {
21
21
  EventSearchConfig,
22
+ logToSortableEvent,
22
23
  paginatedEventQuery,
23
24
  sortEventsAscendingInPlace,
24
25
  spreadEventWithBlockNumber,
@@ -127,7 +128,7 @@ export class EVMSpokePoolClient extends SpokePoolClient {
127
128
  }
128
129
 
129
130
  // Sort all events to ensure they are stored in a consistent order.
130
- events.forEach((events) => sortEventsAscendingInPlace(events));
131
+ events.forEach((events) => sortEventsAscendingInPlace(events.map(logToSortableEvent)));
131
132
 
132
133
  return {
133
134
  success: true,
@@ -401,7 +401,7 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
401
401
 
402
402
  // Log any invalid deposits with same deposit id but different params.
403
403
  const invalidFillsForDeposit = invalidFills.filter((x) => {
404
- const txnUid = `${x.transactionHash}:${x.logIndex}`;
404
+ const txnUid = `${x.txnRef}:${x.logIndex}`;
405
405
  // if txnUid doesn't exist in the invalidFills set, add it now, but log the corresponding fill.
406
406
  const newInvalidFill = x.depositId.eq(deposit.depositId) && !this.invalidFills.has(txnUid);
407
407
  if (newInvalidFill) {
@@ -2,7 +2,14 @@ import assert from "assert";
2
2
  import winston from "winston";
3
3
  import { Contract, ethers } from "ethers";
4
4
  import { Log } from "../../interfaces";
5
- import { getCurrentTime, EventSearchConfig, MakeOptional, isDefined, utf8ToHex } from "../../utils";
5
+ import {
6
+ getCurrentTime,
7
+ EventSearchConfig,
8
+ MakeOptional,
9
+ isDefined,
10
+ utf8ToHex,
11
+ spreadEventWithBlockNumber,
12
+ } from "../../utils";
6
13
  import {
7
14
  AcrossConfigStoreClient,
8
15
  ConfigStoreUpdate,
@@ -92,9 +99,9 @@ export class MockConfigStoreClient extends AcrossConfigStoreClient {
92
99
  chainId: this.chainId as number,
93
100
  searchEndBlock: this.eventSearchConfig.toBlock || latestBlockSearched,
94
101
  events: {
95
- updatedGlobalConfigEvents: events["UpdatedGlobalConfig"],
102
+ updatedGlobalConfigEvents: events["UpdatedGlobalConfig"].map(spreadEventWithBlockNumber),
96
103
  globalConfigUpdateTimes,
97
- updatedTokenConfigEvents: events["UpdatedTokenConfig"],
104
+ updatedTokenConfigEvents: events["UpdatedTokenConfig"].map(spreadEventWithBlockNumber),
98
105
  },
99
106
  });
100
107
  }
@@ -24,7 +24,7 @@ export class MockHubPoolClient extends HubPoolClient {
24
24
 
25
25
  private l1TokensMock: L1Token[] = []; // L1Tokens and their associated info.
26
26
  private tokenInfoToReturn: L1Token = { address: "", decimals: 0, symbol: "" };
27
-
27
+
28
28
  private spokePoolTokens: { [l1Token: string]: { [chainId: number]: string } } = {};
29
29
 
30
30
  private eventManager: EventManager;
@@ -91,7 +91,7 @@ export class MockHubPoolClient extends HubPoolClient {
91
91
  return this.l1TokensMock;
92
92
  }
93
93
 
94
- getTokenInfoForDeposit() {
94
+ getTokenInfoForAddress() {
95
95
  return this.tokenInfoToReturn;
96
96
  }
97
97
 
@@ -178,6 +178,30 @@ export class MockHubPoolClient extends HubPoolClient {
178
178
  RootBundleExecuted: "uint256,uint256,uint256,address[],uint256[],int256[],int256[],address",
179
179
  };
180
180
 
181
+ setCrossChainContractsEvent(
182
+ l2ChainId: number,
183
+ adapter: string,
184
+ spokePool: string,
185
+ overrides: EventOverrides = {}
186
+ ): Log {
187
+ const event = "CrossChainContractsSet";
188
+
189
+ const topics: string[] = [];
190
+ const args = {
191
+ l2ChainId,
192
+ adapter,
193
+ spokePool,
194
+ };
195
+
196
+ return this.eventManager.generateEvent({
197
+ event,
198
+ address: this.hubPool.address,
199
+ topics: topics.map((topic) => topic.toString()),
200
+ args,
201
+ blockNumber: overrides.blockNumber,
202
+ });
203
+ }
204
+
181
205
  setPoolRebalanceRoute(
182
206
  destinationChainId: number,
183
207
  l1Token: string,
@@ -129,7 +129,7 @@ export class MockSpokePoolClient extends EVMSpokePoolClient {
129
129
  }
130
130
 
131
131
  protected _deposit(event: string, deposit: Omit<Deposit, "messageHash"> & Partial<SortableEvent>): Log {
132
- const { blockNumber, transactionIndex } = deposit;
132
+ const { blockNumber, txnIndex } = deposit;
133
133
  let { depositId, destinationChainId, inputAmount, outputAmount } = deposit;
134
134
  depositId ??= this.numberOfDeposits;
135
135
  this.numberOfDeposits = depositId.add(bnOne);
@@ -171,7 +171,7 @@ export class MockSpokePoolClient extends EVMSpokePoolClient {
171
171
  topics: topics.map((topic) => topic.toString()),
172
172
  args,
173
173
  blockNumber,
174
- transactionIndex,
174
+ transactionIndex: txnIndex,
175
175
  });
176
176
  }
177
177
 
@@ -187,7 +187,7 @@ export class MockSpokePoolClient extends EVMSpokePoolClient {
187
187
  event: string,
188
188
  fill: Omit<Fill, "messageHash"> & { message: string } & Partial<SortableEvent>
189
189
  ): Log {
190
- const { blockNumber, transactionIndex } = fill;
190
+ const { blockNumber, txnIndex } = fill;
191
191
  let { originChainId, depositId, inputAmount, outputAmount, fillDeadline } = fill;
192
192
  originChainId ??= random(1, 42161, false);
193
193
  depositId ??= BigNumber.from(random(1, 100_000, false));
@@ -260,7 +260,7 @@ export class MockSpokePoolClient extends EVMSpokePoolClient {
260
260
  topics: topics.map((topic) => topic.toString()),
261
261
  args,
262
262
  blockNumber,
263
- transactionIndex,
263
+ transactionIndex: txnIndex,
264
264
  });
265
265
  }
266
266
 
@@ -335,7 +335,7 @@ export class MockSpokePoolClient extends EVMSpokePoolClient {
335
335
  exclusiveRelayer: addressModifier(args.exclusiveRelayer ?? ZERO_ADDRESS),
336
336
  },
337
337
  blockNumber: request.blockNumber,
338
- transactionIndex: request.transactionIndex,
338
+ transactionIndex: request.txnIndex,
339
339
  });
340
340
  }
341
341
 
@@ -9,9 +9,9 @@ export type Log = _Log & {
9
9
 
10
10
  export interface SortableEvent {
11
11
  blockNumber: number;
12
- transactionIndex: number;
12
+ txnIndex: number;
13
13
  logIndex: number;
14
- transactionHash: string;
14
+ txnRef: string;
15
15
  }
16
16
 
17
17
  export interface BigNumberForToken {
@@ -252,14 +252,4 @@ export class QueryBase implements QueryInterface {
252
252
  );
253
253
  return price;
254
254
  }
255
-
256
- /**
257
- * Resolves the number of decimal places a token can have
258
- * @param tokenSymbol A valid Across-Enabled Token ID
259
- * @returns The number of decimals of precision for the corresponding tokenSymbol
260
- */
261
- getTokenDecimals(tokenSymbol: string): number {
262
- if (!this.symbolMapping[tokenSymbol]) throw new Error(`${tokenSymbol} does not exist in mapping`);
263
- return this.symbolMapping[tokenSymbol].decimals;
264
- }
265
255
  }
@@ -34,7 +34,6 @@ export interface QueryInterface {
34
34
  }>
35
35
  ) => Promise<TransactionCostEstimate>;
36
36
  getTokenPrice: (tokenSymbol: string) => Promise<number>;
37
- getTokenDecimals: (tokenSymbol: string) => number;
38
37
  }
39
38
 
40
39
  export const expectedCapitalCostsKeys = ["lowerBound", "upperBound", "cutoff", "decimals"];
@@ -241,6 +241,10 @@ export class SvmAddress extends Address {
241
241
  return this.toBase58();
242
242
  }
243
243
 
244
+ override toEvmAddress(): string {
245
+ return toAddress(`0x${this.toBytes32().slice(-40)}`);
246
+ }
247
+
244
248
  // Constructs a new SvmAddress type.
245
249
  static from(bs58Address: string): SvmAddress {
246
250
  return new this(bs58.decode(bs58Address));