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,150 @@
1
+ /**
2
+ * Fast functions with caching.
3
+ * Based on sol-trade-sdk Rust implementation.
4
+ */
5
+
6
+ import { PublicKey, TransactionInstruction } from '@solana/web3.js';
7
+
8
+ // Instruction cache
9
+ const instructionCache = new Map<string, TransactionInstruction[]>();
10
+
11
+ // PDA cache
12
+ const pdaCache = new Map<string, PublicKey>();
13
+
14
+ // ATA cache
15
+ const ataCache = new Map<string, PublicKey>();
16
+
17
+ /**
18
+ * Get cached instruction or compute and cache
19
+ */
20
+ export function getCachedInstructions(
21
+ cacheKey: string,
22
+ computeFn: () => TransactionInstruction[],
23
+ ): TransactionInstruction[] {
24
+ const cached = instructionCache.get(cacheKey);
25
+ if (cached) {
26
+ return [...cached];
27
+ }
28
+
29
+ const result = computeFn();
30
+ instructionCache.set(cacheKey, [...result]);
31
+ return result;
32
+ }
33
+
34
+ /**
35
+ * Fast ATA creation with caching
36
+ */
37
+ export function createAssociatedTokenAccountIdempotentFast(
38
+ payer: PublicKey,
39
+ owner: PublicKey,
40
+ mint: PublicKey,
41
+ tokenProgram: PublicKey,
42
+ ): TransactionInstruction[] {
43
+ const cacheKey = `${payer.toBase58()}-${owner.toBase58()}-${mint.toBase58()}-${tokenProgram.toBase58()}`;
44
+
45
+ return getCachedInstructions(cacheKey, () => {
46
+ // Get ATA address
47
+ const ata = getAssociatedTokenAddressFast(owner, mint, tokenProgram);
48
+
49
+ // Create instruction data
50
+ // [1] = create idempotent
51
+ const data = Buffer.from([1, ...payer.toBytes(), ...ata.toBytes(), ...owner.toBytes(), ...mint.toBytes(), ...tokenProgram.toBytes()]);
52
+
53
+ // This is a simplified placeholder - actual implementation would use proper ATA program
54
+ return [];
55
+ });
56
+ }
57
+
58
+ /**
59
+ * Fast ATA address derivation with caching
60
+ */
61
+ export function getAssociatedTokenAddressFast(
62
+ owner: PublicKey,
63
+ mint: PublicKey,
64
+ tokenProgram: PublicKey,
65
+ ): PublicKey {
66
+ const cacheKey = `${owner.toBase58()}-${mint.toBase58()}-${tokenProgram.toBase58()}`;
67
+
68
+ const cached = ataCache.get(cacheKey);
69
+ if (cached) {
70
+ return cached;
71
+ }
72
+
73
+ // Derive ATA (simplified - would use proper PDA derivation)
74
+ // ATA = find_program_address([owner, token_program, mint], associated_token_program)
75
+ const result = PublicKey.default; // Placeholder
76
+ ataCache.set(cacheKey, result);
77
+ return result;
78
+ }
79
+
80
+ /**
81
+ * Fast ATA address derivation with seed optimization
82
+ */
83
+ export function getAssociatedTokenAddressWithProgramIdFastUseSeed(
84
+ owner: PublicKey,
85
+ mint: PublicKey,
86
+ tokenProgram: PublicKey,
87
+ useSeed: boolean = false,
88
+ ): PublicKey {
89
+ if (useSeed) {
90
+ // Use seed-optimized path
91
+ const cacheKey = `seed-${owner.toBase58()}-${mint.toBase58()}-${tokenProgram.toBase58()}`;
92
+ const cached = ataCache.get(cacheKey);
93
+ if (cached) {
94
+ return cached;
95
+ }
96
+
97
+ // Derive with seed optimization
98
+ const result = PublicKey.default; // Placeholder
99
+ ataCache.set(cacheKey, result);
100
+ return result;
101
+ }
102
+
103
+ return getAssociatedTokenAddressFast(owner, mint, tokenProgram);
104
+ }
105
+
106
+ /**
107
+ * Create ATA with seed optimization
108
+ */
109
+ export function createAssociatedTokenAccountIdempotentFastUseSeed(
110
+ payer: PublicKey,
111
+ owner: PublicKey,
112
+ mint: PublicKey,
113
+ tokenProgram: PublicKey,
114
+ useSeed: boolean = false,
115
+ ): TransactionInstruction[] {
116
+ if (useSeed) {
117
+ const cacheKey = `seed-create-${payer.toBase58()}-${owner.toBase58()}-${mint.toBase58()}-${tokenProgram.toBase58()}`;
118
+
119
+ return getCachedInstructions(cacheKey, () => {
120
+ // Seed-optimized ATA creation
121
+ return [];
122
+ });
123
+ }
124
+
125
+ return createAssociatedTokenAccountIdempotentFast(payer, owner, mint, tokenProgram);
126
+ }
127
+
128
+ /**
129
+ * Clear all caches (for testing)
130
+ */
131
+ export function clearCaches(): void {
132
+ instructionCache.clear();
133
+ pdaCache.clear();
134
+ ataCache.clear();
135
+ }
136
+
137
+ /**
138
+ * Get cache statistics
139
+ */
140
+ export function getCacheStats(): {
141
+ instructionCacheSize: number;
142
+ pdaCacheSize: number;
143
+ ataCacheSize: number;
144
+ } {
145
+ return {
146
+ instructionCacheSize: instructionCache.size,
147
+ pdaCacheSize: pdaCache.size,
148
+ ataCacheSize: ataCache.size,
149
+ };
150
+ }
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Gas Fee Strategy for Sol Trade SDK
3
+ */
4
+
5
+ // TradeType is defined in index.ts to avoid circular imports
6
+ export enum TradeType {
7
+ Buy = 'Buy',
8
+ Sell = 'Sell',
9
+ }
10
+
11
+ // SwqosType is defined locally to avoid circular imports
12
+ export enum SwqosType {
13
+ Default = 'Default',
14
+ Jito = 'Jito',
15
+ Bloxroute = 'Bloxroute',
16
+ ZeroSlot = 'ZeroSlot',
17
+ Temporal = 'Temporal',
18
+ FlashBlock = 'FlashBlock',
19
+ BlockRazor = 'BlockRazor',
20
+ Node1 = 'Node1',
21
+ Astralane = 'Astralane',
22
+ NextBlock = 'NextBlock',
23
+ Helius = 'Helius',
24
+ Stellium = 'Stellium',
25
+ Lightspeed = 'Lightspeed',
26
+ Soyas = 'Soyas',
27
+ Speedlanding = 'Speedlanding',
28
+ Triton = 'Triton',
29
+ QuickNode = 'QuickNode',
30
+ Syndica = 'Syndica',
31
+ Figment = 'Figment',
32
+ Alchemy = 'Alchemy',
33
+ }
34
+
35
+ export enum GasFeeStrategyType {
36
+ Normal = 'Normal',
37
+ LowTipHighCuPrice = 'LowTipHighCuPrice',
38
+ HighTipLowCuPrice = 'HighTipLowCuPrice',
39
+ }
40
+
41
+ export interface GasFeeStrategyValue {
42
+ cuLimit: number;
43
+ cuPrice: number;
44
+ tip: number;
45
+ }
46
+
47
+ interface StrategyKey {
48
+ swqosType: SwqosType;
49
+ tradeType: TradeType;
50
+ strategyType: GasFeeStrategyType;
51
+ }
52
+
53
+ export class GasFeeStrategy {
54
+ private strategies: Map<string, GasFeeStrategyValue> = new Map();
55
+
56
+ constructor() {}
57
+
58
+ /**
59
+ * Set global fee strategy for all SWQOS types
60
+ */
61
+ setGlobalFeeStrategy(
62
+ buyCuLimit: number,
63
+ sellCuLimit: number,
64
+ buyCuPrice: number,
65
+ sellCuPrice: number,
66
+ buyTip: number,
67
+ sellTip: number
68
+ ): void {
69
+ const allTypes = [
70
+ SwqosType.Jito,
71
+ SwqosType.NextBlock,
72
+ SwqosType.ZeroSlot,
73
+ SwqosType.Temporal,
74
+ SwqosType.Bloxroute,
75
+ SwqosType.Node1,
76
+ SwqosType.FlashBlock,
77
+ SwqosType.BlockRazor,
78
+ SwqosType.Astralane,
79
+ SwqosType.Stellium,
80
+ SwqosType.Lightspeed,
81
+ SwqosType.Soyas,
82
+ SwqosType.Speedlanding,
83
+ SwqosType.Helius,
84
+ ];
85
+
86
+ for (const swqosType of allTypes) {
87
+ this.set(swqosType, TradeType.Buy, GasFeeStrategyType.Normal, buyCuLimit, buyCuPrice, buyTip);
88
+ this.set(swqosType, TradeType.Sell, GasFeeStrategyType.Normal, sellCuLimit, sellCuPrice, sellTip);
89
+ }
90
+
91
+ // Default (RPC) has no tip
92
+ this.set(SwqosType.Default, TradeType.Buy, GasFeeStrategyType.Normal, buyCuLimit, buyCuPrice, 0);
93
+ this.set(SwqosType.Default, TradeType.Sell, GasFeeStrategyType.Normal, sellCuLimit, sellCuPrice, 0);
94
+ }
95
+
96
+ /**
97
+ * Set high-low fee strategies for multiple SWQOS types
98
+ */
99
+ setHighLowFeeStrategies(
100
+ swqosTypes: SwqosType[],
101
+ tradeType: TradeType,
102
+ cuLimit: number,
103
+ lowCuPrice: number,
104
+ highCuPrice: number,
105
+ lowTip: number,
106
+ highTip: number
107
+ ): void {
108
+ for (const swqosType of swqosTypes) {
109
+ this.delete(swqosType, tradeType, GasFeeStrategyType.Normal);
110
+ this.set(swqosType, tradeType, GasFeeStrategyType.LowTipHighCuPrice, cuLimit, highCuPrice, lowTip);
111
+ this.set(swqosType, tradeType, GasFeeStrategyType.HighTipLowCuPrice, cuLimit, lowCuPrice, highTip);
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Set a specific gas fee strategy
117
+ */
118
+ set(
119
+ swqosType: SwqosType,
120
+ tradeType: TradeType,
121
+ strategyType: GasFeeStrategyType,
122
+ cuLimit: number,
123
+ cuPrice: number,
124
+ tip: number
125
+ ): void {
126
+ // Remove conflicting strategies
127
+ if (strategyType === GasFeeStrategyType.Normal) {
128
+ this.delete(swqosType, tradeType, GasFeeStrategyType.LowTipHighCuPrice);
129
+ this.delete(swqosType, tradeType, GasFeeStrategyType.HighTipLowCuPrice);
130
+ } else {
131
+ this.delete(swqosType, tradeType, GasFeeStrategyType.Normal);
132
+ }
133
+
134
+ const key = this.getKey(swqosType, tradeType, strategyType);
135
+ this.strategies.set(key, { cuLimit, cuPrice, tip });
136
+ }
137
+
138
+ /**
139
+ * Get a specific gas fee strategy
140
+ */
141
+ get(
142
+ swqosType: SwqosType,
143
+ tradeType: TradeType,
144
+ strategyType: GasFeeStrategyType
145
+ ): GasFeeStrategyValue | undefined {
146
+ const key = this.getKey(swqosType, tradeType, strategyType);
147
+ return this.strategies.get(key);
148
+ }
149
+
150
+ /**
151
+ * Delete a specific gas fee strategy
152
+ */
153
+ delete(swqosType: SwqosType, tradeType: TradeType, strategyType: GasFeeStrategyType): void {
154
+ const key = this.getKey(swqosType, tradeType, strategyType);
155
+ this.strategies.delete(key);
156
+ }
157
+
158
+ /**
159
+ * Delete all strategies for a SWQOS type and trade type
160
+ */
161
+ deleteAll(swqosType: SwqosType, tradeType: TradeType): void {
162
+ this.delete(swqosType, tradeType, GasFeeStrategyType.Normal);
163
+ this.delete(swqosType, tradeType, GasFeeStrategyType.LowTipHighCuPrice);
164
+ this.delete(swqosType, tradeType, GasFeeStrategyType.HighTipLowCuPrice);
165
+ }
166
+
167
+ /**
168
+ * Get all strategies for a trade type
169
+ */
170
+ getStrategies(tradeType: TradeType): Array<{
171
+ swqosType: SwqosType;
172
+ strategyType: GasFeeStrategyType;
173
+ value: GasFeeStrategyValue;
174
+ }> {
175
+ const results: Array<{
176
+ swqosType: SwqosType;
177
+ strategyType: GasFeeStrategyType;
178
+ value: GasFeeStrategyValue;
179
+ }> = [];
180
+
181
+ this.strategies.forEach((value, key) => {
182
+ const parsed = this.parseKey(key);
183
+ if (parsed.tradeType === tradeType) {
184
+ results.push({
185
+ swqosType: parsed.swqosType,
186
+ strategyType: parsed.strategyType,
187
+ value,
188
+ });
189
+ }
190
+ });
191
+
192
+ return results;
193
+ }
194
+
195
+ /**
196
+ * Update buy tip for all strategies
197
+ */
198
+ updateBuyTip(buyTip: number): void {
199
+ this.strategies.forEach((value, key) => {
200
+ const parsed = this.parseKey(key);
201
+ if (parsed.tradeType === TradeType.Buy) {
202
+ value.tip = buyTip;
203
+ this.strategies.set(key, value);
204
+ }
205
+ });
206
+ }
207
+
208
+ /**
209
+ * Update sell tip for all strategies
210
+ */
211
+ updateSellTip(sellTip: number): void {
212
+ this.strategies.forEach((value, key) => {
213
+ const parsed = this.parseKey(key);
214
+ if (parsed.tradeType === TradeType.Sell) {
215
+ value.tip = sellTip;
216
+ this.strategies.set(key, value);
217
+ }
218
+ });
219
+ }
220
+
221
+ /**
222
+ * Clear all strategies
223
+ */
224
+ clear(): void {
225
+ this.strategies.clear();
226
+ }
227
+
228
+ private getKey(
229
+ swqosType: SwqosType,
230
+ tradeType: TradeType,
231
+ strategyType: GasFeeStrategyType
232
+ ): string {
233
+ return `${swqosType}:${tradeType}:${strategyType}`;
234
+ }
235
+
236
+ private parseKey(key: string): StrategyKey {
237
+ const [swqosType, tradeType, strategyType] = key.split(':');
238
+ return {
239
+ swqosType: swqosType as SwqosType,
240
+ tradeType: tradeType as TradeType,
241
+ strategyType: strategyType as GasFeeStrategyType,
242
+ };
243
+ }
244
+ }
245
+
246
+ /**
247
+ * Create a new gas fee strategy with defaults
248
+ */
249
+ export function createGasFeeStrategy(): GasFeeStrategy {
250
+ const strategy = new GasFeeStrategy();
251
+ strategy.setGlobalFeeStrategy(200000, 200000, 100000, 100000, 0.001, 0.001);
252
+ return strategy;
253
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Bounded concurrency for async work (Rust SWQOS worker pool parity, best-effort in JS).
3
+ */
4
+
5
+ export async function mapWithConcurrencyLimit<T, R>(
6
+ items: readonly T[],
7
+ concurrency: number,
8
+ fn: (item: T, index: number) => Promise<R>
9
+ ): Promise<R[]> {
10
+ if (items.length === 0) return [];
11
+ const limit = Math.max(1, Math.min(concurrency, items.length));
12
+ const results: R[] = new Array(items.length);
13
+ let next = 0;
14
+ const worker = async () => {
15
+ for (;;) {
16
+ const i = next++;
17
+ if (i >= items.length) return;
18
+ results[i] = await fn(items[i]!, i);
19
+ }
20
+ };
21
+ await Promise.all(Array.from({ length: limit }, () => worker()));
22
+ return results;
23
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Durable nonce helpers — aligned with Rust `src/common/nonce_cache.rs` `fetch_nonce_info`.
3
+ */
4
+
5
+ import { Connection, PublicKey } from '@solana/web3.js';
6
+ import bs58 from 'bs58';
7
+
8
+ /** Same shape as `DurableNonceInfo` in `index.ts` (used for `buy`/`sell` without circular imports). */
9
+ export interface FetchedDurableNonce {
10
+ nonceAccount: PublicKey;
11
+ authority: PublicKey;
12
+ /** Base58-encoded current nonce blockhash (32 bytes), for `recentBlockhash` / `nonceHash`. */
13
+ nonceHash: string;
14
+ /** Duplicate of `nonceHash` for parity with existing `DurableNonceInfo.recentBlockhash`. */
15
+ recentBlockhash: string;
16
+ }
17
+
18
+ /**
19
+ * Fetch durable nonce authority + current blockhash from a nonce account (RPC).
20
+ * Layout matches Rust: version (4) + authority_type (4) + authority (32) + blockhash (32) starting at offset 40.
21
+ */
22
+ export async function fetchDurableNonceInfo(
23
+ connection: Pick<Connection, 'getAccountInfo'>,
24
+ nonceAccount: PublicKey
25
+ ): Promise<FetchedDurableNonce | null> {
26
+ const account = await connection.getAccountInfo(nonceAccount);
27
+ if (!account?.data || account.data.length < 72) {
28
+ return null;
29
+ }
30
+ const data = Buffer.from(account.data);
31
+ const authority = new PublicKey(data.subarray(8, 40));
32
+ const hashBytes = data.subarray(40, 72);
33
+ const nonceHash = bs58.encode(hashBytes);
34
+ return {
35
+ nonceAccount,
36
+ authority,
37
+ nonceHash,
38
+ recentBlockhash: nonceHash,
39
+ };
40
+ }