@xswap-link/sdk 0.10.8 → 0.10.9

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 (69) hide show
  1. package/.eslintrc.json +10 -1
  2. package/CHANGELOG.md +6 -0
  3. package/dist/index.global.js +331 -331
  4. package/dist/index.js +9 -9
  5. package/dist/index.mjs +9 -9
  6. package/package.json +6 -3
  7. package/src/components/Swap/SwapView/ConfirmationView/TxOverview/index.tsx +106 -9
  8. package/src/components/Swap/SwapView/SwapButton/index.tsx +11 -11
  9. package/src/constants/index.ts +19 -2
  10. package/src/context/SwapProvider.tsx +7 -3
  11. package/src/services/api.ts +1 -0
  12. package/src/services/svm/README.md +483 -0
  13. package/src/services/svm/bindings/accounts/AllowedOfframp.ts +73 -0
  14. package/src/services/svm/bindings/accounts/Config.ts +153 -0
  15. package/src/services/svm/bindings/accounts/DestChain.ts +113 -0
  16. package/src/services/svm/bindings/accounts/Nonce.ts +97 -0
  17. package/src/services/svm/bindings/accounts/index.ts +15 -0
  18. package/src/services/svm/bindings/accounts/tokenAdminRegistry.ts +128 -0
  19. package/src/services/svm/bindings/errors/anchor.ts +773 -0
  20. package/src/services/svm/bindings/errors/custom.ts +375 -0
  21. package/src/services/svm/bindings/errors/index.ts +62 -0
  22. package/src/services/svm/bindings/instructions/ccipSend.ts +112 -0
  23. package/src/services/svm/bindings/instructions/getFee.ts +73 -0
  24. package/src/services/svm/bindings/instructions/index.ts +4 -0
  25. package/src/services/svm/bindings/programId.ts +6 -0
  26. package/src/services/svm/bindings/types/BaseChain.ts +92 -0
  27. package/src/services/svm/bindings/types/BaseConfig.ts +184 -0
  28. package/src/services/svm/bindings/types/CodeVersion.ts +88 -0
  29. package/src/services/svm/bindings/types/CrossChainAmount.ts +53 -0
  30. package/src/services/svm/bindings/types/DestChainConfig.ts +76 -0
  31. package/src/services/svm/bindings/types/DestChainState.ts +76 -0
  32. package/src/services/svm/bindings/types/GetFeeResult.ts +72 -0
  33. package/src/services/svm/bindings/types/LockOrBurnInV1.ts +102 -0
  34. package/src/services/svm/bindings/types/LockOrBurnOutV1.ts +79 -0
  35. package/src/services/svm/bindings/types/RampMessageHeader.ts +94 -0
  36. package/src/services/svm/bindings/types/RateLimitConfig.ts +72 -0
  37. package/src/services/svm/bindings/types/RateLimitTokenBucket.ts +76 -0
  38. package/src/services/svm/bindings/types/ReleaseOrMintInV1.ts +156 -0
  39. package/src/services/svm/bindings/types/ReleaseOrMintOutV1.ts +53 -0
  40. package/src/services/svm/bindings/types/RemoteAddress.ts +61 -0
  41. package/src/services/svm/bindings/types/RemoteConfig.ts +86 -0
  42. package/src/services/svm/bindings/types/RestoreOnAction.ts +120 -0
  43. package/src/services/svm/bindings/types/SVM2AnyMessage.ts +128 -0
  44. package/src/services/svm/bindings/types/SVM2AnyRampMessage.ts +166 -0
  45. package/src/services/svm/bindings/types/SVM2AnyTokenTransfer.ts +118 -0
  46. package/src/services/svm/bindings/types/SVMTokenAmount.ts +64 -0
  47. package/src/services/svm/bindings/types/index.ts +78 -0
  48. package/src/services/svm/core/client/accounts.ts +97 -0
  49. package/src/services/svm/core/client/events.ts +95 -0
  50. package/src/services/svm/core/client/fee.ts +279 -0
  51. package/src/services/svm/core/client/index.ts +150 -0
  52. package/src/services/svm/core/client/send.ts +607 -0
  53. package/src/services/svm/core/client/utils.ts +131 -0
  54. package/src/services/svm/core/models.ts +236 -0
  55. package/src/services/svm/index.ts +32 -0
  56. package/src/services/svm/utils/conversion.ts +62 -0
  57. package/src/services/svm/utils/errors.ts +51 -0
  58. package/src/services/svm/utils/keypair.ts +19 -0
  59. package/src/services/svm/utils/logger.ts +171 -0
  60. package/src/services/svm/utils/pdas/common.ts +15 -0
  61. package/src/services/svm/utils/pdas/feeQuoter.ts +68 -0
  62. package/src/services/svm/utils/pdas/index.ts +12 -0
  63. package/src/services/svm/utils/pdas/receiver.ts +58 -0
  64. package/src/services/svm/utils/pdas/rmnRemote.ts +23 -0
  65. package/src/services/svm/utils/pdas/router.ts +328 -0
  66. package/src/services/svm/utils/pdas/tokenpool.ts +161 -0
  67. package/src/services/svm/utils/transaction.ts +132 -0
  68. package/src/utils/validation.ts +7 -3
  69. package/tsconfig.json +2 -1
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Common utilities for PDA derivation
3
+ */
4
+
5
+ /**
6
+ * Converts a u64 to 8-byte little endian buffer
7
+ * @param n - Number to convert
8
+ * @returns Buffer representation
9
+ */
10
+ export function uint64ToLE(n: number | bigint): Buffer {
11
+ const bn = BigInt(n);
12
+ const buf = Buffer.alloc(8);
13
+ buf.writeBigUInt64LE(bn);
14
+ return buf;
15
+ }
@@ -0,0 +1,68 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import { uint64ToLE } from "./common";
3
+
4
+ /**
5
+ * Fee Quoter PDA utilities
6
+ */
7
+
8
+ /**
9
+ * Finds the Fee Quoter Config PDA
10
+ * @param feeQuoter Fee Quoter program ID
11
+ * @returns [PDA, bump]
12
+ */
13
+ export function findFqConfigPDA(feeQuoter: PublicKey): [PublicKey, number] {
14
+ return PublicKey.findProgramAddressSync([Buffer.from("config")], feeQuoter);
15
+ }
16
+
17
+ /**
18
+ * Finds the Fee Quoter Dest Chain PDA for a chain selector
19
+ * @param chainSelector Chain selector
20
+ * @param feeQuoter Fee Quoter program ID
21
+ * @returns [PDA, bump]
22
+ */
23
+ export function findFqDestChainPDA(chainSelector: bigint, feeQuoter: PublicKey): [PublicKey, number] {
24
+ return PublicKey.findProgramAddressSync(
25
+ [Buffer.from("dest_chain"), uint64ToLE(chainSelector)],
26
+ feeQuoter
27
+ );
28
+ }
29
+
30
+ /**
31
+ * Finds the Fee Quoter Billing Token Config PDA for a mint
32
+ * @param mint Token mint
33
+ * @param feeQuoter Fee Quoter program ID
34
+ * @returns [PDA, bump]
35
+ */
36
+ export function findFqBillingTokenConfigPDA(mint: PublicKey, feeQuoter: PublicKey): [PublicKey, number] {
37
+ return PublicKey.findProgramAddressSync(
38
+ [Buffer.from("fee_billing_token_config"), mint.toBuffer()],
39
+ feeQuoter
40
+ );
41
+ }
42
+
43
+ /**
44
+ * Finds the Fee Quoter Per Chain Per Token Config PDA for a chain selector and mint
45
+ * @param chainSelector Chain selector
46
+ * @param mint Token mint
47
+ * @param feeQuoter Fee Quoter program ID
48
+ * @returns [PDA, bump]
49
+ */
50
+ export function findFqPerChainPerTokenConfigPDA(chainSelector: bigint, mint: PublicKey, feeQuoter: PublicKey): [PublicKey, number] {
51
+ return PublicKey.findProgramAddressSync(
52
+ [Buffer.from("per_chain_per_token_config"), uint64ToLE(chainSelector), mint.toBuffer()],
53
+ feeQuoter
54
+ );
55
+ }
56
+
57
+ /**
58
+ * Finds the Fee Quoter Allowed Price Updater PDA for a price updater
59
+ * @param priceUpdater Price updater public key
60
+ * @param feeQuoter Fee Quoter program ID
61
+ * @returns [PDA, bump]
62
+ */
63
+ export function findFqAllowedPriceUpdaterPDA(priceUpdater: PublicKey, feeQuoter: PublicKey): [PublicKey, number] {
64
+ return PublicKey.findProgramAddressSync(
65
+ [Buffer.from("allowed_price_updater"), priceUpdater.toBuffer()],
66
+ feeQuoter
67
+ );
68
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * PDA utilities for CCIP and related programs
3
+ * This module exports all PDA-related functionality in a unified way
4
+ */
5
+
6
+ // Export all PDA modules
7
+ export * from "./router";
8
+ export * from "./feeQuoter";
9
+ export * from "./rmnRemote";
10
+ export * from "./common";
11
+ export * from "./receiver";
12
+ export * from "./tokenpool";
@@ -0,0 +1,58 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+
3
+ /**
4
+ * CCIP Receiver PDA utilities
5
+ */
6
+
7
+ // Seeds for the CCIP receiver program
8
+ export const RECEIVER_SEEDS = {
9
+ EXTERNAL_EXECUTION_CONFIG: Buffer.from("external_execution_config"),
10
+ STATE: Buffer.from("state"),
11
+ CONFIG: Buffer.from("config"),
12
+ DEST_CHAIN_STATE: Buffer.from("dest_chain_state"),
13
+ FEE_BILLING_SIGNER: Buffer.from("fee_billing_signer"),
14
+ NONCE: Buffer.from("nonce"),
15
+ FEE_BILLING_TOKEN_CONFIG: Buffer.from("fee_billing_token_config"),
16
+ CURSES: Buffer.from("curses"),
17
+ };
18
+
19
+ /**
20
+ * Derives the state PDA for a CCIP receiver program
21
+ * @param programId Receiver program ID
22
+ * @returns State PDA
23
+ */
24
+ export function deriveStatePda(programId: PublicKey): PublicKey {
25
+ const [statePda] = PublicKey.findProgramAddressSync(
26
+ [RECEIVER_SEEDS.STATE],
27
+ programId,
28
+ );
29
+ return statePda;
30
+ }
31
+
32
+ /**
33
+ * Derives the config PDA for a CCIP receiver program
34
+ * @param programId Receiver program ID
35
+ * @returns Config PDA
36
+ */
37
+ export function deriveConfigPda(programId: PublicKey): PublicKey {
38
+ const [configPda] = PublicKey.findProgramAddressSync(
39
+ [RECEIVER_SEEDS.CONFIG],
40
+ programId,
41
+ );
42
+ return configPda;
43
+ }
44
+
45
+ /**
46
+ * Derives the external execution config PDA for a CCIP receiver program
47
+ * @param programId Receiver program ID
48
+ * @returns External execution config PDA
49
+ */
50
+ export function deriveExternalExecutionConfigPda(
51
+ programId: PublicKey,
52
+ ): PublicKey {
53
+ const [pda] = PublicKey.findProgramAddressSync(
54
+ [RECEIVER_SEEDS.EXTERNAL_EXECUTION_CONFIG],
55
+ programId,
56
+ );
57
+ return pda;
58
+ }
@@ -0,0 +1,23 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+
3
+ /**
4
+ * RMN Remote PDA utilities
5
+ */
6
+
7
+ /**
8
+ * Finds the RMN Remote Config PDA for a program
9
+ * @param programId RMN Remote program ID
10
+ * @returns [PDA, bump]
11
+ */
12
+ export function findRMNRemoteConfigPDA(programId: PublicKey): [PublicKey, number] {
13
+ return PublicKey.findProgramAddressSync([Buffer.from("config")], programId);
14
+ }
15
+
16
+ /**
17
+ * Finds the RMN Remote Curses PDA for a program
18
+ * @param programId RMN Remote program ID
19
+ * @returns [PDA, bump]
20
+ */
21
+ export function findRMNRemoteCursesPDA(programId: PublicKey): [PublicKey, number] {
22
+ return PublicKey.findProgramAddressSync([Buffer.from("curses")], programId);
23
+ }
@@ -0,0 +1,328 @@
1
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
+ // @ts-nocheck
3
+ import { PublicKey } from "@solana/web3.js";
4
+ import { uint64ToLE } from "./common";
5
+ import { Connection } from "@solana/web3.js";
6
+ import { tokenAdminRegistry } from "../../bindings/accounts";
7
+
8
+ /**
9
+ * CCIP Router seeds for PDA derivation
10
+ */
11
+ export const ROUTER_SEEDS = {
12
+ CONFIG: "config",
13
+ FEE_BILLING_SIGNER: "fee_billing_signer",
14
+ TOKEN_ADMIN_REGISTRY: "token_admin_registry",
15
+ DEST_CHAIN_STATE: "dest_chain_state",
16
+ NONCE: "nonce",
17
+ ALLOWED_OFFRAMP: "allowed_offramp",
18
+ EXTERNAL_TOKEN_POOLS_SIGNER: "external_token_pools_signer",
19
+ APPROVED_CCIP_SENDER: "approved_ccip_sender",
20
+ EXTERNAL_EXECUTION_CONFIG: "external_execution_config",
21
+ TOKEN_POOL_CHAIN_CONFIG: "ccip_tokenpool_chainconfig",
22
+ } as const;
23
+
24
+ /**
25
+ * CCIP Router PDA utilities
26
+ */
27
+
28
+ /**
29
+ * Finds the Config PDA for a program
30
+ * @param programId Router program ID
31
+ * @returns [PDA, bump]
32
+ */
33
+ export function findConfigPDA(programId: PublicKey): [PublicKey, number] {
34
+ return PublicKey.findProgramAddressSync(
35
+ [Buffer.from(ROUTER_SEEDS.CONFIG)],
36
+ programId,
37
+ );
38
+ }
39
+
40
+ /**
41
+ * Finds the Fee Billing Signer PDA for a program
42
+ * @param programId Router program ID
43
+ * @returns [PDA, bump]
44
+ */
45
+ export function findFeeBillingSignerPDA(
46
+ programId: PublicKey,
47
+ ): [PublicKey, number] {
48
+ return PublicKey.findProgramAddressSync(
49
+ [Buffer.from(ROUTER_SEEDS.FEE_BILLING_SIGNER)],
50
+ programId,
51
+ );
52
+ }
53
+
54
+ /**
55
+ * Finds the Token Admin Registry PDA for a mint
56
+ * @param mint Token mint
57
+ * @param programId Router program ID
58
+ * @returns [PDA, bump]
59
+ */
60
+ export function findTokenAdminRegistryPDA(
61
+ mint: PublicKey,
62
+ programId: PublicKey,
63
+ ): [PublicKey, number] {
64
+ return PublicKey.findProgramAddressSync(
65
+ [Buffer.from(ROUTER_SEEDS.TOKEN_ADMIN_REGISTRY), mint.toBuffer()],
66
+ programId,
67
+ );
68
+ }
69
+
70
+ /**
71
+ * Finds the Destination Chain State PDA for a chain selector
72
+ * @param chainSelector Chain selector
73
+ * @param programId Router program ID
74
+ * @returns [PDA, bump]
75
+ */
76
+ export function findDestChainStatePDA(
77
+ chainSelector: bigint,
78
+ programId: PublicKey,
79
+ ): [PublicKey, number] {
80
+ return PublicKey.findProgramAddressSync(
81
+ [Buffer.from(ROUTER_SEEDS.DEST_CHAIN_STATE), uint64ToLE(chainSelector)],
82
+ programId,
83
+ );
84
+ }
85
+
86
+ /**
87
+ * Finds the Nonce PDA for a chain selector and authority
88
+ * @param chainSelector Chain selector
89
+ * @param authority User authority
90
+ * @param programId Router program ID
91
+ * @returns [PDA, bump]
92
+ */
93
+ export function findNoncePDA(
94
+ chainSelector: bigint,
95
+ authority: PublicKey,
96
+ programId: PublicKey,
97
+ ): [PublicKey, number] {
98
+ return PublicKey.findProgramAddressSync(
99
+ [
100
+ Buffer.from(ROUTER_SEEDS.NONCE),
101
+ uint64ToLE(chainSelector),
102
+ authority.toBuffer(),
103
+ ],
104
+ programId,
105
+ );
106
+ }
107
+
108
+ /**
109
+ * Finds the Approved Sender PDA for a chain selector and source sender
110
+ * @param chainSelector Chain selector
111
+ * @param sourceSender Source chain sender address
112
+ * @param receiverProgram Receiver program ID
113
+ * @returns [PDA, bump]
114
+ */
115
+ export function findApprovedSenderPDA(
116
+ chainSelector: bigint,
117
+ sourceSender: Buffer,
118
+ receiverProgram: PublicKey,
119
+ ): [PublicKey, number] {
120
+ const lenPrefix = Buffer.from([sourceSender.length]);
121
+ return PublicKey.findProgramAddressSync(
122
+ [
123
+ Buffer.from(ROUTER_SEEDS.APPROVED_CCIP_SENDER),
124
+ uint64ToLE(chainSelector),
125
+ lenPrefix,
126
+ sourceSender,
127
+ ],
128
+ receiverProgram,
129
+ );
130
+ }
131
+
132
+ /**
133
+ * Finds the Allowed Offramp PDA for a chain selector and offramp
134
+ * @param chainSelector Chain selector
135
+ * @param offramp Offramp program ID
136
+ * @param programId Router program ID
137
+ * @returns [PDA, bump]
138
+ */
139
+ export function findAllowedOfframpPDA(
140
+ chainSelector: bigint,
141
+ offramp: PublicKey,
142
+ programId: PublicKey,
143
+ ): [PublicKey, number] {
144
+ return PublicKey.findProgramAddressSync(
145
+ [
146
+ Buffer.from(ROUTER_SEEDS.ALLOWED_OFFRAMP),
147
+ uint64ToLE(chainSelector),
148
+ offramp.toBuffer(),
149
+ ],
150
+ programId,
151
+ );
152
+ }
153
+
154
+ /**
155
+ * Finds the Token Pool Chain Config PDA for a chain selector and token mint
156
+ * @param chainSelector Chain selector
157
+ * @param tokenMint Token mint
158
+ * @param programId Pool program ID
159
+ * @returns [PDA, bump]
160
+ */
161
+ export function findTokenPoolChainConfigPDA(
162
+ chainSelector: bigint,
163
+ tokenMint: PublicKey,
164
+ programId: PublicKey,
165
+ ): [PublicKey, number] {
166
+ return PublicKey.findProgramAddressSync(
167
+ [
168
+ Buffer.from(ROUTER_SEEDS.TOKEN_POOL_CHAIN_CONFIG),
169
+ uint64ToLE(chainSelector),
170
+ tokenMint.toBuffer(),
171
+ ],
172
+ programId,
173
+ );
174
+ }
175
+
176
+ /**
177
+ * Finds the External Token Pools Signer PDA for a program
178
+ * @param programId Router program ID
179
+ * @returns [PDA, bump]
180
+ */
181
+ export function findExternalTokenPoolsSignerPDA(
182
+ programId: PublicKey,
183
+ ): [PublicKey, number] {
184
+ return PublicKey.findProgramAddressSync(
185
+ [Buffer.from(ROUTER_SEEDS.EXTERNAL_TOKEN_POOLS_SIGNER)],
186
+ programId,
187
+ );
188
+ }
189
+
190
+ /**
191
+ * Dynamically finds the correct token pool signer PDA for a specific token by retrieving
192
+ * its admin registry and pool program from the lookup table.
193
+ *
194
+ * This function performs on-chain lookups to determine the exact PDA used for token transfers
195
+ * in the CCIP protocol, which requires both the external_token_pools_signer seed and the
196
+ * pool program ID from the token's lookup table.
197
+ *
198
+ * @param mint Token mint public key
199
+ * @param routerProgramId CCIP Router program ID
200
+ * @param connection Solana connection
201
+ * @returns Promise with [PDA, bump]
202
+ */
203
+ export async function findDynamicTokenPoolsSignerPDA(
204
+ mint: PublicKey,
205
+ routerProgramId: PublicKey,
206
+ connection: Connection,
207
+ ): Promise<[PublicKey, number]> {
208
+ // First find the token admin registry PDA
209
+ const [tokenAdminRegistryPDA] = findTokenAdminRegistryPDA(
210
+ mint,
211
+ routerProgramId,
212
+ );
213
+
214
+ // Fetch the token admin registry account
215
+ const tokenAdminRegistryAccount = await connection.getAccountInfo(
216
+ tokenAdminRegistryPDA,
217
+ );
218
+ if (!tokenAdminRegistryAccount) {
219
+ throw new Error(
220
+ `Token admin registry not found for mint: ${mint.toString()}`,
221
+ );
222
+ }
223
+
224
+ // Decode the token admin registry to get the lookup table
225
+ const tokenRegistry = tokenAdminRegistry.decode(
226
+ tokenAdminRegistryAccount.data,
227
+ );
228
+ const lookupTableAddress = tokenRegistry.lookupTable;
229
+
230
+ // Fetch the lookup table
231
+ const { value: lookupTableAccount } = await connection.getAddressLookupTable(
232
+ lookupTableAddress,
233
+ );
234
+ if (!lookupTableAccount) {
235
+ throw new Error(`Lookup table not found: ${lookupTableAddress.toString()}`);
236
+ }
237
+
238
+ // Get the addresses from the lookup table
239
+ const lookupTableAddresses = lookupTableAccount.state.addresses;
240
+
241
+ // The pool program is at index 2 in the lookup table
242
+ if (lookupTableAddresses.length <= 2) {
243
+ throw new Error(
244
+ "Lookup table doesn't have enough entries to determine pool program",
245
+ );
246
+ }
247
+
248
+ // Extract the pool program from the lookup table (index 2)
249
+ const poolProgram = lookupTableAddresses[2];
250
+
251
+ // Now create the correct PDA using both the external_token_pools_signer seed and the pool program
252
+ return PublicKey.findProgramAddressSync(
253
+ [
254
+ Buffer.from(ROUTER_SEEDS.EXTERNAL_TOKEN_POOLS_SIGNER),
255
+ poolProgram.toBuffer(),
256
+ ],
257
+ routerProgramId,
258
+ );
259
+ }
260
+
261
+ /**
262
+ * Finds the External Execution Config PDA for a program
263
+ * @param programId Router program ID
264
+ * @returns [PDA, bump]
265
+ */
266
+ export function findExternalExecutionConfigPDA(
267
+ programId: PublicKey,
268
+ ): [PublicKey, number] {
269
+ return PublicKey.findProgramAddressSync(
270
+ [Buffer.from(ROUTER_SEEDS.EXTERNAL_EXECUTION_CONFIG)],
271
+ programId,
272
+ );
273
+ }
274
+
275
+ /**
276
+ * Finds the correct token pool signer PDA using the CCIPAccountReader
277
+ *
278
+ * This version uses the CCIPAccountReader which already has methods to retrieve
279
+ * token admin registry accounts, making the process more reliable and consistent
280
+ * with the rest of the SDK.
281
+ *
282
+ * @param mint Token mint public key
283
+ * @param routerProgramId CCIP Router program ID
284
+ * @param accountReader CCIPAccountReader instance
285
+ * @param connection Solana connection
286
+ * @returns Promise with [PDA, bump]
287
+ */
288
+ export async function findTokenPoolsSignerWithAccountReader(
289
+ mint: PublicKey,
290
+ routerProgramId: PublicKey,
291
+ accountReader: import("../../core/client/accounts").CCIPAccountReader,
292
+ connection: Connection,
293
+ ): Promise<[PublicKey, number]> {
294
+ // Use the account reader to get the token admin registry
295
+ const tokenRegistry = await accountReader.getTokenAdminRegistry(mint);
296
+
297
+ // Fetch the lookup table
298
+ const { value: lookupTableAccount } = await connection.getAddressLookupTable(
299
+ tokenRegistry.lookupTable,
300
+ );
301
+ if (!lookupTableAccount) {
302
+ throw new Error(
303
+ `Lookup table not found: ${tokenRegistry.lookupTable.toString()}`,
304
+ );
305
+ }
306
+
307
+ // Get the addresses from the lookup table
308
+ const lookupTableAddresses = lookupTableAccount.state.addresses;
309
+
310
+ // The pool program is at index 2 in the lookup table
311
+ if (lookupTableAddresses.length <= 2) {
312
+ throw new Error(
313
+ "Lookup table doesn't have enough entries to determine pool program",
314
+ );
315
+ }
316
+
317
+ // Extract the pool program from the lookup table (index 2)
318
+ const poolProgram = lookupTableAddresses[2];
319
+
320
+ // Now create the correct PDA using both the external_token_pools_signer seed and the pool program
321
+ return PublicKey.findProgramAddressSync(
322
+ [
323
+ Buffer.from(ROUTER_SEEDS.EXTERNAL_TOKEN_POOLS_SIGNER),
324
+ poolProgram.toBuffer(),
325
+ ],
326
+ routerProgramId,
327
+ );
328
+ }
@@ -0,0 +1,161 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import { uint64ToLE } from "./common";
3
+
4
+ /**
5
+ * Token Pool PDA utilities
6
+ */
7
+
8
+ // Token Pool seed constants
9
+ export const TOKEN_POOL_STATE_SEED = "state";
10
+ export const TOKEN_POOL_CHAIN_CONFIG_SEED = "chain_config";
11
+ export const TOKEN_POOL_POOL_SIGNER_SEED = "pool_signer";
12
+ export const TOKEN_POOL_RATE_LIMIT_STATE_SEED = "rate_limit_state";
13
+ export const TOKEN_POOL_CHAIN_RATE_LIMIT_SEED = "chain_rate_limit";
14
+ export const TOKEN_POOL_BURN_TRACKING_SEED = "burn_tracking";
15
+ export const TOKEN_POOL_MINT_TRACKING_SEED = "mint_tracking";
16
+
17
+ // Solana system program IDs
18
+ // Use the official BPF Loader Upgradeable Program ID
19
+ // This is hardcoded because @solana/web3.js does not export it directly
20
+ export const BPF_LOADER_UPGRADEABLE_PROGRAM_ID = new PublicKey(
21
+ "BPFLoaderUpgradeab1e11111111111111111111111"
22
+ );
23
+
24
+ /**
25
+ * Finds the State PDA for the burn-mint pool (main configuration)
26
+ * @param mint Token mint
27
+ * @param programId Burn-mint pool program ID
28
+ * @returns [PDA, bump]
29
+ */
30
+ export function findBurnMintPoolConfigPDA(
31
+ mint: PublicKey,
32
+ programId: PublicKey
33
+ ): [PublicKey, number] {
34
+ return PublicKey.findProgramAddressSync(
35
+ [Buffer.from(TOKEN_POOL_STATE_SEED), mint.toBuffer()],
36
+ programId
37
+ );
38
+ }
39
+
40
+ /**
41
+ * Finds the Chain Config PDA for a chain selector and token mint
42
+ * @param chainSelector Chain selector
43
+ * @param tokenMint Token mint
44
+ * @param programId Burn-mint pool program ID
45
+ * @returns [PDA, bump]
46
+ */
47
+ export function findBurnMintPoolChainConfigPDA(
48
+ chainSelector: bigint,
49
+ tokenMint: PublicKey,
50
+ programId: PublicKey
51
+ ): [PublicKey, number] {
52
+ return PublicKey.findProgramAddressSync(
53
+ [
54
+ Buffer.from(TOKEN_POOL_CHAIN_CONFIG_SEED),
55
+ uint64ToLE(chainSelector),
56
+ tokenMint.toBuffer(),
57
+ ],
58
+ programId
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Finds the Program Data PDA for the burn-mint pool program
64
+ * @param programId Burn-mint pool program ID
65
+ * @returns [PDA, bump]
66
+ */
67
+ export function findProgramDataPDA(programId: PublicKey): [PublicKey, number] {
68
+ return PublicKey.findProgramAddressSync(
69
+ [programId.toBuffer()],
70
+ BPF_LOADER_UPGRADEABLE_PROGRAM_ID
71
+ );
72
+ }
73
+
74
+ /**
75
+ * Finds the Rate Limit State PDA for a token mint
76
+ * This is used for global rate limiting
77
+ * @param tokenMint Token mint
78
+ * @param programId Burn-mint pool program ID
79
+ * @returns [PDA, bump]
80
+ */
81
+ export function findRateLimitStatePDA(
82
+ tokenMint: PublicKey,
83
+ programId: PublicKey
84
+ ): [PublicKey, number] {
85
+ return PublicKey.findProgramAddressSync(
86
+ [Buffer.from(TOKEN_POOL_RATE_LIMIT_STATE_SEED), tokenMint.toBuffer()],
87
+ programId
88
+ );
89
+ }
90
+
91
+ /**
92
+ * Finds the Chain Rate Limit PDA for a chain selector and token mint
93
+ * This is used for per-chain rate limiting
94
+ * @param chainSelector Chain selector
95
+ * @param tokenMint Token mint
96
+ * @param programId Burn-mint pool program ID
97
+ * @returns [PDA, bump]
98
+ */
99
+ export function findChainRateLimitPDA(
100
+ chainSelector: bigint,
101
+ tokenMint: PublicKey,
102
+ programId: PublicKey
103
+ ): [PublicKey, number] {
104
+ return PublicKey.findProgramAddressSync(
105
+ [
106
+ Buffer.from(TOKEN_POOL_CHAIN_RATE_LIMIT_SEED),
107
+ uint64ToLE(chainSelector),
108
+ tokenMint.toBuffer(),
109
+ ],
110
+ programId
111
+ );
112
+ }
113
+
114
+ /**
115
+ * Finds the Pool Signer PDA for a mint
116
+ * Used as the authority for token accounts
117
+ * @param mint Token mint
118
+ * @param programId Burn-mint pool program ID
119
+ * @returns [PDA, bump]
120
+ */
121
+ export function findPoolSignerPDA(
122
+ mint: PublicKey,
123
+ programId: PublicKey
124
+ ): [PublicKey, number] {
125
+ return PublicKey.findProgramAddressSync(
126
+ [Buffer.from(TOKEN_POOL_POOL_SIGNER_SEED), mint.toBuffer()],
127
+ programId
128
+ );
129
+ }
130
+
131
+ /**
132
+ * Finds the Burn Tracking PDA for a message ID
133
+ * @param messageId Message ID as byte array
134
+ * @param programId Burn-mint pool program ID
135
+ * @returns [PDA, bump]
136
+ */
137
+ export function findBurnTrackingPDA(
138
+ messageId: Uint8Array,
139
+ programId: PublicKey
140
+ ): [PublicKey, number] {
141
+ return PublicKey.findProgramAddressSync(
142
+ [Buffer.from(TOKEN_POOL_BURN_TRACKING_SEED), Buffer.from(messageId)],
143
+ programId
144
+ );
145
+ }
146
+
147
+ /**
148
+ * Finds the Mint Tracking PDA for a message ID
149
+ * @param messageId Message ID as byte array
150
+ * @param programId Burn-mint pool program ID
151
+ * @returns [PDA, bump]
152
+ */
153
+ export function findMintTrackingPDA(
154
+ messageId: Uint8Array,
155
+ programId: PublicKey
156
+ ): [PublicKey, number] {
157
+ return PublicKey.findProgramAddressSync(
158
+ [Buffer.from(TOKEN_POOL_MINT_TRACKING_SEED), Buffer.from(messageId)],
159
+ programId
160
+ );
161
+ }