@across-protocol/sdk 4.2.9-alpha.0 → 4.2.9-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 (193) hide show
  1. package/dist/cjs/arch/evm/SpokeUtils.d.ts +2 -2
  2. package/dist/cjs/arch/evm/SpokeUtils.js +3 -18
  3. package/dist/cjs/arch/evm/SpokeUtils.js.map +1 -1
  4. package/dist/cjs/arch/svm/SpokeUtils.d.ts +16 -1
  5. package/dist/cjs/arch/svm/SpokeUtils.js +135 -34
  6. package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
  7. package/dist/cjs/arch/svm/utils.d.ts +5 -1
  8. package/dist/cjs/arch/svm/utils.js +26 -16
  9. package/dist/cjs/arch/svm/utils.js.map +1 -1
  10. package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts +3 -3
  11. package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +2 -4
  12. package/dist/cjs/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
  13. package/dist/cjs/clients/BundleDataClient/BundleDataClient.d.ts +2 -2
  14. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js +53 -57
  15. package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  16. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js +13 -13
  17. package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
  18. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.d.ts +1 -2
  19. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +2 -3
  20. package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  21. package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js +3 -3
  22. package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
  23. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.d.ts +63 -63
  24. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js +8 -11
  25. package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  26. package/dist/cjs/clients/HubPoolClient.d.ts +20 -20
  27. package/dist/cjs/clients/HubPoolClient.js +57 -78
  28. package/dist/cjs/clients/HubPoolClient.js.map +1 -1
  29. package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js +2 -2
  30. package/dist/cjs/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
  31. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.d.ts +3 -5
  32. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js +29 -35
  33. package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  34. package/dist/cjs/clients/mocks/MockHubPoolClient.d.ts +9 -9
  35. package/dist/cjs/clients/mocks/MockHubPoolClient.js +9 -15
  36. package/dist/cjs/clients/mocks/MockHubPoolClient.js.map +1 -1
  37. package/dist/cjs/clients/mocks/MockSpokePoolClient.d.ts +13 -9
  38. package/dist/cjs/clients/mocks/MockSpokePoolClient.js +56 -40
  39. package/dist/cjs/clients/mocks/MockSpokePoolClient.js.map +1 -1
  40. package/dist/cjs/clients/mocks/MockSvmSpokePoolClient.d.ts +2 -2
  41. package/dist/cjs/clients/mocks/MockSvmSpokePoolClient.js +2 -2
  42. package/dist/cjs/clients/mocks/MockSvmSpokePoolClient.js.map +1 -1
  43. package/dist/cjs/interfaces/HubPool.d.ts +13 -18
  44. package/dist/cjs/interfaces/SpokePool.d.ts +16 -14
  45. package/dist/cjs/interfaces/SpokePool.js.map +1 -1
  46. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.d.ts +6 -6
  47. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js +7 -7
  48. package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
  49. package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.d.ts +7 -8
  50. package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.js +73 -64
  51. package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.js.map +1 -1
  52. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +6 -6
  53. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js +7 -7
  54. package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
  55. package/dist/cjs/utils/AddressUtils.d.ts +4 -7
  56. package/dist/cjs/utils/AddressUtils.js +8 -21
  57. package/dist/cjs/utils/AddressUtils.js.map +1 -1
  58. package/dist/cjs/utils/SpokeUtils.d.ts +3 -3
  59. package/dist/cjs/utils/SpokeUtils.js +22 -4
  60. package/dist/cjs/utils/SpokeUtils.js.map +1 -1
  61. package/dist/cjs/utils/TokenUtils.d.ts +4 -4
  62. package/dist/cjs/utils/TokenUtils.js +3 -3
  63. package/dist/cjs/utils/TokenUtils.js.map +1 -1
  64. package/dist/esm/arch/evm/SpokeUtils.d.ts +2 -2
  65. package/dist/esm/arch/evm/SpokeUtils.js +4 -19
  66. package/dist/esm/arch/evm/SpokeUtils.js.map +1 -1
  67. package/dist/esm/arch/svm/SpokeUtils.d.ts +46 -6
  68. package/dist/esm/arch/svm/SpokeUtils.js +164 -43
  69. package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
  70. package/dist/esm/arch/svm/utils.d.ts +11 -1
  71. package/dist/esm/arch/svm/utils.js +31 -16
  72. package/dist/esm/arch/svm/utils.js.map +1 -1
  73. package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts +3 -3
  74. package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js +2 -4
  75. package/dist/esm/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.js.map +1 -1
  76. package/dist/esm/clients/BundleDataClient/BundleDataClient.d.ts +2 -2
  77. package/dist/esm/clients/BundleDataClient/BundleDataClient.js +54 -58
  78. package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
  79. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js +14 -14
  80. package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
  81. package/dist/esm/clients/BundleDataClient/utils/FillUtils.d.ts +1 -2
  82. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +3 -4
  83. package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
  84. package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js +4 -4
  85. package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
  86. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.d.ts +63 -63
  87. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js +9 -12
  88. package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.js.map +1 -1
  89. package/dist/esm/clients/HubPoolClient.d.ts +21 -22
  90. package/dist/esm/clients/HubPoolClient.js +61 -91
  91. package/dist/esm/clients/HubPoolClient.js.map +1 -1
  92. package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js +3 -3
  93. package/dist/esm/clients/SpokePoolClient/EVMSpokePoolClient.js.map +1 -1
  94. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.d.ts +3 -5
  95. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +30 -37
  96. package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
  97. package/dist/esm/clients/mocks/MockHubPoolClient.d.ts +9 -9
  98. package/dist/esm/clients/mocks/MockHubPoolClient.js +10 -16
  99. package/dist/esm/clients/mocks/MockHubPoolClient.js.map +1 -1
  100. package/dist/esm/clients/mocks/MockSpokePoolClient.d.ts +13 -9
  101. package/dist/esm/clients/mocks/MockSpokePoolClient.js +60 -44
  102. package/dist/esm/clients/mocks/MockSpokePoolClient.js.map +1 -1
  103. package/dist/esm/clients/mocks/MockSvmSpokePoolClient.d.ts +2 -2
  104. package/dist/esm/clients/mocks/MockSvmSpokePoolClient.js +3 -3
  105. package/dist/esm/clients/mocks/MockSvmSpokePoolClient.js.map +1 -1
  106. package/dist/esm/interfaces/HubPool.d.ts +13 -18
  107. package/dist/esm/interfaces/SpokePool.d.ts +16 -14
  108. package/dist/esm/interfaces/SpokePool.js.map +1 -1
  109. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.d.ts +6 -6
  110. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js +8 -8
  111. package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
  112. package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.d.ts +8 -9
  113. package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.js +77 -66
  114. package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.js.map +1 -1
  115. package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +6 -6
  116. package/dist/esm/relayFeeCalculator/relayFeeCalculator.js +8 -8
  117. package/dist/esm/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
  118. package/dist/esm/utils/AddressUtils.d.ts +4 -7
  119. package/dist/esm/utils/AddressUtils.js +10 -25
  120. package/dist/esm/utils/AddressUtils.js.map +1 -1
  121. package/dist/esm/utils/SpokeUtils.d.ts +8 -3
  122. package/dist/esm/utils/SpokeUtils.js +26 -4
  123. package/dist/esm/utils/SpokeUtils.js.map +1 -1
  124. package/dist/esm/utils/TokenUtils.d.ts +16 -4
  125. package/dist/esm/utils/TokenUtils.js +3 -3
  126. package/dist/esm/utils/TokenUtils.js.map +1 -1
  127. package/dist/types/arch/evm/SpokeUtils.d.ts +2 -2
  128. package/dist/types/arch/evm/SpokeUtils.d.ts.map +1 -1
  129. package/dist/types/arch/svm/SpokeUtils.d.ts +46 -6
  130. package/dist/types/arch/svm/SpokeUtils.d.ts.map +1 -1
  131. package/dist/types/arch/svm/utils.d.ts +11 -1
  132. package/dist/types/arch/svm/utils.d.ts.map +1 -1
  133. package/dist/types/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts +3 -3
  134. package/dist/types/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.d.ts.map +1 -1
  135. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts +2 -2
  136. package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
  137. package/dist/types/clients/BundleDataClient/utils/DataworkerUtils.d.ts.map +1 -1
  138. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts +1 -2
  139. package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
  140. package/dist/types/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts.map +1 -1
  141. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts +63 -63
  142. package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts.map +1 -1
  143. package/dist/types/clients/HubPoolClient.d.ts +21 -22
  144. package/dist/types/clients/HubPoolClient.d.ts.map +1 -1
  145. package/dist/types/clients/SpokePoolClient/EVMSpokePoolClient.d.ts.map +1 -1
  146. package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts +3 -5
  147. package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts.map +1 -1
  148. package/dist/types/clients/mocks/MockHubPoolClient.d.ts +9 -9
  149. package/dist/types/clients/mocks/MockHubPoolClient.d.ts.map +1 -1
  150. package/dist/types/clients/mocks/MockSpokePoolClient.d.ts +13 -9
  151. package/dist/types/clients/mocks/MockSpokePoolClient.d.ts.map +1 -1
  152. package/dist/types/clients/mocks/MockSvmSpokePoolClient.d.ts +2 -2
  153. package/dist/types/clients/mocks/MockSvmSpokePoolClient.d.ts.map +1 -1
  154. package/dist/types/interfaces/HubPool.d.ts +13 -18
  155. package/dist/types/interfaces/HubPool.d.ts.map +1 -1
  156. package/dist/types/interfaces/SpokePool.d.ts +16 -14
  157. package/dist/types/interfaces/SpokePool.d.ts.map +1 -1
  158. package/dist/types/relayFeeCalculator/chain-queries/baseQuery.d.ts +6 -6
  159. package/dist/types/relayFeeCalculator/chain-queries/baseQuery.d.ts.map +1 -1
  160. package/dist/types/relayFeeCalculator/chain-queries/svmQuery.d.ts +8 -9
  161. package/dist/types/relayFeeCalculator/chain-queries/svmQuery.d.ts.map +1 -1
  162. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +6 -6
  163. package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
  164. package/dist/types/utils/AddressUtils.d.ts +4 -7
  165. package/dist/types/utils/AddressUtils.d.ts.map +1 -1
  166. package/dist/types/utils/SpokeUtils.d.ts +8 -3
  167. package/dist/types/utils/SpokeUtils.d.ts.map +1 -1
  168. package/dist/types/utils/TokenUtils.d.ts +16 -4
  169. package/dist/types/utils/TokenUtils.d.ts.map +1 -1
  170. package/package.json +2 -1
  171. package/src/arch/evm/SpokeUtils.ts +8 -22
  172. package/src/arch/svm/SpokeUtils.ts +156 -49
  173. package/src/arch/svm/utils.ts +22 -3
  174. package/src/clients/AcrossConfigStoreClient/AcrossConfigStoreClient.ts +4 -7
  175. package/src/clients/BundleDataClient/BundleDataClient.ts +47 -49
  176. package/src/clients/BundleDataClient/utils/DataworkerUtils.ts +13 -28
  177. package/src/clients/BundleDataClient/utils/FillUtils.ts +4 -6
  178. package/src/clients/BundleDataClient/utils/PoolRebalanceUtils.ts +4 -4
  179. package/src/clients/BundleDataClient/utils/SuperstructUtils.ts +9 -13
  180. package/src/clients/HubPoolClient.ts +79 -113
  181. package/src/clients/SpokePoolClient/EVMSpokePoolClient.ts +1 -7
  182. package/src/clients/SpokePoolClient/SpokePoolClient.ts +37 -104
  183. package/src/clients/mocks/MockHubPoolClient.ts +19 -24
  184. package/src/clients/mocks/MockSpokePoolClient.ts +74 -53
  185. package/src/clients/mocks/MockSvmSpokePoolClient.ts +3 -12
  186. package/src/interfaces/HubPool.ts +13 -22
  187. package/src/interfaces/SpokePool.ts +17 -14
  188. package/src/relayFeeCalculator/chain-queries/baseQuery.ts +8 -10
  189. package/src/relayFeeCalculator/chain-queries/svmQuery.ts +92 -91
  190. package/src/relayFeeCalculator/relayFeeCalculator.ts +14 -16
  191. package/src/utils/AddressUtils.ts +14 -32
  192. package/src/utils/SpokeUtils.ts +33 -11
  193. package/src/utils/TokenUtils.ts +7 -7
@@ -13,10 +13,11 @@ import {
13
13
  isDefined,
14
14
  isUnsafeDepositId,
15
15
  isZeroAddress,
16
+ getDepositRelayData,
16
17
  getNetworkName,
17
18
  paginatedEventQuery,
18
19
  spreadEventWithBlockNumber,
19
- Address,
20
+ toBytes32,
20
21
  } from "../../utils";
21
22
 
22
23
  type BlockTag = providers.BlockTag;
@@ -30,23 +31,10 @@ type BlockTag = providers.BlockTag;
30
31
  export function populateV3Relay(
31
32
  spokePool: Contract,
32
33
  deposit: Omit<Deposit, "messageHash">,
33
- relayer: Address,
34
+ relayer: string,
34
35
  repaymentChainId = deposit.destinationChainId
35
36
  ): Promise<PopulatedTransaction> {
36
- const relayData = {
37
- depositor: deposit.depositor.toBytes32(),
38
- recipient: deposit.recipient.toBytes32(),
39
- inputToken: deposit.inputToken.toBytes32(),
40
- outputToken: deposit.outputToken.toBytes32(),
41
- inputAmount: deposit.inputAmount,
42
- outputAmount: deposit.outputAmount,
43
- originChainId: deposit.originChainId,
44
- depositId: deposit.depositId,
45
- fillDeadline: deposit.fillDeadline,
46
- exclusivityDeadline: deposit.exclusivityDeadline,
47
- message: deposit.message,
48
- exclusiveRelayer: deposit.exclusiveRelayer.toBytes32(),
49
- };
37
+ const relayData = getDepositRelayData(deposit);
50
38
 
51
39
  if (isDefined(deposit.speedUpSignature)) {
52
40
  assert(isDefined(deposit.updatedRecipient) && !isZeroAddress(deposit.updatedRecipient));
@@ -55,18 +43,16 @@ export function populateV3Relay(
55
43
  return spokePool.populateTransaction.fillRelayWithUpdatedDeposit(
56
44
  relayData,
57
45
  repaymentChainId,
58
- relayer.toBytes32(),
46
+ toBytes32(relayer),
59
47
  deposit.updatedOutputAmount,
60
- deposit.updatedRecipient.toBytes32(),
48
+ toBytes32(deposit.updatedRecipient),
61
49
  deposit.updatedMessage,
62
50
  deposit.speedUpSignature,
63
- { from: relayer.toAddress() }
51
+ { from: relayer }
64
52
  );
65
53
  }
66
54
 
67
- return spokePool.populateTransaction.fillRelay(relayData, repaymentChainId, relayer.toBytes32(), {
68
- from: relayer.toAddress(),
69
- });
55
+ return spokePool.populateTransaction.fillRelay(relayData, repaymentChainId, toBytes32(relayer), { from: relayer });
70
56
  }
71
57
 
72
58
  /**
@@ -4,17 +4,21 @@ import { hashNonEmptyMessage } from "@across-protocol/contracts/dist/src/svm/web
4
4
  import {
5
5
  ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
6
6
  TOKEN_PROGRAM_ADDRESS,
7
+ fetchMint,
7
8
  getApproveCheckedInstruction,
9
+ getCreateAssociatedTokenIdempotentInstruction,
8
10
  } from "@solana-program/token";
9
11
  import {
10
12
  Address,
11
13
  address,
14
+ appendTransactionMessageInstruction,
12
15
  fetchEncodedAccount,
13
16
  fetchEncodedAccounts,
14
17
  getAddressEncoder,
15
18
  getProgramDerivedAddress,
16
19
  getU32Encoder,
17
20
  getU64Encoder,
21
+ pipe,
18
22
  some,
19
23
  type TransactionSigner,
20
24
  } from "@solana/kit";
@@ -22,19 +26,17 @@ import assert from "assert";
22
26
  import { arrayify, hexZeroPad, hexlify } from "ethers/lib/utils";
23
27
  import { Logger } from "winston";
24
28
 
25
- import { CHAIN_IDs } from "../../constants";
29
+ import { SYSTEM_PROGRAM_ADDRESS } from "@solana-program/system";
26
30
  import { Deposit, DepositWithBlock, FillStatus, FillWithBlock, RelayData } from "../../interfaces";
31
+ import { BigNumber, SvmAddress, chainIsSvm, chunk, isUnsafeDepositId, keccak256, toAddressType } from "../../utils";
27
32
  import {
28
- BigNumber,
29
- SvmAddress,
30
- chainIsSvm,
31
- chunk,
32
- getTokenInfo,
33
- isDefined,
34
- isUnsafeDepositId,
35
- keccak256,
36
- } from "../../utils";
37
- import { SvmCpiEventsClient, getEventAuthority, getFillStatusPda, getStatePda, unwrapEventData } from "./";
33
+ SvmCpiEventsClient,
34
+ createDefaultTransaction,
35
+ getEventAuthority,
36
+ getFillStatusPda,
37
+ getStatePda,
38
+ unwrapEventData,
39
+ } from "./";
38
40
  import { SVMEventNames, SVMProvider } from "./types";
39
41
 
40
42
  /**
@@ -355,7 +357,7 @@ export async function fillRelayInstruction(
355
357
  deposit.exclusiveRelayer,
356
358
  deposit.inputToken,
357
359
  deposit.outputToken,
358
- ].map((addr) => addr.forceSvmAddress());
360
+ ].map((addr) => toAddressType(addr).forceSvmAddress());
359
361
 
360
362
  const _relayDataHash = getRelayDataHash(deposit, deposit.destinationChainId);
361
363
  const relayDataHash = new Uint8Array(Buffer.from(_relayDataHash.slice(2), "hex"));
@@ -366,7 +368,7 @@ export async function fillRelayInstruction(
366
368
  const [statePda, fillStatusPda, eventAuthority] = await Promise.all([
367
369
  getStatePda(spokePool.toV2Address()),
368
370
  getFillStatusPda(spokePool.toV2Address(), deposit, deposit.destinationChainId),
369
- getEventAuthority(spokePool.toV2Address()),
371
+ getEventAuthority(),
370
372
  ]);
371
373
  const depositIdBuffer = new Uint8Array(32);
372
374
  const shortenedBuffer = new Uint8Array(Buffer.from(deposit.depositId.toHexString().slice(2), "hex"));
@@ -425,41 +427,146 @@ export function createTokenAccountsInstruction(
425
427
  }
426
428
 
427
429
  /**
428
- * @param mint Address of the token corresponding to the account being made.
429
- * @param amount Amount of the token to approve.
430
- * @param relayer Address of the relayer filling the deposit.
431
- * @param spokePool Address (program ID) of the SvmSpoke.
432
- * @returns A token approval instruction.
430
+ * Creates a fill instruction.
431
+ * @param signer - The signer of the transaction.
432
+ * @param solanaClient - The Solana client.
433
+ * @param fillInput - The fill input.
434
+ * @param tokenDecimals - The token decimals.
435
+ * @param createRecipientAtaIfNeeded - Whether to create a recipient token account.
436
+ * @returns The fill instruction.
433
437
  */
434
- export async function createApproveInstruction(
435
- mint: SvmAddress,
436
- amount: BigNumber,
437
- relayer: SvmAddress,
438
- spokePool: SvmAddress,
439
- mintDecimals?: number
440
- ) {
441
- const [relayerTokenAccount, statePda] = await Promise.all([
442
- getAssociatedTokenAddress(relayer, mint, TOKEN_PROGRAM_ADDRESS),
443
- getStatePda(spokePool.toV2Address()),
444
- ]);
438
+ export const createFillInstruction = async (
439
+ signer: TransactionSigner,
440
+ solanaClient: SVMProvider,
441
+ fillInput: SvmSpokeClient.FillRelayInput,
442
+ tokenDecimals: number,
443
+ createRecipientAtaIfNeeded: boolean = true
444
+ ) => {
445
+ const mintInfo = await fetchMint(solanaClient, fillInput.mint);
446
+ const approveIx = getApproveCheckedInstruction(
447
+ {
448
+ source: fillInput.relayerTokenAccount,
449
+ mint: fillInput.mint,
450
+ delegate: fillInput.delegate,
451
+ owner: fillInput.signer,
452
+ amount: (fillInput.relayData as SvmSpokeClient.RelayDataArgs).outputAmount,
453
+ decimals: tokenDecimals,
454
+ },
455
+ {
456
+ programAddress: mintInfo.programAddress,
457
+ }
458
+ );
445
459
 
446
- // If no mint decimals were supplied, then assign it to whatever value we have in TOKEN_SYMBOLS_MAP.
447
- // If this token is not in TOKEN_SYMBOLS_MAP, then throw an error.
448
- mintDecimals ??= getTokenInfo(mint.toBase58(), CHAIN_IDs.SOLANA)?.decimals;
449
- if (!isDefined(mintDecimals)) {
450
- throw new Error(`No mint decimals found for token ${mint.toBase58()}`);
451
- }
460
+ const getCreateAssociatedTokenIdempotentIx = () =>
461
+ getCreateAssociatedTokenIdempotentInstruction({
462
+ payer: signer,
463
+ owner: (fillInput.relayData as SvmSpokeClient.RelayDataArgs).recipient,
464
+ mint: fillInput.mint,
465
+ ata: fillInput.recipientTokenAccount,
466
+ systemProgram: SYSTEM_PROGRAM_ADDRESS,
467
+ tokenProgram: fillInput.tokenProgram,
468
+ });
452
469
 
453
- return getApproveCheckedInstruction({
454
- source: relayerTokenAccount,
455
- mint: mint.toV2Address(),
456
- delegate: statePda,
457
- owner: relayer.toV2Address(),
458
- amount: amount.toBigInt(),
459
- decimals: mintDecimals,
460
- });
461
- }
470
+ const createFillIx = await SvmSpokeClient.getFillRelayInstruction(fillInput);
471
+
472
+ return pipe(
473
+ await createDefaultTransaction(solanaClient, signer),
474
+ (tx) =>
475
+ createRecipientAtaIfNeeded ? appendTransactionMessageInstruction(getCreateAssociatedTokenIdempotentIx(), tx) : tx,
476
+ (tx) => appendTransactionMessageInstruction(approveIx, tx),
477
+ (tx) => appendTransactionMessageInstruction(createFillIx, tx)
478
+ );
479
+ };
462
480
 
481
+ /**
482
+ * Creates a deposit instruction.
483
+ * @param signer - The signer of the transaction.
484
+ * @param solanaClient - The Solana client.
485
+ * @param depositInput - The deposit input.
486
+ * @param tokenDecimals - The token decimals.
487
+ * @param createVaultAtaIfNeeded - Whether to create a vault token account.
488
+ * @returns The deposit instruction.
489
+ */
490
+ export const createDepositInstruction = async (
491
+ signer: TransactionSigner,
492
+ solanaClient: SVMProvider,
493
+ depositInput: SvmSpokeClient.DepositInput,
494
+ tokenDecimals: number,
495
+ createVaultAtaIfNeeded: boolean = true
496
+ ) => {
497
+ const getCreateAssociatedTokenIdempotentIx = () =>
498
+ getCreateAssociatedTokenIdempotentInstruction({
499
+ payer: signer,
500
+ owner: depositInput.state,
501
+ mint: depositInput.mint,
502
+ ata: depositInput.vault,
503
+ systemProgram: depositInput.systemProgram,
504
+ tokenProgram: depositInput.tokenProgram,
505
+ });
506
+ const mintInfo = await fetchMint(solanaClient, depositInput.mint);
507
+ const approveIx = getApproveCheckedInstruction(
508
+ {
509
+ source: depositInput.depositorTokenAccount,
510
+ mint: depositInput.mint,
511
+ delegate: depositInput.delegate,
512
+ owner: depositInput.depositor,
513
+ amount: depositInput.inputAmount,
514
+ decimals: tokenDecimals,
515
+ },
516
+ {
517
+ programAddress: mintInfo.programAddress,
518
+ }
519
+ );
520
+ const depositIx = await SvmSpokeClient.getDepositInstruction(depositInput);
521
+ return pipe(
522
+ await createDefaultTransaction(solanaClient, signer),
523
+ (tx) =>
524
+ createVaultAtaIfNeeded ? appendTransactionMessageInstruction(getCreateAssociatedTokenIdempotentIx(), tx) : tx,
525
+ (tx) => appendTransactionMessageInstruction(approveIx, tx),
526
+ (tx) => appendTransactionMessageInstruction(depositIx, tx)
527
+ );
528
+ };
529
+
530
+ /**
531
+ * Creates a request slow fill instruction.
532
+ * @param signer - The signer of the transaction.
533
+ * @param solanaClient - The Solana client.
534
+ * @param depositInput - The deposit input.
535
+ * @returns The request slow fill instruction.
536
+ */
537
+ export const createRequestSlowFillInstruction = async (
538
+ signer: TransactionSigner,
539
+ solanaClient: SVMProvider,
540
+ depositInput: SvmSpokeClient.RequestSlowFillInput
541
+ ) => {
542
+ const requestSlowFillIx = await SvmSpokeClient.getRequestSlowFillInstruction(depositInput);
543
+
544
+ return pipe(await createDefaultTransaction(solanaClient, signer), (tx) =>
545
+ appendTransactionMessageInstruction(requestSlowFillIx, tx)
546
+ );
547
+ };
548
+
549
+ /**
550
+ * Creates a close fill PDA instruction.
551
+ * @param signer - The signer of the transaction.
552
+ * @param solanaClient - The Solana client.
553
+ * @param fillStatusPda - The fill status PDA.
554
+ * @returns The close fill PDA instruction.
555
+ */
556
+ export const createCloseFillPdaInstruction = async (
557
+ signer: TransactionSigner,
558
+ solanaClient: SVMProvider,
559
+ fillStatusPda: Address
560
+ ) => {
561
+ const closeFillPdaIx = await SvmSpokeClient.getCloseFillPdaInstruction({
562
+ signer,
563
+ state: await getStatePda(SvmSpokeClient.SVM_SPOKE_PROGRAM_ADDRESS),
564
+ fillStatus: fillStatusPda,
565
+ });
566
+ return pipe(await createDefaultTransaction(solanaClient, signer), (tx) =>
567
+ appendTransactionMessageInstruction(closeFillPdaIx, tx)
568
+ );
569
+ };
463
570
  export async function getAssociatedTokenAddress(
464
571
  owner: SvmAddress,
465
572
  mint: SvmAddress,
@@ -484,11 +591,11 @@ export function getRelayDataHash(relayData: RelayData, destinationChainId: numbe
484
591
  assert(relayData.message.startsWith("0x"), "Message must be a hex string");
485
592
 
486
593
  const contentToHash = Buffer.concat([
487
- Uint8Array.from(addressEncoder.encode(address(relayData.depositor.toBase58()))),
488
- Uint8Array.from(addressEncoder.encode(address(relayData.recipient.toBase58()))),
489
- Uint8Array.from(addressEncoder.encode(address(relayData.exclusiveRelayer.toBase58()))),
490
- Uint8Array.from(addressEncoder.encode(address(relayData.inputToken.toBase58()))),
491
- Uint8Array.from(addressEncoder.encode(address(relayData.outputToken.toBase58()))),
594
+ Uint8Array.from(addressEncoder.encode(SvmAddress.from(relayData.depositor, "base16").toV2Address())),
595
+ Uint8Array.from(addressEncoder.encode(SvmAddress.from(relayData.recipient, "base16").toV2Address())),
596
+ Uint8Array.from(addressEncoder.encode(SvmAddress.from(relayData.exclusiveRelayer, "base16").toV2Address())),
597
+ Uint8Array.from(addressEncoder.encode(SvmAddress.from(relayData.inputToken, "base16").toV2Address())),
598
+ Uint8Array.from(addressEncoder.encode(SvmAddress.from(relayData.outputToken, "base16").toV2Address())),
492
599
  Uint8Array.from(uint64Encoder.encode(BigInt(relayData.inputAmount.toString()))),
493
600
  Uint8Array.from(uint64Encoder.encode(BigInt(relayData.outputAmount.toString()))),
494
601
  Uint8Array.from(uint64Encoder.encode(BigInt(relayData.originChainId.toString()))),
@@ -10,6 +10,10 @@ import {
10
10
  getU32Encoder,
11
11
  isAddress,
12
12
  type TransactionSigner,
13
+ pipe,
14
+ createTransactionMessage,
15
+ setTransactionMessageFeePayerSigner,
16
+ setTransactionMessageLifetimeUsingBlockhash,
13
17
  } from "@solana/kit";
14
18
  import { SvmSpokeClient } from "@across-protocol/contracts";
15
19
  import { FillType, RelayData } from "../../interfaces";
@@ -264,13 +268,13 @@ export async function getInstructionParamsPda(programId: Address, signer: Addres
264
268
  * Returns the PDA for the Event Authority.
265
269
  * @returns The PDA for the Event Authority.
266
270
  */
267
- export async function getEventAuthority(programId: Address): Promise<Address> {
271
+ export const getEventAuthority = async () => {
268
272
  const [eventAuthority] = await getProgramDerivedAddress({
269
- programAddress: programId,
273
+ programAddress: address(SvmSpokeClient.SVM_SPOKE_PROGRAM_ADDRESS),
270
274
  seeds: ["__event_authority"],
271
275
  });
272
276
  return eventAuthority;
273
- }
277
+ };
274
278
 
275
279
  /**
276
280
  * Returns a random SVM address.
@@ -280,3 +284,18 @@ export function getRandomSvmAddress() {
280
284
  const base58Address = bs58.encode(bytes);
281
285
  return address(base58Address);
282
286
  }
287
+
288
+ /**
289
+ * Creates a default v0 transaction skeleton.
290
+ * @param rpcClient - The Solana client.
291
+ * @param signer - The signer of the transaction.
292
+ * @returns The default transaction.
293
+ */
294
+ export const createDefaultTransaction = async (rpcClient: SVMProvider, signer: TransactionSigner) => {
295
+ const { value: latestBlockhash } = await rpcClient.getLatestBlockhash().send();
296
+ return pipe(
297
+ createTransactionMessage({ version: 0 }),
298
+ (tx) => setTransactionMessageFeePayerSigner(signer, tx),
299
+ (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx)
300
+ );
301
+ };
@@ -5,7 +5,6 @@ import winston from "winston";
5
5
  import { isError } from "../../typeguards";
6
6
  import {
7
7
  EventSearchConfig,
8
- EvmAddress,
9
8
  MakeOptional,
10
9
  isArrayOf,
11
10
  isDefined,
@@ -108,7 +107,7 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
108
107
  }
109
108
 
110
109
  getRateModelForBlockNumber(
111
- l1Token: EvmAddress,
110
+ l1Token: string,
112
111
  originChainId: number | string,
113
112
  destinationChainId: number | string,
114
113
  blockNumber: number | undefined = undefined
@@ -122,9 +121,7 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
122
121
 
123
122
  const defaultRateModelUpdate = sortEventsDescending(this.cumulativeRateModelUpdates).find(
124
123
  (config) =>
125
- config.blockNumber <= (blockNumber ?? 0) &&
126
- config.l1Token === l1Token.toEvmAddress() &&
127
- config.rateModel !== undefined
124
+ config.blockNumber <= (blockNumber ?? 0) && config.l1Token === l1Token && config.rateModel !== undefined
128
125
  );
129
126
  if (!defaultRateModelUpdate) {
130
127
  throw new Error(`Could not find TokenConfig update for ${l1Token} at block ${blockNumber}`);
@@ -133,12 +130,12 @@ export class AcrossConfigStoreClient extends BaseAbstractClient {
133
130
  }
134
131
 
135
132
  getRouteRateModelForBlockNumber(
136
- l1Token: EvmAddress,
133
+ l1Token: string,
137
134
  route: string,
138
135
  blockNumber: number | undefined = undefined
139
136
  ): RateModel | undefined {
140
137
  const config = (sortEventsDescending(this.cumulativeRouteRateModelUpdates) as RouteRateModelUpdate[]).find(
141
- (config) => config.blockNumber <= (blockNumber ?? 0) && config.l1Token === l1Token.toEvmAddress()
138
+ (config) => config.blockNumber <= (blockNumber ?? 0) && config.l1Token === l1Token
142
139
  );
143
140
  if (config?.routeRateModel[route] === undefined) {
144
141
  return undefined;
@@ -40,9 +40,9 @@ import {
40
40
  isZeroValueDeposit,
41
41
  isZeroValueFillOrSlowFillRequest,
42
42
  chainIsEvm,
43
+ isValidEvmAddress,
43
44
  duplicateEvent,
44
45
  invalidOutputToken,
45
- Address,
46
46
  } from "../../utils";
47
47
  import winston from "winston";
48
48
  import {
@@ -67,20 +67,22 @@ type DataCache = Record<string, Promise<LoadDataReturnValue>>;
67
67
  // V3 dictionary helper functions
68
68
  function updateExpiredDepositsV3(dict: ExpiredDepositsToRefundV3, deposit: V3DepositWithBlock): void {
69
69
  // A deposit refund for a deposit is invalid if the depositor has a bytes32 address input for an EVM chain. It is valid otherwise.
70
- if (chainIsEvm(deposit.originChainId) && !deposit.depositor.isValidEvmAddress()) {
70
+ if (chainIsEvm(deposit.originChainId) && !isValidEvmAddress(deposit.depositor)) {
71
71
  return;
72
72
  }
73
73
  const { originChainId, inputToken } = deposit;
74
- dict[originChainId] ??= {};
75
- dict[originChainId][inputToken.toBytes32()] ??= [];
76
- dict[originChainId][inputToken.toBytes32()].push(deposit);
74
+ if (!dict?.[originChainId]?.[inputToken]) {
75
+ assign(dict, [originChainId, inputToken], []);
76
+ }
77
+ dict[originChainId][inputToken].push(deposit);
77
78
  }
78
79
 
79
80
  function updateBundleDepositsV3(dict: BundleDepositsV3, deposit: V3DepositWithBlock): void {
80
81
  const { originChainId, inputToken } = deposit;
81
- dict[originChainId] ??= {};
82
- dict[originChainId][inputToken.toBytes32()] ??= [];
83
- dict[originChainId][inputToken.toBytes32()].push(deposit);
82
+ if (!dict?.[originChainId]?.[inputToken]) {
83
+ assign(dict, [originChainId, inputToken], []);
84
+ }
85
+ dict[originChainId][inputToken].push(deposit);
84
86
  }
85
87
 
86
88
  function updateBundleFillsV3(
@@ -88,28 +90,29 @@ function updateBundleFillsV3(
88
90
  fill: V3FillWithBlock,
89
91
  lpFeePct: BigNumber,
90
92
  repaymentChainId: number,
91
- repaymentToken: Address,
92
- repaymentAddress: Address
93
+ repaymentToken: string,
94
+ repaymentAddress: string
93
95
  ): void {
94
96
  // We shouldn't pass any unrepayable fills into this function, so we perform an extra safety check.
95
- if (chainIsEvm(repaymentChainId) && !fill.relayer.isValidEvmAddress()) {
97
+ if (chainIsEvm(repaymentChainId) && !isValidEvmAddress(fill.relayer)) {
96
98
  return;
97
99
  }
98
- dict[repaymentChainId] ??= {};
99
- dict[repaymentChainId][repaymentToken.toBytes32()] ??= {
100
- fills: [],
101
- totalRefundAmount: bnZero,
102
- realizedLpFees: bnZero,
103
- refunds: {},
104
- };
100
+ if (!dict?.[repaymentChainId]?.[repaymentToken]) {
101
+ assign(dict, [repaymentChainId, repaymentToken], {
102
+ fills: [],
103
+ totalRefundAmount: bnZero,
104
+ realizedLpFees: bnZero,
105
+ refunds: {},
106
+ });
107
+ }
105
108
 
106
109
  const bundleFill: BundleFillV3 = { ...fill, lpFeePct, relayer: repaymentAddress };
107
110
 
108
111
  // Add all fills, slow and fast, to dictionary.
109
- assign(dict, [repaymentChainId, repaymentToken.toBytes32(), "fills"], [bundleFill]);
112
+ assign(dict, [repaymentChainId, repaymentToken, "fills"], [bundleFill]);
110
113
 
111
114
  // All fills update the bundle LP fees.
112
- const refundObj = dict[repaymentChainId][repaymentToken.toBytes32()];
115
+ const refundObj = dict[repaymentChainId][repaymentToken];
113
116
  const realizedLpFee = bundleFill.inputAmount.mul(bundleFill.lpFeePct).div(fixedPointAdjustment);
114
117
  refundObj.realizedLpFees = refundObj.realizedLpFees ? refundObj.realizedLpFees.add(realizedLpFee) : realizedLpFee;
115
118
 
@@ -123,11 +126,10 @@ function updateBundleFillsV3(
123
126
  // Instantiate dictionary if it doesn't exist.
124
127
  refundObj.refunds ??= {};
125
128
 
126
- if (refundObj.refunds[bundleFill.relayer.toBytes32()]) {
127
- refundObj.refunds[bundleFill.relayer.toBytes32()] =
128
- refundObj.refunds[bundleFill.relayer.toBytes32()].add(refundAmount);
129
+ if (refundObj.refunds[bundleFill.relayer]) {
130
+ refundObj.refunds[bundleFill.relayer] = refundObj.refunds[bundleFill.relayer].add(refundAmount);
129
131
  } else {
130
- refundObj.refunds[bundleFill.relayer.toBytes32()] = refundAmount;
132
+ refundObj.refunds[bundleFill.relayer] = refundAmount;
131
133
  }
132
134
  }
133
135
  }
@@ -137,19 +139,21 @@ function updateBundleExcessSlowFills(
137
139
  deposit: V3DepositWithBlock & { lpFeePct: BigNumber }
138
140
  ): void {
139
141
  const { destinationChainId, outputToken } = deposit;
140
- dict[destinationChainId] ??= {};
141
- dict[destinationChainId][outputToken.toBytes32()] ??= [];
142
- dict[destinationChainId][outputToken.toBytes32()].push(deposit);
142
+ if (!dict?.[destinationChainId]?.[outputToken]) {
143
+ assign(dict, [destinationChainId, outputToken], []);
144
+ }
145
+ dict[destinationChainId][outputToken].push(deposit);
143
146
  }
144
147
 
145
148
  function updateBundleSlowFills(dict: BundleSlowFills, deposit: V3DepositWithBlock & { lpFeePct: BigNumber }): void {
146
- if (chainIsEvm(deposit.destinationChainId) && !deposit.recipient.isValidEvmAddress()) {
149
+ if (chainIsEvm(deposit.destinationChainId) && !isValidEvmAddress(deposit.recipient)) {
147
150
  return;
148
151
  }
149
152
  const { destinationChainId, outputToken } = deposit;
150
- dict[destinationChainId] ??= {};
151
- dict[destinationChainId][outputToken.toBytes32()] ??= [];
152
- dict[destinationChainId][outputToken.toBytes32()].push(deposit);
153
+ if (!dict?.[destinationChainId]?.[outputToken]) {
154
+ assign(dict, [destinationChainId, outputToken], []);
155
+ }
156
+ dict[destinationChainId][outputToken].push(deposit);
153
157
  }
154
158
 
155
159
  // @notice Shared client for computing data needed to construct or validate a bundle.
@@ -485,23 +489,21 @@ export class BundleDataClient {
485
489
  // worst from the relayer's perspective.
486
490
  const { relayer, inputAmount: refundAmount } = fill;
487
491
  refundsForChain[chainToSendRefundTo] ??= {};
488
- refundsForChain[chainToSendRefundTo][repaymentToken.toBytes32()] ??= {};
489
- const existingRefundAmount =
490
- refundsForChain[chainToSendRefundTo][repaymentToken.toBytes32()][relayer.toBytes32()] ?? bnZero;
491
- refundsForChain[chainToSendRefundTo][repaymentToken.toBytes32()][relayer.toBytes32()] =
492
- existingRefundAmount.add(refundAmount);
492
+ refundsForChain[chainToSendRefundTo][repaymentToken] ??= {};
493
+ const existingRefundAmount = refundsForChain[chainToSendRefundTo][repaymentToken][relayer] ?? bnZero;
494
+ refundsForChain[chainToSendRefundTo][repaymentToken][relayer] = existingRefundAmount.add(refundAmount);
493
495
  });
494
496
  }
495
497
  return refundsForChain;
496
498
  }
497
499
 
498
- getUpcomingDepositAmount(chainId: number, l2Token: Address, latestBlockToSearch: number): BigNumber {
500
+ getUpcomingDepositAmount(chainId: number, l2Token: string, latestBlockToSearch: number): BigNumber {
499
501
  if (this.spokePoolClients[chainId] === undefined) {
500
502
  return toBN(0);
501
503
  }
502
504
  return this.spokePoolClients[chainId]
503
505
  .getDeposits()
504
- .filter((deposit) => deposit.blockNumber > latestBlockToSearch && deposit.inputToken.eq(l2Token))
506
+ .filter((deposit) => deposit.blockNumber > latestBlockToSearch && deposit.inputToken === l2Token)
505
507
  .reduce((acc, deposit) => {
506
508
  return acc.add(deposit.inputAmount);
507
509
  }, toBN(0));
@@ -624,18 +626,18 @@ export class BundleDataClient {
624
626
  const executedRefunds: { [tokenAddress: string]: { [relayer: string]: BigNumber } } = {};
625
627
  for (const refundLeaf of executedRefundLeaves) {
626
628
  const tokenAddress = refundLeaf.l2TokenAddress;
627
- if (executedRefunds[tokenAddress.toBytes32()] === undefined) {
628
- executedRefunds[tokenAddress.toBytes32()] = {};
629
+ if (executedRefunds[tokenAddress] === undefined) {
630
+ executedRefunds[tokenAddress] = {};
629
631
  }
630
- const executedTokenRefunds = executedRefunds[tokenAddress.toBytes32()];
632
+ const executedTokenRefunds = executedRefunds[tokenAddress];
631
633
 
632
634
  for (let i = 0; i < refundLeaf.refundAddresses.length; i++) {
633
635
  const relayer = refundLeaf.refundAddresses[i];
634
636
  const refundAmount = refundLeaf.refundAmounts[i];
635
- if (executedTokenRefunds[relayer.toBytes32()] === undefined) {
636
- executedTokenRefunds[relayer.toBytes32()] = bnZero;
637
+ if (executedTokenRefunds[relayer] === undefined) {
638
+ executedTokenRefunds[relayer] = bnZero;
637
639
  }
638
- executedTokenRefunds[relayer.toBytes32()] = executedTokenRefunds[relayer.toBytes32()].add(refundAmount);
640
+ executedTokenRefunds[relayer] = executedTokenRefunds[relayer].add(refundAmount);
639
641
  }
640
642
  }
641
643
  return executedRefunds;
@@ -897,11 +899,7 @@ export class BundleDataClient {
897
899
  "Not using correct bundle deposit hash key"
898
900
  );
899
901
  if (deposit.blockNumber >= originChainBlockRange[0]) {
900
- if (
901
- bundleDepositsV3?.[originChainId]?.[deposit.inputToken.toBytes32()]?.find((d) =>
902
- duplicateEvent(deposit, d)
903
- )
904
- ) {
902
+ if (bundleDepositsV3?.[originChainId]?.[deposit.inputToken]?.find((d) => duplicateEvent(deposit, d))) {
905
903
  this.logger.debug({
906
904
  at: "BundleDataClient#loadData",
907
905
  message: "Duplicate deposit detected",