@across-protocol/sdk 4.2.5 → 4.2.6-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 (79) hide show
  1. package/dist/cjs/arch/evm/types.d.ts +5 -0
  2. package/dist/cjs/arch/evm/types.js +3 -0
  3. package/dist/cjs/arch/evm/types.js.map +1 -0
  4. package/dist/cjs/arch/svm/SpokeUtils.d.ts +29 -1
  5. package/dist/cjs/arch/svm/SpokeUtils.js +105 -2
  6. package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
  7. package/dist/cjs/arch/svm/eventsClient.d.ts +5 -1
  8. package/dist/cjs/arch/svm/eventsClient.js.map +1 -1
  9. package/dist/cjs/arch/svm/types.d.ts +3 -4
  10. package/dist/cjs/arch/svm/types.js +0 -1
  11. package/dist/cjs/arch/svm/types.js.map +1 -1
  12. package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.d.ts +1 -1
  13. package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.js +1 -5
  14. package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.js.map +1 -1
  15. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.d.ts +3 -3
  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/MockSvmCpiEventsClient.d.ts +1 -1
  19. package/dist/cjs/gasPriceOracle/oracle.d.ts +2 -1
  20. package/dist/cjs/gasPriceOracle/oracle.js.map +1 -1
  21. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.d.ts +3 -5
  22. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
  23. package/dist/cjs/utils/TypeGuards.d.ts +2 -2
  24. package/dist/cjs/utils/TypeGuards.js +1 -2
  25. package/dist/cjs/utils/TypeGuards.js.map +1 -1
  26. package/dist/esm/arch/evm/types.d.ts +5 -0
  27. package/dist/esm/arch/evm/types.js +2 -0
  28. package/dist/esm/arch/evm/types.js.map +1 -0
  29. package/dist/esm/arch/svm/SpokeUtils.d.ts +38 -1
  30. package/dist/esm/arch/svm/SpokeUtils.js +112 -3
  31. package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
  32. package/dist/esm/arch/svm/eventsClient.d.ts +5 -1
  33. package/dist/esm/arch/svm/eventsClient.js.map +1 -1
  34. package/dist/esm/arch/svm/types.d.ts +3 -4
  35. package/dist/esm/arch/svm/types.js +0 -1
  36. package/dist/esm/arch/svm/types.js.map +1 -1
  37. package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.d.ts +2 -2
  38. package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.js +2 -9
  39. package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.js.map +1 -1
  40. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.d.ts +3 -3
  41. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +1 -1
  42. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  43. package/dist/esm/clients/mocks/MockSvmCpiEventsClient.d.ts +1 -1
  44. package/dist/esm/gasPriceOracle/oracle.d.ts +2 -1
  45. package/dist/esm/gasPriceOracle/oracle.js.map +1 -1
  46. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.d.ts +3 -5
  47. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
  48. package/dist/esm/utils/TypeGuards.d.ts +2 -2
  49. package/dist/esm/utils/TypeGuards.js +2 -2
  50. package/dist/esm/utils/TypeGuards.js.map +1 -1
  51. package/dist/types/arch/evm/types.d.ts +6 -0
  52. package/dist/types/arch/evm/types.d.ts.map +1 -0
  53. package/dist/types/arch/svm/SpokeUtils.d.ts +38 -1
  54. package/dist/types/arch/svm/SpokeUtils.d.ts.map +1 -1
  55. package/dist/types/arch/svm/eventsClient.d.ts +5 -1
  56. package/dist/types/arch/svm/eventsClient.d.ts.map +1 -1
  57. package/dist/types/arch/svm/types.d.ts +3 -4
  58. package/dist/types/arch/svm/types.d.ts.map +1 -1
  59. package/dist/types/clients/SpokePoolClient/SVMSpokePoolClient.d.ts +2 -2
  60. package/dist/types/clients/SpokePoolClient/SVMSpokePoolClient.d.ts.map +1 -1
  61. package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts +3 -3
  62. package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts.map +1 -1
  63. package/dist/types/clients/mocks/MockSvmCpiEventsClient.d.ts +1 -1
  64. package/dist/types/gasPriceOracle/oracle.d.ts +2 -1
  65. package/dist/types/gasPriceOracle/oracle.d.ts.map +1 -1
  66. package/dist/types/relayFeeCalculator/chain-queries/baseQuery.d.ts +3 -5
  67. package/dist/types/relayFeeCalculator/chain-queries/baseQuery.d.ts.map +1 -1
  68. package/dist/types/utils/TypeGuards.d.ts +2 -2
  69. package/dist/types/utils/TypeGuards.d.ts.map +1 -1
  70. package/package.json +3 -3
  71. package/src/arch/evm/types.ts +7 -0
  72. package/src/arch/svm/SpokeUtils.ts +139 -5
  73. package/src/arch/svm/eventsClient.ts +1 -1
  74. package/src/arch/svm/types.ts +3 -4
  75. package/src/clients/SpokePoolClient/SVMSpokePoolClient.ts +2 -11
  76. package/src/clients/SpokePoolClient/SpokePoolClient.ts +1 -1
  77. package/src/gasPriceOracle/oracle.ts +3 -2
  78. package/src/relayFeeCalculator/chain-queries/baseQuery.ts +3 -3
  79. package/src/utils/TypeGuards.ts +4 -3
@@ -26,16 +26,16 @@ import { CHAIN_IDs } from "../../constants";
26
26
  import { Deposit, DepositWithBlock, FillStatus, FillWithBlock, RelayData } from "../../interfaces";
27
27
  import {
28
28
  BigNumber,
29
- isUnsafeDepositId,
30
29
  SvmAddress,
30
+ chainIsSvm,
31
+ chunk,
31
32
  getTokenInfo,
32
33
  isDefined,
33
- toAddressType,
34
+ isUnsafeDepositId,
34
35
  keccak256,
35
- chainIsSvm,
36
- chunk,
36
+ toAddressType,
37
37
  } from "../../utils";
38
- import { getStatePda, SvmCpiEventsClient, getFillStatusPda, unwrapEventData, getEventAuthority } from "./";
38
+ import { SvmCpiEventsClient, getEventAuthority, getFillStatusPda, getStatePda, unwrapEventData } from "./";
39
39
  import { SVMEventNames, SVMProvider } from "./types";
40
40
 
41
41
  /**
@@ -373,9 +373,17 @@ export async function fillRelayInstruction(
373
373
  const shortenedBuffer = new Uint8Array(Buffer.from(deposit.depositId.toHexString().slice(2), "hex"));
374
374
  depositIdBuffer.set(shortenedBuffer, 32 - shortenedBuffer.length);
375
375
 
376
+ const delegatePda = await getFillRelayDelegatePda(
377
+ relayDataHash,
378
+ BigInt(repaymentChainId),
379
+ relayerAddress.toV2Address(),
380
+ spokePool.toV2Address()
381
+ );
382
+
376
383
  return SvmSpokeClient.getFillRelayInstruction({
377
384
  signer: relayer,
378
385
  state: statePda,
386
+ delegate: SvmAddress.from(delegatePda.toString()).toV2Address(),
379
387
  mint: outputToken.toV2Address(),
380
388
  relayerTokenAccount: relayerTokenAccount,
381
389
  recipientTokenAccount: recipientTokenAccount,
@@ -579,3 +587,129 @@ async function fetchBatchFillStatusFromPdaAccounts(
579
587
 
580
588
  return fillStatuses;
581
589
  }
590
+
591
+ /**
592
+ * Returns the delegate PDA for deposit.
593
+ */
594
+ export async function getDepositDelegatePda(
595
+ depositData: {
596
+ depositor: Address<string>;
597
+ recipient: Address<string>;
598
+ inputToken: Address<string>;
599
+ outputToken: Address<string>;
600
+ inputAmount: bigint;
601
+ outputAmount: bigint;
602
+ destinationChainId: bigint;
603
+ exclusiveRelayer: Address<string>;
604
+ quoteTimestamp: bigint;
605
+ fillDeadline: bigint;
606
+ exclusivityParameter: bigint;
607
+ message: Uint8Array;
608
+ },
609
+ programId: Address<string>
610
+ ): Promise<Address<string>> {
611
+ const addrEnc = getAddressEncoder();
612
+ const u64 = getU64Encoder();
613
+ const u32 = getU32Encoder();
614
+
615
+ const parts: Uint8Array[] = [
616
+ Uint8Array.from(addrEnc.encode(depositData.depositor)),
617
+ Uint8Array.from(addrEnc.encode(depositData.recipient)),
618
+ Uint8Array.from(addrEnc.encode(depositData.inputToken)),
619
+ Uint8Array.from(addrEnc.encode(depositData.outputToken)),
620
+ Uint8Array.from(u64.encode(depositData.inputAmount)),
621
+ Uint8Array.from(u64.encode(depositData.outputAmount)),
622
+ Uint8Array.from(u64.encode(depositData.destinationChainId)),
623
+ Uint8Array.from(addrEnc.encode(depositData.exclusiveRelayer)),
624
+ Uint8Array.from(u32.encode(depositData.quoteTimestamp)),
625
+ Uint8Array.from(u32.encode(depositData.fillDeadline)),
626
+ Uint8Array.from(u32.encode(depositData.exclusivityParameter)),
627
+ Uint8Array.from(u32.encode(BigInt(depositData.message.length))),
628
+ depositData.message,
629
+ ];
630
+
631
+ const seedHash = Buffer.from(keccak256(Buffer.concat(parts)).slice(2), "hex");
632
+
633
+ const [pda] = await getProgramDerivedAddress({
634
+ programAddress: programId,
635
+ seeds: [Buffer.from("delegate"), seedHash],
636
+ });
637
+
638
+ return pda;
639
+ }
640
+
641
+ /**
642
+ * Returns the delegate PDA for depositNow.
643
+ */
644
+ export async function getDepositNowDelegatePda(
645
+ depositData: {
646
+ depositor: Address<string>;
647
+ recipient: Address<string>;
648
+ inputToken: Address<string>;
649
+ outputToken: Address<string>;
650
+ inputAmount: bigint;
651
+ outputAmount: bigint;
652
+ destinationChainId: bigint;
653
+ exclusiveRelayer: Address<string>;
654
+ fillDeadlineOffset: bigint;
655
+ exclusivityPeriod: bigint;
656
+ message: Uint8Array;
657
+ },
658
+ programId: Address<string>
659
+ ): Promise<Address<string>> {
660
+ const addrEnc = getAddressEncoder();
661
+ const u64 = getU64Encoder();
662
+ const u32 = getU32Encoder();
663
+
664
+ const parts: Uint8Array[] = [
665
+ Uint8Array.from(addrEnc.encode(depositData.depositor)),
666
+ Uint8Array.from(addrEnc.encode(depositData.recipient)),
667
+ Uint8Array.from(addrEnc.encode(depositData.inputToken)),
668
+ Uint8Array.from(addrEnc.encode(depositData.outputToken)),
669
+ Uint8Array.from(u64.encode(depositData.inputAmount)),
670
+ Uint8Array.from(u64.encode(depositData.outputAmount)),
671
+ Uint8Array.from(u64.encode(depositData.destinationChainId)),
672
+ Uint8Array.from(addrEnc.encode(depositData.exclusiveRelayer)),
673
+ Uint8Array.from(u32.encode(depositData.fillDeadlineOffset)),
674
+ Uint8Array.from(u32.encode(depositData.exclusivityPeriod)),
675
+ Uint8Array.from(u32.encode(BigInt(depositData.message.length))),
676
+ depositData.message,
677
+ ];
678
+
679
+ const seedHash = Buffer.from(keccak256(Buffer.concat(parts)).slice(2), "hex");
680
+
681
+ const [pda] = await getProgramDerivedAddress({
682
+ programAddress: programId,
683
+ seeds: [Buffer.from("delegate"), seedHash],
684
+ });
685
+
686
+ return pda;
687
+ }
688
+
689
+ /**
690
+ * Returns the fill-delegate PDA for fillRelay.
691
+ */
692
+ export async function getFillRelayDelegatePda(
693
+ relayHash: Uint8Array,
694
+ repaymentChainId: bigint,
695
+ repaymentAddress: Address<string>,
696
+ programId: Address<string>
697
+ ): Promise<Address<string>> {
698
+ const addrEnc = getAddressEncoder();
699
+ const u64 = getU64Encoder();
700
+
701
+ const parts: Uint8Array[] = [
702
+ relayHash,
703
+ Uint8Array.from(u64.encode(repaymentChainId)),
704
+ Uint8Array.from(addrEnc.encode(repaymentAddress)),
705
+ ];
706
+
707
+ const seedHash = Buffer.from(keccak256(Buffer.concat(parts)).slice(2), "hex");
708
+
709
+ const [pda] = await getProgramDerivedAddress({
710
+ programAddress: programId,
711
+ seeds: [Buffer.from("delegate"), seedHash],
712
+ });
713
+
714
+ return pda;
715
+ }
@@ -177,7 +177,7 @@ export class SvmCpiEventsClient {
177
177
  * @param commitment - Commitment level.
178
178
  * @returns A promise that resolves to an array of events.
179
179
  */
180
- private async readEventsFromSignature(txSignature: Signature, commitment: Commitment = "confirmed") {
180
+ async readEventsFromSignature(txSignature: Signature, commitment: Commitment = "confirmed") {
181
181
  const txResult = await this.rpc
182
182
  .getTransaction(txSignature, { commitment, maxSupportedTransactionVersion: 0 })
183
183
  .send();
@@ -19,7 +19,6 @@ export type EventData =
19
19
  | SvmSpokeClient.PausedDeposits
20
20
  | SvmSpokeClient.PausedFills
21
21
  | SvmSpokeClient.SetXDomainAdmin
22
- | SvmSpokeClient.EnabledDepositRoute
23
22
  | SvmSpokeClient.FilledRelay
24
23
  | SvmSpokeClient.FundsDeposited
25
24
  | SvmSpokeClient.EmergencyDeletedRootBundle
@@ -30,7 +29,6 @@ export type EventData =
30
29
  export enum SVMEventNames {
31
30
  FilledRelay = "FilledRelay",
32
31
  FundsDeposited = "FundsDeposited",
33
- EnabledDepositRoute = "EnabledDepositRoute",
34
32
  RelayedRootBundle = "RelayedRootBundle",
35
33
  ExecutedRelayerRefundRoot = "ExecutedRelayerRefundRoot",
36
34
  BridgedToHubPool = "BridgedToHubPool",
@@ -56,9 +54,10 @@ export type EventWithData = {
56
54
  program: Address;
57
55
  };
58
56
 
57
+ export type SVMProvider = Rpc<SolanaRpcApiFromTransport<RpcTransport>>;
58
+
59
59
  // Typed aggregate of JSON‑RPC and subscription clients.
60
60
  export type RpcClient = {
61
- rpc: Rpc<SolanaRpcApiFromTransport<RpcTransport>>;
61
+ rpc: SVMProvider;
62
62
  rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi & SlotNotificationsApi>;
63
63
  };
64
- export type SVMProvider = Rpc<SolanaRpcApiFromTransport<RpcTransport>>;
@@ -32,9 +32,9 @@ import { knownEventNames, SpokePoolClient, SpokePoolUpdate } from "./SpokePoolCl
32
32
  */
33
33
  export class SVMSpokePoolClient extends SpokePoolClient {
34
34
  /**
35
- * Protected constructor. Use the async create() method to instantiate.
35
+ * Note: Strongly prefer to use the async create() method to instantiate.
36
36
  */
37
- protected constructor(
37
+ constructor(
38
38
  logger: winston.Logger,
39
39
  hubPoolClient: HubPoolClient | null,
40
40
  chainId: number,
@@ -118,8 +118,6 @@ export class SVMSpokePoolClient extends SpokePoolClient {
118
118
  return { success: false, reason };
119
119
  }
120
120
 
121
- const deploymentSlot = BigInt(this.deploymentBlock);
122
-
123
121
  const eventSearchConfigs = eventsToQuery.map((eventName) => {
124
122
  if (!this._queryableEventNames().includes(eventName)) {
125
123
  throw new Error(`SpokePoolClient: Cannot query unrecognised SpokePool event name: ${eventName}`);
@@ -127,13 +125,6 @@ export class SVMSpokePoolClient extends SpokePoolClient {
127
125
 
128
126
  const _searchConfig = { ...searchConfig }; // shallow copy
129
127
 
130
- // By default, an event's query range is controlled by the `eventSearchConfig` passed in during instantiation.
131
- // However, certain events have special overriding requirements to their search ranges:
132
- // - EnabledDepositRoute: The full history is always required, so override the requested fromBlock.
133
- if (eventName === "EnabledDepositRoute" && !this.isUpdated) {
134
- _searchConfig.from = Number(deploymentSlot);
135
- }
136
-
137
128
  return _searchConfig as EventSearchConfig;
138
129
  });
139
130
 
@@ -76,7 +76,6 @@ export const knownEventNames = [
76
76
  */
77
77
  export abstract class SpokePoolClient extends BaseAbstractClient {
78
78
  protected currentTime = 0;
79
- protected depositHashes: { [depositHash: string]: DepositWithBlock } = {};
80
79
  protected duplicateDepositHashes: { [depositHash: string]: DepositWithBlock[] } = {};
81
80
  protected depositHashesToFills: { [depositHash: string]: FillWithBlock[] } = {};
82
81
  protected speedUps: { [depositorAddress: string]: { [depositId: string]: SpeedUpWithBlock[] } } = {};
@@ -87,6 +86,7 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
87
86
  protected relayerRefundExecutions: RelayerRefundExecutionWithBlock[] = [];
88
87
  protected configStoreClient: AcrossConfigStoreClient | undefined;
89
88
  protected invalidFills: Set<string> = new Set();
89
+ public readonly depositHashes: { [depositHash: string]: DepositWithBlock } = {};
90
90
  public spokePoolAddress: Address | undefined;
91
91
  public fills: { [OriginChainId: number]: FillWithBlock[] } = {};
92
92
 
@@ -11,6 +11,7 @@ import * as ethereum from "./adapters/ethereum";
11
11
  import * as polygon from "./adapters/polygon";
12
12
  import * as lineaViem from "./adapters/linea-viem";
13
13
  import * as solana from "./adapters/solana";
14
+ import { EvmProvider } from "../arch/evm/types";
14
15
 
15
16
  export interface GasPriceEstimateOptions {
16
17
  // baseFeeMultiplier Multiplier applied to base fee for EIP1559 gas prices (or total fee for legacy).
@@ -36,7 +37,7 @@ const VIEM_CHAINS = [CHAIN_IDs.LINEA];
36
37
 
37
38
  // Overload For EVM providers
38
39
  export async function getGasPriceEstimate(
39
- provider: providers.Provider,
40
+ provider: EvmProvider,
40
41
  opts?: Partial<GasPriceEstimateOptions>
41
42
  ): Promise<EvmGasPriceEstimate>;
42
43
 
@@ -53,7 +54,7 @@ export async function getGasPriceEstimate(
53
54
  * @returns An object of type GasPriceEstimate.
54
55
  */
55
56
  export async function getGasPriceEstimate(
56
- provider: providers.Provider | SolanaProvider,
57
+ provider: EvmProvider | SolanaProvider,
57
58
  opts: Partial<GasPriceEstimateOptions> = {}
58
59
  ): Promise<GasPriceEstimate> {
59
60
  const baseFeeMultiplier = opts.baseFeeMultiplier ?? toBNWei("1");
@@ -20,8 +20,8 @@ import assert from "assert";
20
20
  import { Logger, QueryInterface, getDefaultSimulatedRelayerAddress } from "../relayFeeCalculator";
21
21
  import { Transport } from "viem";
22
22
  import { getGasPriceEstimate, EvmGasPriceEstimate } from "../../gasPriceOracle";
23
- type Provider = providers.Provider;
24
- type OptimismProvider = L2Provider<Provider>;
23
+ import { EvmProvider } from "../../arch/evm/types";
24
+
25
25
  export type SymbolMappingType = Record<
26
26
  string,
27
27
  {
@@ -48,7 +48,7 @@ export class QueryBase implements QueryInterface {
48
48
  * @param coingeckoBaseCurrency The basis currency that CoinGecko will use to resolve pricing
49
49
  */
50
50
  constructor(
51
- readonly provider: Provider | OptimismProvider,
51
+ readonly provider: EvmProvider,
52
52
  readonly symbolMapping: SymbolMappingType,
53
53
  readonly spokePoolAddress: string,
54
54
  readonly simulatedRelayerAddress: string,
@@ -1,5 +1,5 @@
1
- import { providers } from "ethers";
2
1
  import { SVMProvider } from "../arch/svm/types";
2
+ import { EvmProvider } from "../arch/evm/types";
3
3
 
4
4
  export function isPromiseFulfilled<T>(
5
5
  promiseSettledResult: PromiseSettledResult<T>
@@ -17,6 +17,7 @@ export function isDefined<T>(input: T | null | undefined): input is T {
17
17
  return input !== null && input !== undefined;
18
18
  }
19
19
 
20
- export function isEvmProvider(provider: providers.Provider | SVMProvider): provider is providers.Provider {
21
- return provider instanceof providers.Provider;
20
+ export function isEvmProvider(provider: EvmProvider | SVMProvider): provider is EvmProvider {
21
+ // Check that the provider doesn't have SVM-specific methods
22
+ return typeof provider === "object" && provider !== null && !("getSlot" in provider);
22
23
  }