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,483 @@
1
+ /**
2
+ * DEX parameters — RPC loaders aligned with Rust `src/trading/core/params.rs`
3
+ */
4
+
5
+ import { PublicKey, Connection } from '@solana/web3.js';
6
+ import {
7
+ TOKEN_PROGRAM,
8
+ TOKEN_PROGRAM_2022,
9
+ WSOL_TOKEN_ACCOUNT,
10
+ USD1_TOKEN_ACCOUNT,
11
+ BONK_PROGRAM,
12
+ } from '../constants';
13
+ import {
14
+ getBondingCurvePda,
15
+ getCreatorVaultPda,
16
+ } from '../instruction/pumpfun_builder';
17
+ import {
18
+ findByMint as findPumpSwapPoolByMint,
19
+ fetchPool as fetchPumpSwapPool,
20
+ getTokenBalances as getPumpSwapTokenBalances,
21
+ getAssociatedTokenAddress as getPumpSwapAta,
22
+ getCoinCreatorVaultAta,
23
+ getCoinCreatorVaultAuthority,
24
+ type PumpSwapPool,
25
+ } from '../instruction/pumpswap';
26
+ import {
27
+ fetchBonkPoolState,
28
+ getBonkPoolPDA,
29
+ } from '../instruction/bonk_builder';
30
+ import {
31
+ fetchRaydiumCPMMpoolState,
32
+ getRaydiumCPMMpoolTokenBalances,
33
+ } from '../instruction/raydium_cpmm_builder';
34
+ import { fetchAmmInfo } from '../instruction/raydium_amm_v4_builder';
35
+ import { fetchMeteoraPool } from '../instruction/meteora_damm_v2_builder';
36
+
37
+ /** Maps `Connection` to the minimal RPC shape used by Rust-parity instruction fetch helpers. */
38
+ function wrapConnection(connection: Connection) {
39
+ return {
40
+ getAccountInfo: async (pubkey: PublicKey) => {
41
+ const a = await connection.getAccountInfo(pubkey);
42
+ return { value: a ? { data: Buffer.from(a.data), owner: a.owner } : undefined };
43
+ },
44
+ getTokenAccountBalance: (pubkey: PublicKey) =>
45
+ connection.getTokenAccountBalance(pubkey),
46
+ getProgramAccounts: (
47
+ programId: PublicKey,
48
+ config?: Parameters<Connection['getProgramAccounts']>[1]
49
+ ) => connection.getProgramAccounts(programId, config),
50
+ };
51
+ }
52
+
53
+ // ============== Bonding Curve ==============
54
+
55
+ export interface BondingCurveAccount {
56
+ discriminator: number;
57
+ account: PublicKey;
58
+ virtualTokenReserves: bigint;
59
+ virtualSolReserves: bigint;
60
+ realTokenReserves: bigint;
61
+ realSolReserves: bigint;
62
+ tokenTotalSupply: bigint;
63
+ complete: boolean;
64
+ creator: PublicKey;
65
+ isMayhemMode: boolean;
66
+ isCashbackCoin: boolean;
67
+ }
68
+
69
+ function decodePumpFunBondingCurveData(
70
+ data: Buffer,
71
+ bondingCurveAddr: PublicKey
72
+ ): BondingCurveAccount {
73
+ let offset = 8;
74
+ const virtualTokenReserves = data.readBigUInt64LE(offset);
75
+ offset += 8;
76
+ const virtualSolReserves = data.readBigUInt64LE(offset);
77
+ offset += 8;
78
+ const realTokenReserves = data.readBigUInt64LE(offset);
79
+ offset += 8;
80
+ const realSolReserves = data.readBigUInt64LE(offset);
81
+ offset += 8;
82
+ const tokenTotalSupply = data.readBigUInt64LE(offset);
83
+ offset += 8;
84
+ const complete = data.readUInt8(offset) === 1;
85
+ offset += 1;
86
+ const creator = new PublicKey(data.subarray(offset, offset + 32));
87
+ offset += 32;
88
+ const isMayhemMode = data.readUInt8(offset) === 1;
89
+ offset += 1;
90
+ const isCashbackCoin = data.readUInt8(offset) === 1;
91
+ return {
92
+ discriminator: 0,
93
+ account: bondingCurveAddr,
94
+ virtualTokenReserves,
95
+ virtualSolReserves,
96
+ realTokenReserves,
97
+ realSolReserves,
98
+ tokenTotalSupply,
99
+ complete,
100
+ creator,
101
+ isMayhemMode,
102
+ isCashbackCoin,
103
+ };
104
+ }
105
+
106
+ export class PumpFunParams {
107
+ constructor(
108
+ public bondingCurve: BondingCurveAccount,
109
+ public associatedBondingCurve: PublicKey,
110
+ public creatorVault: PublicKey,
111
+ public tokenProgram: PublicKey,
112
+ public closeTokenAccountWhenSell?: boolean
113
+ ) {}
114
+
115
+ static immediateSell(
116
+ creatorVault: PublicKey,
117
+ tokenProgram: PublicKey,
118
+ closeTokenAccountWhenSell: boolean = false
119
+ ): PumpFunParams {
120
+ return new PumpFunParams(
121
+ {
122
+ discriminator: 0,
123
+ account: PublicKey.default,
124
+ virtualTokenReserves: BigInt(0),
125
+ virtualSolReserves: BigInt(0),
126
+ realTokenReserves: BigInt(0),
127
+ realSolReserves: BigInt(0),
128
+ tokenTotalSupply: BigInt(0),
129
+ complete: false,
130
+ creator: PublicKey.default,
131
+ isMayhemMode: false,
132
+ isCashbackCoin: false,
133
+ },
134
+ PublicKey.default,
135
+ creatorVault,
136
+ tokenProgram,
137
+ closeTokenAccountWhenSell
138
+ );
139
+ }
140
+
141
+ static fromTrade(params: {
142
+ bondingCurve: PublicKey;
143
+ associatedBondingCurve: PublicKey;
144
+ mint: PublicKey;
145
+ creator: PublicKey;
146
+ creatorVault: PublicKey;
147
+ virtualTokenReserves: bigint;
148
+ virtualSolReserves: bigint;
149
+ realTokenReserves: bigint;
150
+ realSolReserves: bigint;
151
+ closeTokenAccountWhenSell?: boolean;
152
+ feeRecipient: PublicKey;
153
+ tokenProgram: PublicKey;
154
+ isCashbackCoin: boolean;
155
+ }): PumpFunParams {
156
+ const isMayhemMode = false;
157
+ return new PumpFunParams(
158
+ {
159
+ discriminator: 0,
160
+ account: params.bondingCurve,
161
+ virtualTokenReserves: params.virtualTokenReserves,
162
+ virtualSolReserves: params.virtualSolReserves,
163
+ realTokenReserves: params.realTokenReserves,
164
+ realSolReserves: params.realSolReserves,
165
+ tokenTotalSupply: BigInt(0),
166
+ complete: false,
167
+ creator: params.creator,
168
+ isMayhemMode,
169
+ isCashbackCoin: params.isCashbackCoin,
170
+ },
171
+ params.associatedBondingCurve,
172
+ params.creatorVault,
173
+ params.tokenProgram,
174
+ params.closeTokenAccountWhenSell
175
+ );
176
+ }
177
+
178
+ static async fromMintByRpc(
179
+ connection: Connection,
180
+ mint: PublicKey
181
+ ): Promise<PumpFunParams> {
182
+ const bondingCurveAddr = getBondingCurvePda(mint);
183
+ const accountInfo = await connection.getAccountInfo(bondingCurveAddr);
184
+ if (!accountInfo?.data?.length) {
185
+ throw new Error('Bonding curve account not found');
186
+ }
187
+ const bondingCurve = decodePumpFunBondingCurveData(
188
+ accountInfo.data,
189
+ bondingCurveAddr
190
+ );
191
+ const mintAccount = await connection.getAccountInfo(mint);
192
+ const tokenProgram = mintAccount?.owner ?? TOKEN_PROGRAM;
193
+ const associatedBondingCurve = getPumpSwapAta(
194
+ bondingCurveAddr,
195
+ mint,
196
+ tokenProgram
197
+ );
198
+ const creatorVault = getCreatorVaultPda(bondingCurve.creator);
199
+ return new PumpFunParams(
200
+ bondingCurve,
201
+ associatedBondingCurve,
202
+ creatorVault,
203
+ tokenProgram
204
+ );
205
+ }
206
+
207
+ withCreatorVault(vault: PublicKey): PumpFunParams {
208
+ this.creatorVault = vault;
209
+ return this;
210
+ }
211
+ }
212
+
213
+ // ============== PumpSwap Params ==============
214
+
215
+ export class PumpSwapParams {
216
+ constructor(
217
+ public pool: PublicKey,
218
+ public baseMint: PublicKey,
219
+ public quoteMint: PublicKey,
220
+ public poolBaseTokenAccount: PublicKey,
221
+ public poolQuoteTokenAccount: PublicKey,
222
+ public poolBaseTokenReserves: bigint,
223
+ public poolQuoteTokenReserves: bigint,
224
+ public coinCreatorVaultAta: PublicKey,
225
+ public coinCreatorVaultAuthority: PublicKey,
226
+ public baseTokenProgram: PublicKey,
227
+ public quoteTokenProgram: PublicKey,
228
+ public isMayhemMode: boolean,
229
+ public isCashbackCoin: boolean
230
+ ) {}
231
+
232
+ static async fromPoolAddressByRpc(
233
+ connection: Connection,
234
+ poolAddress: PublicKey
235
+ ): Promise<PumpSwapParams> {
236
+ const pool = await fetchPumpSwapPool(wrapConnection(connection), poolAddress);
237
+ if (!pool) {
238
+ throw new Error('PumpSwap pool account not found or invalid');
239
+ }
240
+ return PumpSwapParams.fromPoolData(connection, poolAddress, pool);
241
+ }
242
+
243
+ static async fromMintByRpc(
244
+ connection: Connection,
245
+ mint: PublicKey
246
+ ): Promise<PumpSwapParams> {
247
+ const rpc = wrapConnection(connection);
248
+ const found = await findPumpSwapPoolByMint(
249
+ { getAccountInfo: rpc.getAccountInfo },
250
+ mint
251
+ );
252
+ if (!found) {
253
+ throw new Error('No pool found for mint');
254
+ }
255
+ return PumpSwapParams.fromPoolData(
256
+ connection,
257
+ found.poolAddress,
258
+ found.pool
259
+ );
260
+ }
261
+
262
+ private static async fromPoolData(
263
+ connection: Connection,
264
+ poolAddress: PublicKey,
265
+ pool: PumpSwapPool
266
+ ): Promise<PumpSwapParams> {
267
+ const balances = await getPumpSwapTokenBalances(wrapConnection(connection), pool);
268
+ if (!balances) {
269
+ throw new Error('Failed to read pool token balances');
270
+ }
271
+ const baseAtaTp = getPumpSwapAta(
272
+ poolAddress,
273
+ pool.baseMint,
274
+ TOKEN_PROGRAM
275
+ );
276
+ const quoteAtaTp = getPumpSwapAta(
277
+ poolAddress,
278
+ pool.quoteMint,
279
+ TOKEN_PROGRAM
280
+ );
281
+ const baseTokenProgram = pool.poolBaseTokenAccount.equals(baseAtaTp)
282
+ ? TOKEN_PROGRAM
283
+ : TOKEN_PROGRAM_2022;
284
+ const quoteTokenProgram = pool.poolQuoteTokenAccount.equals(quoteAtaTp)
285
+ ? TOKEN_PROGRAM
286
+ : TOKEN_PROGRAM_2022;
287
+ return new PumpSwapParams(
288
+ poolAddress,
289
+ pool.baseMint,
290
+ pool.quoteMint,
291
+ pool.poolBaseTokenAccount,
292
+ pool.poolQuoteTokenAccount,
293
+ balances.baseBalance,
294
+ balances.quoteBalance,
295
+ getCoinCreatorVaultAta(pool.coinCreator, pool.quoteMint),
296
+ getCoinCreatorVaultAuthority(pool.coinCreator),
297
+ baseTokenProgram,
298
+ quoteTokenProgram,
299
+ pool.isMayhemMode,
300
+ pool.isCashbackCoin
301
+ );
302
+ }
303
+ }
304
+
305
+ // ============== Bonk Params ==============
306
+
307
+ function bonkPlatformAssociatedAccount(platformConfig: PublicKey): PublicKey {
308
+ const [pda] = PublicKey.findProgramAddressSync(
309
+ [platformConfig.toBuffer(), WSOL_TOKEN_ACCOUNT.toBuffer()],
310
+ BONK_PROGRAM
311
+ );
312
+ return pda;
313
+ }
314
+
315
+ function bonkCreatorAssociatedAccount(creator: PublicKey): PublicKey {
316
+ const [pda] = PublicKey.findProgramAddressSync(
317
+ [creator.toBuffer(), WSOL_TOKEN_ACCOUNT.toBuffer()],
318
+ BONK_PROGRAM
319
+ );
320
+ return pda;
321
+ }
322
+
323
+ export class BonkParams {
324
+ constructor(
325
+ public virtualBase: bigint,
326
+ public virtualQuote: bigint,
327
+ public realBase: bigint,
328
+ public realQuote: bigint,
329
+ public poolState: PublicKey,
330
+ public baseVault: PublicKey,
331
+ public quoteVault: PublicKey,
332
+ public mintTokenProgram: PublicKey,
333
+ public platformConfig: PublicKey,
334
+ public platformAssociatedAccount: PublicKey,
335
+ public creatorAssociatedAccount: PublicKey,
336
+ public globalConfig: PublicKey
337
+ ) {}
338
+
339
+ static async fromMintByRpc(
340
+ connection: Connection,
341
+ mint: PublicKey,
342
+ usd1Pool: boolean = false
343
+ ): Promise<BonkParams> {
344
+ const quoteMint = usd1Pool ? USD1_TOKEN_ACCOUNT : WSOL_TOKEN_ACCOUNT;
345
+ const poolAddress = getBonkPoolPDA(mint, quoteMint);
346
+ const poolData = await fetchBonkPoolState(wrapConnection(connection), poolAddress);
347
+ if (!poolData) {
348
+ throw new Error('Bonk pool state not found');
349
+ }
350
+ const tokenAccount = await connection.getAccountInfo(poolData.baseMint);
351
+ const mintTokenProgram = tokenAccount?.owner ?? TOKEN_PROGRAM;
352
+ return new BonkParams(
353
+ poolData.virtualBase,
354
+ poolData.virtualQuote,
355
+ poolData.realBase,
356
+ poolData.realQuote,
357
+ poolAddress,
358
+ poolData.baseVault,
359
+ poolData.quoteVault,
360
+ mintTokenProgram,
361
+ poolData.platformConfig,
362
+ bonkPlatformAssociatedAccount(poolData.platformConfig),
363
+ bonkCreatorAssociatedAccount(poolData.creator),
364
+ poolData.globalConfig
365
+ );
366
+ }
367
+ }
368
+
369
+ // ============== Raydium Params ==============
370
+
371
+ export class RaydiumCpmmParams {
372
+ constructor(
373
+ public poolState: PublicKey,
374
+ public ammConfig: PublicKey,
375
+ public baseMint: PublicKey,
376
+ public quoteMint: PublicKey,
377
+ public baseReserve: bigint,
378
+ public quoteReserve: bigint,
379
+ public baseVault: PublicKey,
380
+ public quoteVault: PublicKey,
381
+ public baseTokenProgram: PublicKey,
382
+ public quoteTokenProgram: PublicKey,
383
+ public observationState: PublicKey
384
+ ) {}
385
+
386
+ static async fromPoolAddressByRpc(
387
+ connection: Connection,
388
+ poolAddress: PublicKey
389
+ ): Promise<RaydiumCpmmParams> {
390
+ const pool = await fetchRaydiumCPMMpoolState(wrapConnection(connection), poolAddress);
391
+ if (!pool) {
392
+ throw new Error('Raydium CPMM pool not found');
393
+ }
394
+ const bal = await getRaydiumCPMMpoolTokenBalances(
395
+ wrapConnection(connection),
396
+ poolAddress,
397
+ pool.token0Mint,
398
+ pool.token1Mint
399
+ );
400
+ if (!bal) {
401
+ throw new Error('Failed to read Raydium CPMM vault balances');
402
+ }
403
+ return new RaydiumCpmmParams(
404
+ poolAddress,
405
+ pool.ammConfig,
406
+ pool.token0Mint,
407
+ pool.token1Mint,
408
+ bal.token0Balance,
409
+ bal.token1Balance,
410
+ pool.token0Vault,
411
+ pool.token1Vault,
412
+ pool.token0Program,
413
+ pool.token1Program,
414
+ pool.observationKey
415
+ );
416
+ }
417
+ }
418
+
419
+ export class RaydiumAmmV4Params {
420
+ constructor(
421
+ public amm: PublicKey,
422
+ public coinMint: PublicKey,
423
+ public pcMint: PublicKey,
424
+ public tokenCoin: PublicKey,
425
+ public tokenPc: PublicKey,
426
+ public coinReserve: number,
427
+ public pcReserve: number
428
+ ) {}
429
+
430
+ static async fromAmmAddressByRpc(
431
+ connection: Connection,
432
+ amm: PublicKey
433
+ ): Promise<RaydiumAmmV4Params> {
434
+ const ammInfo = await fetchAmmInfo(wrapConnection(connection), amm);
435
+ if (!ammInfo) {
436
+ throw new Error('Raydium AMM account not found');
437
+ }
438
+ const coinBal = await connection.getTokenAccountBalance(ammInfo.tokenCoin);
439
+ const pcBal = await connection.getTokenAccountBalance(ammInfo.tokenPc);
440
+ const coinReserve = Number(coinBal.value.amount);
441
+ const pcReserve = Number(pcBal.value.amount);
442
+ return new RaydiumAmmV4Params(
443
+ amm,
444
+ ammInfo.coinMint,
445
+ ammInfo.pcMint,
446
+ ammInfo.tokenCoin,
447
+ ammInfo.tokenPc,
448
+ coinReserve,
449
+ pcReserve
450
+ );
451
+ }
452
+ }
453
+
454
+ export class MeteoraDammV2Params {
455
+ constructor(
456
+ public pool: PublicKey,
457
+ public tokenAVault: PublicKey,
458
+ public tokenBVault: PublicKey,
459
+ public tokenAMint: PublicKey,
460
+ public tokenBMint: PublicKey,
461
+ public tokenAProgram: PublicKey,
462
+ public tokenBProgram: PublicKey
463
+ ) {}
464
+
465
+ static async fromPoolAddressByRpc(
466
+ connection: Connection,
467
+ poolAddress: PublicKey
468
+ ): Promise<MeteoraDammV2Params> {
469
+ const poolData = await fetchMeteoraPool(wrapConnection(connection), poolAddress);
470
+ if (!poolData) {
471
+ throw new Error('Meteora DAMM V2 pool not found');
472
+ }
473
+ return new MeteoraDammV2Params(
474
+ poolAddress,
475
+ poolData.tokenAVault,
476
+ poolData.tokenBVault,
477
+ poolData.tokenAMint,
478
+ poolData.tokenBMint,
479
+ TOKEN_PROGRAM,
480
+ TOKEN_PROGRAM
481
+ );
482
+ }
483
+ }