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.
- package/README.md +390 -0
- package/dist/chunk-MMQAMIKR.mjs +3735 -0
- package/dist/chunk-NEZDFAYA.mjs +7744 -0
- package/dist/clients-VITWK7B6.mjs +1370 -0
- package/dist/index-1BK_FXsW.d.mts +2327 -0
- package/dist/index-1BK_FXsW.d.ts +2327 -0
- package/dist/index.d.mts +2659 -0
- package/dist/index.d.ts +2659 -0
- package/dist/index.js +13265 -0
- package/dist/index.mjs +562 -0
- package/dist/perf/index.d.mts +2 -0
- package/dist/perf/index.d.ts +2 -0
- package/dist/perf/index.js +3742 -0
- package/dist/perf/index.mjs +214 -0
- package/package.json +101 -0
- package/src/__tests__/complete_sdk.test.ts +354 -0
- package/src/__tests__/hotpath.test.ts +486 -0
- package/src/__tests__/nonce.test.ts +45 -0
- package/src/__tests__/sdk.test.ts +425 -0
- package/src/address-lookup/index.ts +197 -0
- package/src/cache/cache.ts +308 -0
- package/src/calc/index.ts +1058 -0
- package/src/calc/pumpfun.ts +124 -0
- package/src/common/bonding_curve.ts +272 -0
- package/src/common/compute-budget.ts +148 -0
- package/src/common/confirm-any-signature.ts +184 -0
- package/src/common/fast-timing.ts +481 -0
- package/src/common/fast_fn.ts +150 -0
- package/src/common/gas-fee-strategy.ts +253 -0
- package/src/common/map-pool.ts +23 -0
- package/src/common/nonce.ts +40 -0
- package/src/common/sdk-log.ts +460 -0
- package/src/common/seed.ts +381 -0
- package/src/common/spl-token.ts +578 -0
- package/src/common/subscription-handle.ts +644 -0
- package/src/common/trading-utils.ts +239 -0
- package/src/common/wsol-manager.ts +325 -0
- package/src/compute/compute_budget_manager.ts +187 -0
- package/src/compute/index.ts +21 -0
- package/src/constants/index.ts +96 -0
- package/src/execution/execution.ts +532 -0
- package/src/execution/index.ts +42 -0
- package/src/hotpath/executor.ts +464 -0
- package/src/hotpath/index.ts +64 -0
- package/src/hotpath/state.ts +435 -0
- package/src/index.ts +2117 -0
- package/src/instruction/bonk_builder.ts +730 -0
- package/src/instruction/index.ts +24 -0
- package/src/instruction/meteora_damm_v2_builder.ts +509 -0
- package/src/instruction/pumpfun_builder.ts +1183 -0
- package/src/instruction/pumpswap.ts +1123 -0
- package/src/instruction/raydium_amm_v4_builder.ts +692 -0
- package/src/instruction/raydium_cpmm_builder.ts +795 -0
- package/src/middleware/traits.ts +407 -0
- package/src/params/index.ts +483 -0
- package/src/perf/compiler-optimization.ts +529 -0
- package/src/perf/hardware.ts +631 -0
- package/src/perf/index.ts +9 -0
- package/src/perf/kernel-bypass.ts +656 -0
- package/src/perf/protocol.ts +682 -0
- package/src/perf/realtime.ts +592 -0
- package/src/perf/simd.ts +668 -0
- package/src/perf/syscall-bypass.ts +331 -0
- package/src/perf/ultra-low-latency.ts +505 -0
- package/src/perf/zero-copy.ts +589 -0
- package/src/pool/pool.ts +294 -0
- package/src/rpc/client.ts +345 -0
- package/src/sdk-errors.ts +13 -0
- package/src/security/index.ts +26 -0
- package/src/security/secure-key.ts +303 -0
- package/src/security/validators.ts +281 -0
- package/src/seed/pda.ts +262 -0
- package/src/serialization/index.ts +28 -0
- package/src/serialization/serialization.ts +288 -0
- package/src/swqos/clients.ts +1754 -0
- package/src/swqos/index.ts +50 -0
- package/src/swqos/providers.ts +1707 -0
- package/src/trading/core/async-executor.ts +702 -0
- package/src/trading/core/confirmation-monitor.ts +711 -0
- package/src/trading/core/index.ts +82 -0
- package/src/trading/core/retry-handler.ts +683 -0
- package/src/trading/core/transaction-pool.ts +780 -0
- package/src/trading/executor.ts +385 -0
- package/src/trading/factory.ts +282 -0
- package/src/trading/index.ts +30 -0
- package/src/types.ts +8 -0
- package/src/utils/index.ts +155 -0
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution: instruction preprocessing, cache prefetch, branch hints.
|
|
3
|
+
* 执行模块:指令预处理、缓存预取、分支提示。
|
|
4
|
+
*
|
|
5
|
+
* Based on sol-trade-sdk Rust implementation patterns.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { PublicKey } from '@solana/web3.js';
|
|
9
|
+
import {
|
|
10
|
+
SOL_TOKEN_ACCOUNT,
|
|
11
|
+
WSOL_TOKEN_ACCOUNT,
|
|
12
|
+
USD1_TOKEN_ACCOUNT,
|
|
13
|
+
USDC_TOKEN_ACCOUNT,
|
|
14
|
+
} from '../constants';
|
|
15
|
+
|
|
16
|
+
// ===== Constants =====
|
|
17
|
+
|
|
18
|
+
export const BYTES_PER_ACCOUNT = 32;
|
|
19
|
+
export const MAX_INSTRUCTIONS_WARN = 64;
|
|
20
|
+
|
|
21
|
+
// ===== Branch Optimization =====
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Branch prediction hints.
|
|
25
|
+
* In JS/TS, we can't control branch prediction, but we structure code
|
|
26
|
+
* to match the Rust patterns.
|
|
27
|
+
*/
|
|
28
|
+
export class BranchOptimizer {
|
|
29
|
+
/**
|
|
30
|
+
* Hint that condition is likely true
|
|
31
|
+
*/
|
|
32
|
+
static likely<T>(condition: boolean, value: T, fallback: T): T {
|
|
33
|
+
return condition ? value : fallback;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Hint that condition is likely false
|
|
38
|
+
*/
|
|
39
|
+
static unlikely<T>(condition: boolean, value: T, fallback: T): T {
|
|
40
|
+
return condition ? value : fallback;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Prefetch read data into cache (no-op in JS, but pattern preserved)
|
|
45
|
+
*/
|
|
46
|
+
static prefetchReadData<T>(data: T): void {
|
|
47
|
+
// Touch the data to potentially load into cache
|
|
48
|
+
// In JS this is a no-op, but the pattern is preserved
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ===== Prefetch Helper =====
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Cache prefetching utilities.
|
|
56
|
+
* Call once on hot-path refs to reduce cache-miss latency.
|
|
57
|
+
*/
|
|
58
|
+
export class Prefetch {
|
|
59
|
+
/**
|
|
60
|
+
* Prefetch instruction data into cache
|
|
61
|
+
* Accepts any instruction-shaped array (Rust: `Prefetch::instructions`).
|
|
62
|
+
*/
|
|
63
|
+
static instructions(instructions: ReadonlyArray<unknown>): void {
|
|
64
|
+
if (instructions.length === 0) return;
|
|
65
|
+
|
|
66
|
+
// Touch first, middle, and last instructions
|
|
67
|
+
void instructions[0];
|
|
68
|
+
if (instructions.length > 2) {
|
|
69
|
+
void instructions[Math.floor(instructions.length / 2)];
|
|
70
|
+
}
|
|
71
|
+
if (instructions.length > 1) {
|
|
72
|
+
void instructions[instructions.length - 1];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Prefetch pubkey into cache
|
|
78
|
+
*/
|
|
79
|
+
static pubkey(pubkey: Uint8Array): void {
|
|
80
|
+
if (pubkey.length > 0) {
|
|
81
|
+
void pubkey[0];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Prefetch keypair data into cache
|
|
87
|
+
*/
|
|
88
|
+
static keypair(keypair: unknown): void {
|
|
89
|
+
// Touch keypair for cache effect
|
|
90
|
+
void keypair;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ===== Memory Operations =====
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* SIMD-accelerated memory operations (where available in JS)
|
|
98
|
+
*/
|
|
99
|
+
export class MemoryOps {
|
|
100
|
+
/**
|
|
101
|
+
* Optimized memory copy using TypedArray
|
|
102
|
+
*/
|
|
103
|
+
static copy(dst: Uint8Array, src: Uint8Array): void {
|
|
104
|
+
dst.set(src);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Optimized memory comparison
|
|
109
|
+
*/
|
|
110
|
+
static compare(a: Uint8Array, b: Uint8Array): boolean {
|
|
111
|
+
if (a.length !== b.length) return false;
|
|
112
|
+
for (let i = 0; i < a.length; i++) {
|
|
113
|
+
if (a[i] !== b[i]) return false;
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Create zeroed memory
|
|
120
|
+
*/
|
|
121
|
+
static zero(size: number): Uint8Array {
|
|
122
|
+
return new Uint8Array(size);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Fast copy with pre-allocated buffer
|
|
127
|
+
*/
|
|
128
|
+
static copyFast(
|
|
129
|
+
dst: Uint8Array,
|
|
130
|
+
dstOffset: number,
|
|
131
|
+
src: Uint8Array
|
|
132
|
+
): void {
|
|
133
|
+
dst.set(src, dstOffset);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ===== Instruction Types =====
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Account metadata for instructions
|
|
141
|
+
*/
|
|
142
|
+
export interface AccountMeta {
|
|
143
|
+
pubkey: Uint8Array;
|
|
144
|
+
isSigner: boolean;
|
|
145
|
+
isWritable: boolean;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Solana instruction
|
|
150
|
+
*/
|
|
151
|
+
export interface Instruction {
|
|
152
|
+
programId: Uint8Array;
|
|
153
|
+
accounts: AccountMeta[];
|
|
154
|
+
data: Uint8Array;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// ===== Instruction Processor =====
|
|
158
|
+
|
|
159
|
+
/** Account metas: web3 `TransactionInstruction.keys` or internal `Instruction.accounts`. */
|
|
160
|
+
function instructionAccountCount(ix: {
|
|
161
|
+
keys?: readonly unknown[];
|
|
162
|
+
accounts?: readonly unknown[];
|
|
163
|
+
}): number {
|
|
164
|
+
if (ix.keys !== undefined) return ix.keys.length;
|
|
165
|
+
if (ix.accounts !== undefined) return ix.accounts.length;
|
|
166
|
+
return 0;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Handles instruction preprocessing and validation.
|
|
171
|
+
* Based on Rust's InstructionProcessor pattern.
|
|
172
|
+
*/
|
|
173
|
+
export class InstructionProcessor {
|
|
174
|
+
/**
|
|
175
|
+
* Validate and prepare instructions for execution.
|
|
176
|
+
* Rust: `InstructionProcessor::preprocess` (empty check, prefetch, warn when count exceeds {@link MAX_INSTRUCTIONS_WARN}).
|
|
177
|
+
*/
|
|
178
|
+
static preprocess(instructions: ReadonlyArray<unknown>): void {
|
|
179
|
+
if (instructions.length === 0) {
|
|
180
|
+
throw new Error('Instructions empty');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
Prefetch.instructions(instructions);
|
|
184
|
+
|
|
185
|
+
if (instructions.length > MAX_INSTRUCTIONS_WARN) {
|
|
186
|
+
console.warn(
|
|
187
|
+
`[sol-trade-sdk] Large instruction count: ${instructions.length}`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Calculate total size for buffer allocation (web3 `keys` or internal `accounts`).
|
|
194
|
+
*/
|
|
195
|
+
static calculateSize(
|
|
196
|
+
instructions: ReadonlyArray<{
|
|
197
|
+
data: { length: number };
|
|
198
|
+
keys?: readonly unknown[];
|
|
199
|
+
accounts?: readonly unknown[];
|
|
200
|
+
}>
|
|
201
|
+
): number {
|
|
202
|
+
let totalSize = 0;
|
|
203
|
+
for (let i = 0; i < instructions.length; i++) {
|
|
204
|
+
if (i + 1 < instructions.length) {
|
|
205
|
+
void instructions[i + 1];
|
|
206
|
+
}
|
|
207
|
+
const ix = instructions[i]!;
|
|
208
|
+
totalSize += ix.data.length;
|
|
209
|
+
totalSize += instructionAccountCount(ix) * BYTES_PER_ACCOUNT;
|
|
210
|
+
}
|
|
211
|
+
return totalSize;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// ===== Execution Path Helpers =====
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Trade direction and execution path utilities
|
|
219
|
+
*/
|
|
220
|
+
export class ExecutionPath {
|
|
221
|
+
/**
|
|
222
|
+
* Rust `ExecutionPath::is_buy`: input mint is quote-side (SOL / WSOL / USD1 / USDC).
|
|
223
|
+
*/
|
|
224
|
+
static isBuy(inputMint: PublicKey): boolean {
|
|
225
|
+
return (
|
|
226
|
+
inputMint.equals(SOL_TOKEN_ACCOUNT) ||
|
|
227
|
+
inputMint.equals(WSOL_TOKEN_ACCOUNT) ||
|
|
228
|
+
inputMint.equals(USD1_TOKEN_ACCOUNT) ||
|
|
229
|
+
inputMint.equals(USDC_TOKEN_ACCOUNT)
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Select between fast and slow path
|
|
235
|
+
*/
|
|
236
|
+
static select<T>(
|
|
237
|
+
condition: boolean,
|
|
238
|
+
fastPath: () => T,
|
|
239
|
+
slowPath: () => T
|
|
240
|
+
): T {
|
|
241
|
+
if (condition) {
|
|
242
|
+
return fastPath();
|
|
243
|
+
}
|
|
244
|
+
return slowPath();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// ===== Transaction Builder Pool =====
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Builds transactions with pre-allocated buffers.
|
|
252
|
+
* Based on Rust's zero-allocation pattern.
|
|
253
|
+
*/
|
|
254
|
+
export class TransactionBuilder {
|
|
255
|
+
private instructions: Instruction[] = [];
|
|
256
|
+
private dataBuffer: Uint8Array;
|
|
257
|
+
private capacity: number;
|
|
258
|
+
|
|
259
|
+
constructor(initialSize: number = 10) {
|
|
260
|
+
this.capacity = initialSize;
|
|
261
|
+
this.dataBuffer = new Uint8Array(1024);
|
|
262
|
+
this.reset();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Reset for reuse
|
|
267
|
+
*/
|
|
268
|
+
reset(): void {
|
|
269
|
+
this.instructions = [];
|
|
270
|
+
this.dataBuffer.fill(0);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Add instruction
|
|
275
|
+
*/
|
|
276
|
+
addInstruction(instr: Instruction): void {
|
|
277
|
+
this.instructions.push(instr);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Build final transaction bytes
|
|
282
|
+
*/
|
|
283
|
+
build(payer: Uint8Array, blockhash: Uint8Array): Uint8Array {
|
|
284
|
+
// Calculate total size
|
|
285
|
+
const size = InstructionProcessor.calculateSize(this.instructions);
|
|
286
|
+
const result = new Uint8Array(64 + size); // payer + blockhash + data
|
|
287
|
+
|
|
288
|
+
let offset = 0;
|
|
289
|
+
result.set(payer, offset);
|
|
290
|
+
offset += 32;
|
|
291
|
+
result.set(blockhash, offset);
|
|
292
|
+
offset += 32;
|
|
293
|
+
|
|
294
|
+
for (const instr of this.instructions) {
|
|
295
|
+
result.set(instr.data, offset);
|
|
296
|
+
offset += instr.data.length;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return result.slice(0, offset);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Manages pre-allocated transaction builders.
|
|
305
|
+
* Based on Rust's acquire_builder/release_builder pattern.
|
|
306
|
+
*/
|
|
307
|
+
export class TransactionBuilderPool {
|
|
308
|
+
private pool: TransactionBuilder[] = [];
|
|
309
|
+
private maxSize: number;
|
|
310
|
+
private builderSize: number;
|
|
311
|
+
|
|
312
|
+
constructor(poolSize: number = 10, builderSize: number = 10) {
|
|
313
|
+
this.maxSize = poolSize;
|
|
314
|
+
this.builderSize = builderSize;
|
|
315
|
+
|
|
316
|
+
// Pre-populate pool
|
|
317
|
+
for (let i = 0; i < poolSize; i++) {
|
|
318
|
+
this.pool.push(new TransactionBuilder(builderSize));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Get a builder from the pool
|
|
324
|
+
*/
|
|
325
|
+
acquire(): TransactionBuilder {
|
|
326
|
+
if (this.pool.length > 0) {
|
|
327
|
+
return this.pool.pop()!;
|
|
328
|
+
}
|
|
329
|
+
return new TransactionBuilder(this.builderSize);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Return a builder to the pool
|
|
334
|
+
*/
|
|
335
|
+
release(builder: TransactionBuilder): void {
|
|
336
|
+
builder.reset();
|
|
337
|
+
if (this.pool.length < this.maxSize) {
|
|
338
|
+
this.pool.push(builder);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// ===== Ultra Low Latency Stats =====
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Tracks nanosecond-level latency statistics.
|
|
347
|
+
* Uses Atomics for thread-safety in Worker contexts.
|
|
348
|
+
*/
|
|
349
|
+
export class UltraLowLatencyStats {
|
|
350
|
+
private stats: {
|
|
351
|
+
eventsProcessed: Int32Array;
|
|
352
|
+
totalLatencyNs: BigInt64Array;
|
|
353
|
+
minLatencyNs: BigInt64Array;
|
|
354
|
+
maxLatencyNs: BigInt64Array;
|
|
355
|
+
subMillisecondEvents: Int32Array;
|
|
356
|
+
ultraFastEvents: Int32Array;
|
|
357
|
+
lightningFastEvents: Int32Array;
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
constructor() {
|
|
361
|
+
this.stats = {
|
|
362
|
+
eventsProcessed: new Int32Array(new SharedArrayBuffer(4)),
|
|
363
|
+
totalLatencyNs: new BigInt64Array(new SharedArrayBuffer(8)),
|
|
364
|
+
minLatencyNs: new BigInt64Array(new SharedArrayBuffer(8)),
|
|
365
|
+
maxLatencyNs: new BigInt64Array(new SharedArrayBuffer(8)),
|
|
366
|
+
subMillisecondEvents: new Int32Array(new SharedArrayBuffer(4)),
|
|
367
|
+
ultraFastEvents: new Int32Array(new SharedArrayBuffer(4)),
|
|
368
|
+
lightningFastEvents: new Int32Array(new SharedArrayBuffer(4)),
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
// Initialize min to max
|
|
372
|
+
Atomics.store(this.stats.minLatencyNs, 0, BigInt(Number.MAX_SAFE_INTEGER));
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Record a latency measurement
|
|
377
|
+
*/
|
|
378
|
+
record(latencyNs: bigint): void {
|
|
379
|
+
Atomics.add(this.stats.eventsProcessed, 0, 1);
|
|
380
|
+
Atomics.add(this.stats.totalLatencyNs, 0, latencyNs);
|
|
381
|
+
|
|
382
|
+
// Update min
|
|
383
|
+
let current = Atomics.load(this.stats.minLatencyNs, 0);
|
|
384
|
+
while (latencyNs < current) {
|
|
385
|
+
if (Atomics.compareExchange(this.stats.minLatencyNs, 0, current, latencyNs) === current) {
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
current = Atomics.load(this.stats.minLatencyNs, 0);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Update max
|
|
392
|
+
current = Atomics.load(this.stats.maxLatencyNs, 0);
|
|
393
|
+
while (latencyNs > current) {
|
|
394
|
+
if (Atomics.compareExchange(this.stats.maxLatencyNs, 0, current, latencyNs) === current) {
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
current = Atomics.load(this.stats.maxLatencyNs, 0);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Classify latency
|
|
401
|
+
if (latencyNs < BigInt(1_000_000)) {
|
|
402
|
+
Atomics.add(this.stats.subMillisecondEvents, 0, 1);
|
|
403
|
+
}
|
|
404
|
+
if (latencyNs < BigInt(100_000)) {
|
|
405
|
+
Atomics.add(this.stats.ultraFastEvents, 0, 1);
|
|
406
|
+
}
|
|
407
|
+
if (latencyNs < BigInt(10_000)) {
|
|
408
|
+
Atomics.add(this.stats.lightningFastEvents, 0, 1);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Get all statistics
|
|
414
|
+
*/
|
|
415
|
+
getStats(): {
|
|
416
|
+
eventsProcessed: number;
|
|
417
|
+
totalLatencyNs: bigint;
|
|
418
|
+
minLatencyNs: bigint;
|
|
419
|
+
maxLatencyNs: bigint;
|
|
420
|
+
avgLatencyNs: number;
|
|
421
|
+
subMillisecondEvents: number;
|
|
422
|
+
ultraFastEvents: number;
|
|
423
|
+
lightningFastEvents: number;
|
|
424
|
+
} {
|
|
425
|
+
const eventsProcessed = Atomics.load(this.stats.eventsProcessed, 0);
|
|
426
|
+
const totalLatencyNs = Atomics.load(this.stats.totalLatencyNs, 0);
|
|
427
|
+
const minLatencyNs = Atomics.load(this.stats.minLatencyNs, 0);
|
|
428
|
+
const maxLatencyNs = Atomics.load(this.stats.maxLatencyNs, 0);
|
|
429
|
+
|
|
430
|
+
const avgLatencyNs =
|
|
431
|
+
eventsProcessed > 0 ? Number(totalLatencyNs) / eventsProcessed : 0;
|
|
432
|
+
|
|
433
|
+
return {
|
|
434
|
+
eventsProcessed,
|
|
435
|
+
totalLatencyNs,
|
|
436
|
+
minLatencyNs: eventsProcessed > 0 ? minLatencyNs : BigInt(0),
|
|
437
|
+
maxLatencyNs,
|
|
438
|
+
avgLatencyNs,
|
|
439
|
+
subMillisecondEvents: Atomics.load(this.stats.subMillisecondEvents, 0),
|
|
440
|
+
ultraFastEvents: Atomics.load(this.stats.ultraFastEvents, 0),
|
|
441
|
+
lightningFastEvents: Atomics.load(this.stats.lightningFastEvents, 0),
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// ===== DexParamEnum (Zero-cost abstraction pattern) =====
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Base interface for DEX parameters
|
|
450
|
+
*/
|
|
451
|
+
export interface DexParam {
|
|
452
|
+
readonly type: string;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* PumpFun protocol parameters
|
|
457
|
+
*/
|
|
458
|
+
export interface PumpFunParams extends DexParam {
|
|
459
|
+
readonly type: 'PumpFun';
|
|
460
|
+
bondingCurve: Uint8Array;
|
|
461
|
+
associatedBondingCurve: Uint8Array;
|
|
462
|
+
creatorVault: Uint8Array;
|
|
463
|
+
tokenProgram: Uint8Array;
|
|
464
|
+
closeTokenAccountWhenSell?: boolean;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* PumpSwap protocol parameters
|
|
469
|
+
*/
|
|
470
|
+
export interface PumpSwapParams extends DexParam {
|
|
471
|
+
readonly type: 'PumpSwap';
|
|
472
|
+
pool: Uint8Array;
|
|
473
|
+
baseMint: Uint8Array;
|
|
474
|
+
quoteMint: Uint8Array;
|
|
475
|
+
poolBaseTokenAccount: Uint8Array;
|
|
476
|
+
poolQuoteTokenAccount: Uint8Array;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Raydium CPMM protocol parameters
|
|
481
|
+
*/
|
|
482
|
+
export interface RaydiumCpmmParams extends DexParam {
|
|
483
|
+
readonly type: 'RaydiumCpmm';
|
|
484
|
+
poolState: Uint8Array;
|
|
485
|
+
ammConfig: Uint8Array;
|
|
486
|
+
baseMint: Uint8Array;
|
|
487
|
+
quoteMint: Uint8Array;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Meteora DAMM v2 protocol parameters
|
|
492
|
+
*/
|
|
493
|
+
export interface MeteoraDammV2Params extends DexParam {
|
|
494
|
+
readonly type: 'MeteoraDammV2';
|
|
495
|
+
pool: Uint8Array;
|
|
496
|
+
tokenAVault: Uint8Array;
|
|
497
|
+
tokenBVault: Uint8Array;
|
|
498
|
+
tokenAMint: Uint8Array;
|
|
499
|
+
tokenBMint: Uint8Array;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Union type for DEX parameters (zero-cost abstraction like Rust enum)
|
|
504
|
+
*/
|
|
505
|
+
export type DexParamEnum =
|
|
506
|
+
| PumpFunParams
|
|
507
|
+
| PumpSwapParams
|
|
508
|
+
| RaydiumCpmmParams
|
|
509
|
+
| MeteoraDammV2Params;
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Type guards for DEX params
|
|
513
|
+
*/
|
|
514
|
+
export function isPumpFunParams(param: DexParamEnum): param is PumpFunParams {
|
|
515
|
+
return param.type === 'PumpFun';
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
export function isPumpSwapParams(param: DexParamEnum): param is PumpSwapParams {
|
|
519
|
+
return param.type === 'PumpSwap';
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
export function isRaydiumCpmmParams(
|
|
523
|
+
param: DexParamEnum
|
|
524
|
+
): param is RaydiumCpmmParams {
|
|
525
|
+
return param.type === 'RaydiumCpmm';
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
export function isMeteoraDammV2Params(
|
|
529
|
+
param: DexParamEnum
|
|
530
|
+
): param is MeteoraDammV2Params {
|
|
531
|
+
return param.type === 'MeteoraDammV2';
|
|
532
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution Module for Sol Trade SDK
|
|
3
|
+
*
|
|
4
|
+
* Provides optimized execution patterns based on Rust sol-trade-sdk:
|
|
5
|
+
* - Branch optimization hints
|
|
6
|
+
* - Cache prefetching
|
|
7
|
+
* - Memory operations
|
|
8
|
+
* - Instruction processing
|
|
9
|
+
* - Transaction builder pool
|
|
10
|
+
* - Ultra low latency stats
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
BYTES_PER_ACCOUNT,
|
|
15
|
+
MAX_INSTRUCTIONS_WARN,
|
|
16
|
+
BranchOptimizer,
|
|
17
|
+
Prefetch,
|
|
18
|
+
MemoryOps,
|
|
19
|
+
InstructionProcessor,
|
|
20
|
+
ExecutionPath,
|
|
21
|
+
TransactionBuilder,
|
|
22
|
+
TransactionBuilderPool,
|
|
23
|
+
UltraLowLatencyStats,
|
|
24
|
+
} from './execution';
|
|
25
|
+
|
|
26
|
+
export type {
|
|
27
|
+
AccountMeta,
|
|
28
|
+
Instruction,
|
|
29
|
+
DexParam,
|
|
30
|
+
PumpFunParams,
|
|
31
|
+
PumpSwapParams,
|
|
32
|
+
RaydiumCpmmParams,
|
|
33
|
+
MeteoraDammV2Params,
|
|
34
|
+
DexParamEnum,
|
|
35
|
+
} from './execution';
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
isPumpFunParams,
|
|
39
|
+
isPumpSwapParams,
|
|
40
|
+
isRaydiumCpmmParams,
|
|
41
|
+
isMeteoraDammV2Params,
|
|
42
|
+
} from './execution';
|