sol-trade-sdk 0.1.0

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 (87) hide show
  1. package/README.md +390 -0
  2. package/dist/chunk-MMQAMIKR.mjs +3735 -0
  3. package/dist/chunk-NEZDFAYA.mjs +7744 -0
  4. package/dist/clients-VITWK7B6.mjs +1370 -0
  5. package/dist/index-1BK_FXsW.d.mts +2327 -0
  6. package/dist/index-1BK_FXsW.d.ts +2327 -0
  7. package/dist/index.d.mts +2659 -0
  8. package/dist/index.d.ts +2659 -0
  9. package/dist/index.js +13265 -0
  10. package/dist/index.mjs +562 -0
  11. package/dist/perf/index.d.mts +2 -0
  12. package/dist/perf/index.d.ts +2 -0
  13. package/dist/perf/index.js +3742 -0
  14. package/dist/perf/index.mjs +214 -0
  15. package/package.json +101 -0
  16. package/src/__tests__/complete_sdk.test.ts +354 -0
  17. package/src/__tests__/hotpath.test.ts +486 -0
  18. package/src/__tests__/nonce.test.ts +45 -0
  19. package/src/__tests__/sdk.test.ts +425 -0
  20. package/src/address-lookup/index.ts +197 -0
  21. package/src/cache/cache.ts +308 -0
  22. package/src/calc/index.ts +1058 -0
  23. package/src/calc/pumpfun.ts +124 -0
  24. package/src/common/bonding_curve.ts +272 -0
  25. package/src/common/compute-budget.ts +148 -0
  26. package/src/common/confirm-any-signature.ts +184 -0
  27. package/src/common/fast-timing.ts +481 -0
  28. package/src/common/fast_fn.ts +150 -0
  29. package/src/common/gas-fee-strategy.ts +253 -0
  30. package/src/common/map-pool.ts +23 -0
  31. package/src/common/nonce.ts +40 -0
  32. package/src/common/sdk-log.ts +460 -0
  33. package/src/common/seed.ts +381 -0
  34. package/src/common/spl-token.ts +578 -0
  35. package/src/common/subscription-handle.ts +644 -0
  36. package/src/common/trading-utils.ts +239 -0
  37. package/src/common/wsol-manager.ts +325 -0
  38. package/src/compute/compute_budget_manager.ts +187 -0
  39. package/src/compute/index.ts +21 -0
  40. package/src/constants/index.ts +96 -0
  41. package/src/execution/execution.ts +532 -0
  42. package/src/execution/index.ts +42 -0
  43. package/src/hotpath/executor.ts +464 -0
  44. package/src/hotpath/index.ts +64 -0
  45. package/src/hotpath/state.ts +435 -0
  46. package/src/index.ts +2117 -0
  47. package/src/instruction/bonk_builder.ts +730 -0
  48. package/src/instruction/index.ts +24 -0
  49. package/src/instruction/meteora_damm_v2_builder.ts +509 -0
  50. package/src/instruction/pumpfun_builder.ts +1183 -0
  51. package/src/instruction/pumpswap.ts +1123 -0
  52. package/src/instruction/raydium_amm_v4_builder.ts +692 -0
  53. package/src/instruction/raydium_cpmm_builder.ts +795 -0
  54. package/src/middleware/traits.ts +407 -0
  55. package/src/params/index.ts +483 -0
  56. package/src/perf/compiler-optimization.ts +529 -0
  57. package/src/perf/hardware.ts +631 -0
  58. package/src/perf/index.ts +9 -0
  59. package/src/perf/kernel-bypass.ts +656 -0
  60. package/src/perf/protocol.ts +682 -0
  61. package/src/perf/realtime.ts +592 -0
  62. package/src/perf/simd.ts +668 -0
  63. package/src/perf/syscall-bypass.ts +331 -0
  64. package/src/perf/ultra-low-latency.ts +505 -0
  65. package/src/perf/zero-copy.ts +589 -0
  66. package/src/pool/pool.ts +294 -0
  67. package/src/rpc/client.ts +345 -0
  68. package/src/sdk-errors.ts +13 -0
  69. package/src/security/index.ts +26 -0
  70. package/src/security/secure-key.ts +303 -0
  71. package/src/security/validators.ts +281 -0
  72. package/src/seed/pda.ts +262 -0
  73. package/src/serialization/index.ts +28 -0
  74. package/src/serialization/serialization.ts +288 -0
  75. package/src/swqos/clients.ts +1754 -0
  76. package/src/swqos/index.ts +50 -0
  77. package/src/swqos/providers.ts +1707 -0
  78. package/src/trading/core/async-executor.ts +702 -0
  79. package/src/trading/core/confirmation-monitor.ts +711 -0
  80. package/src/trading/core/index.ts +82 -0
  81. package/src/trading/core/retry-handler.ts +683 -0
  82. package/src/trading/core/transaction-pool.ts +780 -0
  83. package/src/trading/executor.ts +385 -0
  84. package/src/trading/factory.ts +282 -0
  85. package/src/trading/index.ts +30 -0
  86. package/src/types.ts +8 -0
  87. package/src/utils/index.ts +155 -0
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Sol Trade SDK - Instruction Builders
3
+ *
4
+ * Production-grade instruction builders for Solana DEX protocols.
5
+ * Supports: PumpFun, PumpSwap, Bonk, Raydium CPMM, Raydium AMM V4, Meteora DAMM V2
6
+ */
7
+
8
+ // PumpFun Protocol
9
+ export * from "./pumpfun_builder";
10
+
11
+ // PumpSwap Protocol
12
+ export * from "./pumpswap";
13
+
14
+ // Bonk Protocol
15
+ export * from "./bonk_builder";
16
+
17
+ // Raydium CPMM Protocol
18
+ export * from "./raydium_cpmm_builder";
19
+
20
+ // Raydium AMM V4 Protocol
21
+ export * from "./raydium_amm_v4_builder";
22
+
23
+ // Meteora DAMM V2 Protocol
24
+ export * from "./meteora_damm_v2_builder";
@@ -0,0 +1,509 @@
1
+ /**
2
+ * Meteora DAMM V2 Protocol Instruction Builder
3
+ *
4
+ * Production-grade instruction builder for Meteora DAMM V2 protocol.
5
+ * 100% port of Rust implementation.
6
+ */
7
+
8
+ import {
9
+ PublicKey,
10
+ Keypair,
11
+ AccountMeta,
12
+ TransactionInstruction,
13
+ SystemProgram,
14
+ } from "@solana/web3.js";
15
+ import {
16
+ getAssociatedTokenAddressSync,
17
+ createAssociatedTokenAccountInstruction,
18
+ TOKEN_PROGRAM_ID,
19
+ createCloseAccountInstruction,
20
+ NATIVE_MINT,
21
+ createSyncNativeInstruction,
22
+ } from "@solana/spl-token";
23
+
24
+ // ============================================
25
+ // Program IDs and Constants
26
+ // ============================================
27
+
28
+ /** Meteora DAMM V2 program ID */
29
+ export const METEORA_DAMM_V2_PROGRAM_ID = new PublicKey(
30
+ "cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG"
31
+ );
32
+
33
+ /** Authority */
34
+ export const METEORA_DAMM_V2_AUTHORITY = new PublicKey(
35
+ "HLnpSz9h2S4hiLQ43rnSD9XkcUThA7B8hQMKmDaiTLcC"
36
+ );
37
+
38
+ // ============================================
39
+ // Discriminators
40
+ // ============================================
41
+
42
+ /** Swap instruction discriminator */
43
+ export const METEORA_DAMM_V2_SWAP_DISCRIMINATOR: Buffer = Buffer.from([
44
+ 248, 198, 158, 145, 225, 117, 135, 200,
45
+ ]);
46
+
47
+ // ============================================
48
+ // Seeds
49
+ // ============================================
50
+
51
+ export const METEORA_DAMM_V2_EVENT_AUTHORITY_SEED = Buffer.from("__event_authority");
52
+
53
+ // ============================================
54
+ // PDA Derivation Functions
55
+ // ============================================
56
+
57
+ /**
58
+ * Derive the event authority PDA
59
+ */
60
+ export function getMeteoraDammV2EventAuthorityPda(): PublicKey {
61
+ const [pda] = PublicKey.findProgramAddressSync(
62
+ [METEORA_DAMM_V2_EVENT_AUTHORITY_SEED],
63
+ METEORA_DAMM_V2_PROGRAM_ID
64
+ );
65
+ return pda;
66
+ }
67
+
68
+ // ============================================
69
+ // Types
70
+ // ============================================
71
+
72
+ export interface MeteoraDammV2Params {
73
+ pool: PublicKey;
74
+ tokenAMint: PublicKey;
75
+ tokenBMint: PublicKey;
76
+ tokenAVault: PublicKey;
77
+ tokenBVault: PublicKey;
78
+ tokenAProgram: PublicKey;
79
+ tokenBProgram: PublicKey;
80
+ }
81
+
82
+ export interface BuildMeteoraDammV2BuyInstructionsParams {
83
+ payer: Keypair | PublicKey;
84
+ inputMint: PublicKey;
85
+ outputMint: PublicKey;
86
+ inputAmount: bigint;
87
+ slippageBasisPoints?: bigint;
88
+ fixedOutputAmount?: bigint;
89
+ createInputMintAta?: boolean;
90
+ createOutputMintAta?: boolean;
91
+ closeInputMintAta?: boolean;
92
+ protocolParams: MeteoraDammV2Params;
93
+ }
94
+
95
+ export interface BuildMeteoraDammV2SellInstructionsParams {
96
+ payer: Keypair | PublicKey;
97
+ inputMint: PublicKey;
98
+ outputMint: PublicKey;
99
+ inputAmount: bigint;
100
+ slippageBasisPoints?: bigint;
101
+ fixedOutputAmount?: bigint;
102
+ createOutputMintAta?: boolean;
103
+ closeOutputMintAta?: boolean;
104
+ closeInputMintAta?: boolean;
105
+ protocolParams: MeteoraDammV2Params;
106
+ }
107
+
108
+ // ============================================
109
+ // Instruction Builders
110
+ // ============================================
111
+
112
+ /**
113
+ * Build buy instructions for Meteora DAMM V2 protocol
114
+ */
115
+ export function buildMeteoraDammV2BuyInstructions(
116
+ params: BuildMeteoraDammV2BuyInstructionsParams
117
+ ): TransactionInstruction[] {
118
+ const {
119
+ payer,
120
+ inputMint,
121
+ outputMint,
122
+ inputAmount,
123
+ fixedOutputAmount,
124
+ createInputMintAta = true,
125
+ createOutputMintAta = true,
126
+ closeInputMintAta = false,
127
+ protocolParams,
128
+ } = params;
129
+
130
+ if (inputAmount === BigInt(0)) {
131
+ throw new Error("Amount cannot be zero");
132
+ }
133
+
134
+ if (!fixedOutputAmount) {
135
+ throw new Error("fixedOutputAmount must be set for Meteora DAMM V2 swap");
136
+ }
137
+
138
+ const payerPubkey = payer instanceof Keypair ? payer.publicKey : payer;
139
+ const instructions: TransactionInstruction[] = [];
140
+
141
+ const WSOL_TOKEN_ACCOUNT = new PublicKey("So11111111111111111111111111111111111111112");
142
+ const USDC_TOKEN_ACCOUNT = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
143
+
144
+ const {
145
+ pool,
146
+ tokenAMint,
147
+ tokenBMint,
148
+ tokenAVault,
149
+ tokenBVault,
150
+ tokenAProgram,
151
+ tokenBProgram,
152
+ } = protocolParams;
153
+
154
+ // Check pool type
155
+ const isWsol = tokenAMint.equals(WSOL_TOKEN_ACCOUNT) || tokenBMint.equals(WSOL_TOKEN_ACCOUNT);
156
+ const isUsdc = tokenAMint.equals(USDC_TOKEN_ACCOUNT) || tokenBMint.equals(USDC_TOKEN_ACCOUNT);
157
+
158
+ if (!isWsol && !isUsdc) {
159
+ throw new Error("Pool must contain WSOL or USDC");
160
+ }
161
+
162
+ // Determine swap direction
163
+ const isAIn = tokenAMint.equals(WSOL_TOKEN_ACCOUNT) || tokenAMint.equals(USDC_TOKEN_ACCOUNT);
164
+
165
+ // Derive user token accounts
166
+ const inputTokenAccount = getAssociatedTokenAddressSync(
167
+ inputMint,
168
+ payerPubkey,
169
+ true,
170
+ isAIn ? tokenAProgram : tokenBProgram
171
+ );
172
+ const outputTokenAccount = getAssociatedTokenAddressSync(
173
+ outputMint,
174
+ payerPubkey,
175
+ true,
176
+ isAIn ? tokenBProgram : tokenAProgram
177
+ );
178
+
179
+ // Derive event authority
180
+ const eventAuthority = getMeteoraDammV2EventAuthorityPda();
181
+
182
+ // Handle WSOL wrapping
183
+ if (createInputMintAta && isWsol) {
184
+ const wsolAta = getAssociatedTokenAddressSync(NATIVE_MINT, payerPubkey, true);
185
+ instructions.push(
186
+ createAssociatedTokenAccountInstruction(
187
+ payerPubkey,
188
+ wsolAta,
189
+ payerPubkey,
190
+ NATIVE_MINT,
191
+ TOKEN_PROGRAM_ID
192
+ )
193
+ );
194
+ instructions.push(createSyncNativeInstruction(wsolAta));
195
+ }
196
+
197
+ // Create output mint ATA if needed
198
+ if (createOutputMintAta) {
199
+ instructions.push(
200
+ createAssociatedTokenAccountInstruction(
201
+ payerPubkey,
202
+ outputTokenAccount,
203
+ payerPubkey,
204
+ outputMint,
205
+ TOKEN_PROGRAM_ID
206
+ )
207
+ );
208
+ }
209
+
210
+ // Build instruction data
211
+ const data = Buffer.alloc(24);
212
+ METEORA_DAMM_V2_SWAP_DISCRIMINATOR.copy(data, 0);
213
+ data.writeBigUInt64LE(inputAmount, 8);
214
+ data.writeBigUInt64LE(fixedOutputAmount, 16);
215
+
216
+ // Build accounts (14 accounts)
217
+ const accounts: AccountMeta[] = [
218
+ { pubkey: METEORA_DAMM_V2_AUTHORITY, isSigner: false, isWritable: false },
219
+ { pubkey: pool, isSigner: false, isWritable: true },
220
+ { pubkey: inputTokenAccount, isSigner: false, isWritable: true },
221
+ { pubkey: outputTokenAccount, isSigner: false, isWritable: true },
222
+ { pubkey: tokenAVault, isSigner: false, isWritable: true },
223
+ { pubkey: tokenBVault, isSigner: false, isWritable: true },
224
+ { pubkey: tokenAMint, isSigner: false, isWritable: false },
225
+ { pubkey: tokenBMint, isSigner: false, isWritable: false },
226
+ { pubkey: payerPubkey, isSigner: true, isWritable: true },
227
+ { pubkey: tokenAProgram, isSigner: false, isWritable: false },
228
+ { pubkey: tokenBProgram, isSigner: false, isWritable: false },
229
+ { pubkey: METEORA_DAMM_V2_PROGRAM_ID, isSigner: false, isWritable: false }, // Referral Token Account (placeholder)
230
+ { pubkey: eventAuthority, isSigner: false, isWritable: false },
231
+ { pubkey: METEORA_DAMM_V2_PROGRAM_ID, isSigner: false, isWritable: false },
232
+ ];
233
+
234
+ instructions.push(
235
+ new TransactionInstruction({
236
+ keys: accounts,
237
+ programId: METEORA_DAMM_V2_PROGRAM_ID,
238
+ data,
239
+ })
240
+ );
241
+
242
+ // Close WSOL ATA if requested
243
+ if (closeInputMintAta && isWsol) {
244
+ const wsolAta = getAssociatedTokenAddressSync(NATIVE_MINT, payerPubkey, true);
245
+ instructions.push(
246
+ createCloseAccountInstruction(wsolAta, payerPubkey, payerPubkey, [], TOKEN_PROGRAM_ID)
247
+ );
248
+ }
249
+
250
+ return instructions;
251
+ }
252
+
253
+ /**
254
+ * Build sell instructions for Meteora DAMM V2 protocol
255
+ */
256
+ export function buildMeteoraDammV2SellInstructions(
257
+ params: BuildMeteoraDammV2SellInstructionsParams
258
+ ): TransactionInstruction[] {
259
+ const {
260
+ payer,
261
+ inputMint,
262
+ outputMint,
263
+ inputAmount,
264
+ fixedOutputAmount,
265
+ createOutputMintAta = true,
266
+ closeOutputMintAta = false,
267
+ closeInputMintAta = false,
268
+ protocolParams,
269
+ } = params;
270
+
271
+ if (inputAmount === BigInt(0)) {
272
+ throw new Error("Amount cannot be zero");
273
+ }
274
+
275
+ if (!fixedOutputAmount) {
276
+ throw new Error("fixedOutputAmount must be set for Meteora DAMM V2 swap");
277
+ }
278
+
279
+ const payerPubkey = payer instanceof Keypair ? payer.publicKey : payer;
280
+ const instructions: TransactionInstruction[] = [];
281
+
282
+ const WSOL_TOKEN_ACCOUNT = new PublicKey("So11111111111111111111111111111111111111112");
283
+ const USDC_TOKEN_ACCOUNT = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
284
+
285
+ const {
286
+ pool,
287
+ tokenAMint,
288
+ tokenBMint,
289
+ tokenAVault,
290
+ tokenBVault,
291
+ tokenAProgram,
292
+ tokenBProgram,
293
+ } = protocolParams;
294
+
295
+ // Check pool type
296
+ const isWsol = tokenBMint.equals(WSOL_TOKEN_ACCOUNT) || tokenAMint.equals(WSOL_TOKEN_ACCOUNT);
297
+ const isUsdc = tokenBMint.equals(USDC_TOKEN_ACCOUNT) || tokenAMint.equals(USDC_TOKEN_ACCOUNT);
298
+
299
+ if (!isWsol && !isUsdc) {
300
+ throw new Error("Pool must contain WSOL or USDC");
301
+ }
302
+
303
+ // Determine swap direction (selling token for WSOL/USDC)
304
+ const isAIn = tokenBMint.equals(WSOL_TOKEN_ACCOUNT) || tokenBMint.equals(USDC_TOKEN_ACCOUNT);
305
+
306
+ // Derive user token accounts
307
+ const inputTokenAccount = getAssociatedTokenAddressSync(
308
+ inputMint,
309
+ payerPubkey,
310
+ true,
311
+ isAIn ? tokenAProgram : tokenBProgram
312
+ );
313
+ const outputTokenAccount = getAssociatedTokenAddressSync(
314
+ outputMint,
315
+ payerPubkey,
316
+ true,
317
+ isAIn ? tokenBProgram : tokenAProgram
318
+ );
319
+
320
+ // Derive event authority
321
+ const eventAuthority = getMeteoraDammV2EventAuthorityPda();
322
+
323
+ // Create WSOL ATA for receiving if needed
324
+ if (createOutputMintAta && isWsol) {
325
+ const wsolAta = getAssociatedTokenAddressSync(NATIVE_MINT, payerPubkey, true);
326
+ instructions.push(
327
+ createAssociatedTokenAccountInstruction(
328
+ payerPubkey,
329
+ wsolAta,
330
+ payerPubkey,
331
+ NATIVE_MINT,
332
+ TOKEN_PROGRAM_ID
333
+ )
334
+ );
335
+ }
336
+
337
+ // Build instruction data
338
+ const data = Buffer.alloc(24);
339
+ METEORA_DAMM_V2_SWAP_DISCRIMINATOR.copy(data, 0);
340
+ data.writeBigUInt64LE(inputAmount, 8);
341
+ data.writeBigUInt64LE(fixedOutputAmount, 16);
342
+
343
+ // Build accounts
344
+ const accounts: AccountMeta[] = [
345
+ { pubkey: METEORA_DAMM_V2_AUTHORITY, isSigner: false, isWritable: false },
346
+ { pubkey: pool, isSigner: false, isWritable: true },
347
+ { pubkey: inputTokenAccount, isSigner: false, isWritable: true },
348
+ { pubkey: outputTokenAccount, isSigner: false, isWritable: true },
349
+ { pubkey: tokenAVault, isSigner: false, isWritable: true },
350
+ { pubkey: tokenBVault, isSigner: false, isWritable: true },
351
+ { pubkey: tokenAMint, isSigner: false, isWritable: false },
352
+ { pubkey: tokenBMint, isSigner: false, isWritable: false },
353
+ { pubkey: payerPubkey, isSigner: true, isWritable: true },
354
+ { pubkey: tokenAProgram, isSigner: false, isWritable: false },
355
+ { pubkey: tokenBProgram, isSigner: false, isWritable: false },
356
+ { pubkey: METEORA_DAMM_V2_PROGRAM_ID, isSigner: false, isWritable: false }, // Referral Token Account
357
+ { pubkey: eventAuthority, isSigner: false, isWritable: false },
358
+ { pubkey: METEORA_DAMM_V2_PROGRAM_ID, isSigner: false, isWritable: false },
359
+ ];
360
+
361
+ instructions.push(
362
+ new TransactionInstruction({
363
+ keys: accounts,
364
+ programId: METEORA_DAMM_V2_PROGRAM_ID,
365
+ data,
366
+ })
367
+ );
368
+
369
+ // Close WSOL ATA if requested
370
+ if (closeOutputMintAta && isWsol) {
371
+ const wsolAta = getAssociatedTokenAddressSync(NATIVE_MINT, payerPubkey, true);
372
+ instructions.push(
373
+ createCloseAccountInstruction(wsolAta, payerPubkey, payerPubkey, [], TOKEN_PROGRAM_ID)
374
+ );
375
+ }
376
+
377
+ // Close input token ATA if requested
378
+ if (closeInputMintAta) {
379
+ instructions.push(
380
+ createCloseAccountInstruction(
381
+ inputTokenAccount,
382
+ payerPubkey,
383
+ payerPubkey,
384
+ [],
385
+ isAIn ? tokenAProgram : tokenBProgram
386
+ )
387
+ );
388
+ }
389
+
390
+ return instructions;
391
+ }
392
+
393
+ // ===== Pool Types and Decoder - from Rust: src/instruction/utils/meteora_damm_v2_types.rs =====
394
+
395
+ /** Pool size in bytes */
396
+ export const METEORA_POOL_SIZE = 1104;
397
+
398
+ /**
399
+ * Meteora DAMM V2 Pool structure (simplified for essential fields)
400
+ * 100% from Rust: src/instruction/utils/meteora_damm_v2_types.rs Pool
401
+ */
402
+ export interface MeteoraDammV2Pool {
403
+ tokenAMint: PublicKey;
404
+ tokenBMint: PublicKey;
405
+ tokenAVault: PublicKey;
406
+ tokenBVault: PublicKey;
407
+ liquidity: bigint;
408
+ sqrtPrice: bigint;
409
+ poolStatus: number;
410
+ tokenAFlag: number;
411
+ tokenBFlag: number;
412
+ }
413
+
414
+ /**
415
+ * Decode a Meteora DAMM V2 pool from account data.
416
+ * 100% from Rust: src/instruction/utils/meteora_damm_v2_types.rs pool_decode
417
+ */
418
+ export function decodeMeteoraPool(data: Buffer): MeteoraDammV2Pool | null {
419
+ if (data.length < METEORA_POOL_SIZE) {
420
+ return null;
421
+ }
422
+
423
+ try {
424
+ // Skip pool_fees structure (first 248 bytes)
425
+ let offset = 248;
426
+
427
+ // token_a_mint: Pubkey (32 bytes)
428
+ const tokenAMint = new PublicKey(data.subarray(offset, offset + 32));
429
+ offset += 32;
430
+
431
+ // token_b_mint: Pubkey
432
+ const tokenBMint = new PublicKey(data.subarray(offset, offset + 32));
433
+ offset += 32;
434
+
435
+ // token_a_vault: Pubkey
436
+ const tokenAVault = new PublicKey(data.subarray(offset, offset + 32));
437
+ offset += 32;
438
+
439
+ // token_b_vault: Pubkey
440
+ const tokenBVault = new PublicKey(data.subarray(offset, offset + 32));
441
+ offset += 32;
442
+
443
+ // Skip whitelisted_vault, partner (64 bytes)
444
+ offset += 64;
445
+
446
+ // liquidity: u128 (16 bytes)
447
+ const liquidity = data.readBigUInt64LE(offset) | (data.readBigUInt64LE(offset + 8) << BigInt(64));
448
+ offset += 16;
449
+
450
+ // Skip padding (16 bytes)
451
+ offset += 16;
452
+
453
+ // Skip protocol_a_fee, protocol_b_fee, partner_a_fee, partner_b_fee (32 bytes)
454
+ offset += 32;
455
+
456
+ // Skip sqrt_min_price, sqrt_max_price (32 bytes)
457
+ offset += 32;
458
+
459
+ // sqrt_price: u128
460
+ const sqrtPrice = data.readBigUInt64LE(offset) | (data.readBigUInt64LE(offset + 8) << BigInt(64));
461
+ offset += 16;
462
+
463
+ // Skip activation_point (8 bytes)
464
+ offset += 8;
465
+
466
+ // activation_type: u8, pool_status: u8, token_a_flag: u8, token_b_flag: u8
467
+ const poolStatus = data.readUInt8(offset + 1);
468
+ const tokenAFlag = data.readUInt8(offset + 2);
469
+ const tokenBFlag = data.readUInt8(offset + 3);
470
+
471
+ return {
472
+ tokenAMint,
473
+ tokenBMint,
474
+ tokenAVault,
475
+ tokenBVault,
476
+ liquidity,
477
+ sqrtPrice,
478
+ poolStatus,
479
+ tokenAFlag,
480
+ tokenBFlag,
481
+ };
482
+ } catch {
483
+ return null;
484
+ }
485
+ }
486
+
487
+ // ===== Async Fetch Functions - from Rust: src/instruction/utils/meteora_damm_v2.rs =====
488
+
489
+ /**
490
+ * Fetch a Meteora DAMM V2 pool from RPC.
491
+ * 100% from Rust: src/instruction/utils/meteora_damm_v2.rs fetch_pool
492
+ */
493
+ export async function fetchMeteoraPool(
494
+ connection: { getAccountInfo: (pubkey: PublicKey) => Promise<{ value?: { data: Buffer; owner?: PublicKey } }> },
495
+ poolAddress: PublicKey
496
+ ): Promise<MeteoraDammV2Pool | null> {
497
+ const account = await connection.getAccountInfo(poolAddress);
498
+ if (!account?.value?.data) {
499
+ return null;
500
+ }
501
+
502
+ // Verify owner is Meteora DAMM V2 program
503
+ if (account.value.owner && !account.value.owner.equals(METEORA_DAMM_V2_PROGRAM_ID)) {
504
+ return null;
505
+ }
506
+
507
+ // Skip 8-byte discriminator
508
+ return decodeMeteoraPool(account.value.data.slice(8));
509
+ }