sol-parser-sdk-nodejs 0.4.0 → 0.5.5

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 (74) hide show
  1. package/README.md +22 -4
  2. package/README_CN.md +22 -4
  3. package/dist/accounts/mod.d.ts +1 -0
  4. package/dist/accounts/mod.js +53 -6
  5. package/dist/accounts/pumpfun.d.ts +16 -0
  6. package/dist/accounts/pumpfun.js +538 -0
  7. package/dist/accounts/rust_aliases.d.ts +1 -0
  8. package/dist/accounts/rust_aliases.js +3 -1
  9. package/dist/core/account_dispatcher_rpc.js +5 -26
  10. package/dist/core/account_fill_meteora.d.ts +1 -2
  11. package/dist/core/account_fill_meteora.js +0 -2
  12. package/dist/core/account_fill_pumpfun.js +92 -13
  13. package/dist/core/account_fill_pumpswap.js +50 -0
  14. package/dist/core/account_fill_raydium_launchlab.d.ts +4 -0
  15. package/dist/core/account_fill_raydium_launchlab.js +20 -0
  16. package/dist/core/dex_event.d.ts +283 -17
  17. package/dist/core/pumpfun_fee_enrich.d.ts +5 -0
  18. package/dist/core/pumpfun_fee_enrich.js +131 -0
  19. package/dist/core/unified_parser.js +2 -0
  20. package/dist/grpc/client.d.ts +26 -1
  21. package/dist/grpc/client.js +279 -0
  22. package/dist/grpc/log_instr_dedup.d.ts +2 -0
  23. package/dist/grpc/log_instr_dedup.js +378 -0
  24. package/dist/grpc/order_buffer.d.ts +27 -0
  25. package/dist/grpc/order_buffer.js +166 -0
  26. package/dist/grpc/program_ids.d.ts +5 -3
  27. package/dist/grpc/program_ids.js +12 -5
  28. package/dist/grpc/types.d.ts +17 -6
  29. package/dist/grpc/types.js +265 -153
  30. package/dist/grpc/yellowstone_parse.d.ts +3 -1
  31. package/dist/grpc/yellowstone_parse.js +13 -10
  32. package/dist/index.d.ts +9 -7
  33. package/dist/index.js +33 -7
  34. package/dist/instr/meteora_damm_ix.js +4 -1
  35. package/dist/instr/meteora_dlmm_ix.d.ts +2 -0
  36. package/dist/instr/meteora_dlmm_ix.js +134 -0
  37. package/dist/instr/meteora_pools_ix.d.ts +2 -0
  38. package/dist/instr/meteora_pools_ix.js +78 -0
  39. package/dist/instr/mod.d.ts +4 -1
  40. package/dist/instr/mod.js +45 -18
  41. package/dist/instr/program_ids.d.ts +1 -5
  42. package/dist/instr/program_ids.js +4 -6
  43. package/dist/instr/pump_fees_ix.d.ts +2 -0
  44. package/dist/instr/pump_fees_ix.js +166 -0
  45. package/dist/instr/pumpfun_ix.js +272 -1
  46. package/dist/instr/pumpswap_ix.js +36 -2
  47. package/dist/instr/raydium_clmm_ix.js +73 -52
  48. package/dist/instr/raydium_launchlab_ix.d.ts +8 -0
  49. package/dist/instr/raydium_launchlab_ix.js +125 -0
  50. package/dist/instr/rust_aliases.d.ts +3 -0
  51. package/dist/instr/rust_aliases.js +7 -1
  52. package/dist/logs/discriminator_lut.d.ts +1 -1
  53. package/dist/logs/discriminator_lut.js +2 -0
  54. package/dist/logs/optimized_matcher.js +130 -25
  55. package/dist/logs/program_log_discriminators.d.ts +10 -0
  56. package/dist/logs/program_log_discriminators.js +10 -0
  57. package/dist/logs/pump.d.ts +2 -0
  58. package/dist/logs/pump.js +122 -2
  59. package/dist/logs/pump_amm.js +1 -1
  60. package/dist/logs/pump_fees.d.ts +23 -0
  61. package/dist/logs/pump_fees.js +364 -0
  62. package/dist/logs/raydium_launchlab.d.ts +10 -0
  63. package/dist/logs/raydium_launchlab.js +84 -0
  64. package/dist/rpc_transaction.d.ts +2 -0
  65. package/dist/rpc_transaction.js +14 -6
  66. package/dist/shredstream/client.d.ts +4 -1
  67. package/dist/shredstream/client.js +18 -14
  68. package/dist/shredstream/index.d.ts +1 -1
  69. package/dist/shredstream/index.js +1 -1
  70. package/dist/shredstream/instruction_parse.d.ts +3 -3
  71. package/dist/shredstream/instruction_parse.js +38 -13
  72. package/dist/util/market.d.ts +18 -0
  73. package/dist/util/market.js +54 -0
  74. package/package.json +1 -1
@@ -0,0 +1,378 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dedupeLogInstructionEvents = dedupeLogInstructionEvents;
4
+ const dex_event_js_1 = require("../core/dex_event.js");
5
+ const ZERO = (0, dex_event_js_1.defaultPubkey)();
6
+ const PUMPFUN_TRADE_NAMES = new Set([
7
+ "PumpFunTrade",
8
+ "PumpFunBuy",
9
+ "PumpFunSell",
10
+ "PumpFunBuyExactSolIn",
11
+ ]);
12
+ function eventName(ev) {
13
+ return Object.keys(ev)[0] ?? "";
14
+ }
15
+ function payload(ev) {
16
+ const key = eventName(ev);
17
+ return key ? ev[key] : null;
18
+ }
19
+ function isDefaultPubkey(v) {
20
+ return v === "" || v === ZERO || v == null;
21
+ }
22
+ function fillString(to, key, from) {
23
+ const value = from[key];
24
+ if (isDefaultPubkey(to[key]) && !isDefaultPubkey(value)) {
25
+ to[key] = value;
26
+ }
27
+ }
28
+ function fillNonZero(to, key, from) {
29
+ const value = from[key];
30
+ if ((to[key] == null || to[key] === 0n || to[key] === 0) && value != null && value !== 0n && value !== 0) {
31
+ to[key] = value;
32
+ }
33
+ }
34
+ function fillNestedString(to, parent, key, from) {
35
+ const srcParent = from[parent];
36
+ if (!srcParent || typeof srcParent !== "object")
37
+ return;
38
+ if (!to[parent] || typeof to[parent] !== "object")
39
+ to[parent] = {};
40
+ fillString(to[parent], key, srcParent);
41
+ }
42
+ function fillIxName(to, from) {
43
+ if ((to.ix_name ?? "") === "" && (from.ix_name ?? "") !== "") {
44
+ to.ix_name = from.ix_name;
45
+ }
46
+ }
47
+ function ixLane(ixName) {
48
+ switch (ixName) {
49
+ case "sell":
50
+ case "sell_v2":
51
+ return 1;
52
+ case "buy_exact_sol_in":
53
+ case "buy_exact_quote_in":
54
+ case "buy_exact_quote_in_v2":
55
+ return 2;
56
+ default:
57
+ return 0;
58
+ }
59
+ }
60
+ function nextOccurrence(base, counts) {
61
+ const current = counts.get(base) ?? 0;
62
+ counts.set(base, current + 1);
63
+ return current;
64
+ }
65
+ function dedupeKey(ev, pumpfunLaneCounts) {
66
+ const name = eventName(ev);
67
+ const data = payload(ev);
68
+ if (!data)
69
+ return null;
70
+ if (PUMPFUN_TRADE_NAMES.has(name)) {
71
+ const lane = ixLane(data.ix_name);
72
+ const base = `${data.mint}|${data.user}|${Boolean(data.is_buy)}|${lane}`;
73
+ const occurrence = nextOccurrence(base, pumpfunLaneCounts);
74
+ return `PumpFunTrade|${base}|${occurrence}`;
75
+ }
76
+ switch (name) {
77
+ case "PumpFunCreate":
78
+ return `PumpFunCreate|${data.mint}`;
79
+ case "PumpFunCreateV2":
80
+ return `PumpFunCreateV2|${data.mint}`;
81
+ case "PumpFunMigrate":
82
+ return `PumpFunMigrate|${data.mint}|${data.pool}|${data.user}`;
83
+ case "RaydiumLaunchlabTrade":
84
+ return `RaydiumLaunchlabTrade|${data.pool_state}|${data.user}|${Boolean(data.is_buy)}`;
85
+ case "RaydiumLaunchlabPoolCreate":
86
+ return `RaydiumLaunchlabPoolCreate|${data.pool_state}`;
87
+ case "RaydiumLaunchlabMigrateAmm":
88
+ return `RaydiumLaunchlabMigrateAmm|${data.old_pool}|${data.new_pool}|${data.user}`;
89
+ case "PumpSwapTrade":
90
+ return `PumpSwapTrade|${data.mint}|${data.user}|${Boolean(data.is_buy)}|${ixLane(data.ix_name)}`;
91
+ case "PumpSwapBuy":
92
+ return `PumpSwapBuy|${data.pool}|${data.user}`;
93
+ case "PumpSwapSell":
94
+ return `PumpSwapSell|${data.pool}|${data.user}`;
95
+ case "PumpSwapCreatePool":
96
+ return `PumpSwapCreatePool|${data.pool}|${data.base_mint}|${data.quote_mint}`;
97
+ case "PumpSwapLiquidityAdded":
98
+ return `PumpSwapLiquidityAdded|${data.pool}|${data.user}`;
99
+ case "PumpSwapLiquidityRemoved":
100
+ return `PumpSwapLiquidityRemoved|${data.pool}|${data.user}`;
101
+ case "RaydiumClmmSwap":
102
+ return `RaydiumClmmSwap|${data.pool_state}|${Boolean(data.zero_for_one)}`;
103
+ case "RaydiumAmmV4Swap":
104
+ return `RaydiumAmmV4Swap|${data.amm}`;
105
+ case "MeteoraDlmmSwap":
106
+ return `MeteoraDlmmSwap|${data.pool}|${data.from}|${Boolean(data.swap_for_y)}`;
107
+ default:
108
+ return null;
109
+ }
110
+ }
111
+ function mergePumpfunTrade(log, ix) {
112
+ for (const key of [
113
+ "bonding_curve",
114
+ "bonding_curve_v2",
115
+ "associated_bonding_curve",
116
+ "associated_user",
117
+ "system_program",
118
+ "token_program",
119
+ "quote_token_program",
120
+ "associated_token_program",
121
+ "creator_vault",
122
+ "fee_recipient",
123
+ "associated_quote_fee_recipient",
124
+ "buyback_fee_recipient",
125
+ "associated_quote_buyback_fee_recipient",
126
+ "associated_quote_bonding_curve",
127
+ "associated_quote_user",
128
+ "associated_creator_vault",
129
+ "sharing_config",
130
+ "event_authority",
131
+ "program",
132
+ "global_volume_accumulator",
133
+ "user_volume_accumulator",
134
+ "associated_user_volume_accumulator",
135
+ "fee_config",
136
+ "fee_program",
137
+ "global",
138
+ "quote_mint",
139
+ "creator",
140
+ ]) {
141
+ fillString(log, key, ix);
142
+ }
143
+ if (log.account == null && ix.account != null)
144
+ log.account = ix.account;
145
+ for (const key of [
146
+ "amount",
147
+ "max_sol_cost",
148
+ "min_sol_output",
149
+ "spendable_sol_in",
150
+ "spendable_quote_in",
151
+ "min_tokens_out",
152
+ "quote_amount",
153
+ "virtual_quote_reserves",
154
+ "real_quote_reserves",
155
+ ]) {
156
+ fillNonZero(log, key, ix);
157
+ }
158
+ fillIxName(log, ix);
159
+ log.is_created_buy = Boolean(log.is_created_buy) || Boolean(ix.is_created_buy);
160
+ }
161
+ function mergePumpfunCreate(log, ix) {
162
+ for (const key of [
163
+ "name",
164
+ "symbol",
165
+ "uri",
166
+ "bonding_curve",
167
+ "user",
168
+ "creator",
169
+ "token_program",
170
+ "quote_mint",
171
+ ]) {
172
+ fillString(log, key, ix);
173
+ }
174
+ fillNonZero(log, "virtual_quote_reserves", ix);
175
+ }
176
+ function mergePumpfunCreateV2(log, ix) {
177
+ mergePumpfunCreate(log, ix);
178
+ for (const key of [
179
+ "mint_authority",
180
+ "associated_bonding_curve",
181
+ "global",
182
+ "system_program",
183
+ "associated_token_program",
184
+ "mayhem_program_id",
185
+ "global_params",
186
+ "sol_vault",
187
+ "mayhem_state",
188
+ "mayhem_token_vault",
189
+ "event_authority",
190
+ "program",
191
+ "observed_fee_recipient",
192
+ ]) {
193
+ fillString(log, key, ix);
194
+ }
195
+ }
196
+ function mergePumpfunMigrate(log, ix) {
197
+ for (const key of ["bonding_curve", "pool", "user"]) {
198
+ fillString(log, key, ix);
199
+ }
200
+ }
201
+ function mergePumpSwapBuySell(log, ix, includeIxName) {
202
+ for (const key of [
203
+ "user_base_token_account",
204
+ "user_quote_token_account",
205
+ "protocol_fee_recipient",
206
+ "protocol_fee_recipient_token_account",
207
+ "coin_creator",
208
+ "base_mint",
209
+ "quote_mint",
210
+ "pool_base_token_account",
211
+ "pool_quote_token_account",
212
+ "coin_creator_vault_ata",
213
+ "coin_creator_vault_authority",
214
+ "base_token_program",
215
+ "quote_token_program",
216
+ "pool_v2",
217
+ "fee_recipient",
218
+ "fee_recipient_quote_token_account",
219
+ ]) {
220
+ fillString(log, key, ix);
221
+ }
222
+ if (includeIxName)
223
+ fillIxName(log, ix);
224
+ }
225
+ function mergePumpSwapCreatePool(log, ix) {
226
+ for (const key of [
227
+ "creator",
228
+ "pool",
229
+ "lp_mint",
230
+ "user_base_token_account",
231
+ "user_quote_token_account",
232
+ "coin_creator",
233
+ ]) {
234
+ fillString(log, key, ix);
235
+ }
236
+ }
237
+ function mergePumpSwapLiquidity(log, ix) {
238
+ for (const key of [
239
+ "user_base_token_account",
240
+ "user_quote_token_account",
241
+ "user_pool_token_account",
242
+ ]) {
243
+ fillString(log, key, ix);
244
+ }
245
+ }
246
+ function mergeRaydiumClmmSwap(log, ix) {
247
+ for (const key of ["token_account_0", "token_account_1", "sender"]) {
248
+ fillString(log, key, ix);
249
+ }
250
+ }
251
+ function mergeRaydiumAmmV4Swap(log, ix) {
252
+ for (const key of [
253
+ "token_program",
254
+ "amm_authority",
255
+ "amm_open_orders",
256
+ "amm_target_orders",
257
+ "pool_coin_token_account",
258
+ "pool_pc_token_account",
259
+ "serum_program",
260
+ "serum_market",
261
+ "serum_bids",
262
+ "serum_asks",
263
+ "serum_event_queue",
264
+ "serum_coin_vault_account",
265
+ "serum_pc_vault_account",
266
+ "serum_vault_signer",
267
+ "user_source_token_account",
268
+ "user_destination_token_account",
269
+ ]) {
270
+ fillString(log, key, ix);
271
+ }
272
+ }
273
+ function mergeRaydiumLaunchlabPoolCreate(log, ix) {
274
+ fillString(log, "creator", ix);
275
+ for (const key of ["name", "symbol", "uri"]) {
276
+ fillNestedString(log, "base_mint_param", key, ix);
277
+ }
278
+ }
279
+ function mergeRaydiumLaunchlabMigrateAmm(log, ix) {
280
+ for (const key of ["old_pool", "new_pool", "user"]) {
281
+ fillString(log, key, ix);
282
+ }
283
+ }
284
+ function mergeGrpcInstructionIntoLog(logEvent, ixEvent) {
285
+ const logName = eventName(logEvent);
286
+ const ixName = eventName(ixEvent);
287
+ const log = payload(logEvent);
288
+ const ix = payload(ixEvent);
289
+ if (!log || !ix)
290
+ return;
291
+ if (PUMPFUN_TRADE_NAMES.has(logName) && PUMPFUN_TRADE_NAMES.has(ixName)) {
292
+ mergePumpfunTrade(log, ix);
293
+ return;
294
+ }
295
+ switch (logName) {
296
+ case "PumpFunCreate":
297
+ if (ixName === "PumpFunCreate")
298
+ mergePumpfunCreate(log, ix);
299
+ break;
300
+ case "PumpFunCreateV2":
301
+ if (ixName === "PumpFunCreateV2")
302
+ mergePumpfunCreateV2(log, ix);
303
+ break;
304
+ case "PumpFunMigrate":
305
+ if (ixName === "PumpFunMigrate")
306
+ mergePumpfunMigrate(log, ix);
307
+ break;
308
+ case "PumpSwapTrade":
309
+ if (ixName === "PumpSwapTrade")
310
+ fillIxName(log, ix);
311
+ break;
312
+ case "PumpSwapBuy":
313
+ if (ixName === "PumpSwapBuy")
314
+ mergePumpSwapBuySell(log, ix, true);
315
+ break;
316
+ case "PumpSwapSell":
317
+ if (ixName === "PumpSwapSell")
318
+ mergePumpSwapBuySell(log, ix, false);
319
+ break;
320
+ case "PumpSwapCreatePool":
321
+ if (ixName === "PumpSwapCreatePool")
322
+ mergePumpSwapCreatePool(log, ix);
323
+ break;
324
+ case "PumpSwapLiquidityAdded":
325
+ if (ixName === "PumpSwapLiquidityAdded")
326
+ mergePumpSwapLiquidity(log, ix);
327
+ break;
328
+ case "PumpSwapLiquidityRemoved":
329
+ if (ixName === "PumpSwapLiquidityRemoved")
330
+ mergePumpSwapLiquidity(log, ix);
331
+ break;
332
+ case "RaydiumClmmSwap":
333
+ if (ixName === "RaydiumClmmSwap")
334
+ mergeRaydiumClmmSwap(log, ix);
335
+ break;
336
+ case "RaydiumAmmV4Swap":
337
+ if (ixName === "RaydiumAmmV4Swap")
338
+ mergeRaydiumAmmV4Swap(log, ix);
339
+ break;
340
+ case "RaydiumLaunchlabPoolCreate":
341
+ if (ixName === "RaydiumLaunchlabPoolCreate")
342
+ mergeRaydiumLaunchlabPoolCreate(log, ix);
343
+ break;
344
+ case "RaydiumLaunchlabMigrateAmm":
345
+ if (ixName === "RaydiumLaunchlabMigrateAmm")
346
+ mergeRaydiumLaunchlabMigrateAmm(log, ix);
347
+ break;
348
+ default:
349
+ break;
350
+ }
351
+ }
352
+ function dedupeLogInstructionEvents(logEvents, instructionEvents) {
353
+ const out = [];
354
+ const indexByKey = new Map();
355
+ const logPumpfunLaneCounts = new Map();
356
+ const ixPumpfunLaneCounts = new Map();
357
+ for (const ev of logEvents) {
358
+ const key = dedupeKey(ev, logPumpfunLaneCounts);
359
+ if (key)
360
+ indexByKey.set(key, out.length);
361
+ out.push(ev);
362
+ }
363
+ for (const ev of instructionEvents) {
364
+ const key = dedupeKey(ev, ixPumpfunLaneCounts);
365
+ if (!key) {
366
+ out.push(ev);
367
+ continue;
368
+ }
369
+ const existing = indexByKey.get(key);
370
+ if (existing === undefined) {
371
+ indexByKey.set(key, out.length);
372
+ out.push(ev);
373
+ continue;
374
+ }
375
+ mergeGrpcInstructionIntoLog(out[existing], ev);
376
+ }
377
+ return out;
378
+ }
@@ -0,0 +1,27 @@
1
+ import type { DexEvent } from "../core/dex_event.js";
2
+ import type { ClientConfig } from "./types.js";
3
+ export declare class OrderDispatcher {
4
+ private readonly mode;
5
+ private readonly timeoutMs;
6
+ private readonly microBatchUs;
7
+ private readonly slots;
8
+ private readonly streamingWatermarks;
9
+ private microBatch;
10
+ private microBatchStartUs;
11
+ private lastFlushMs;
12
+ private currentSlot;
13
+ private seq;
14
+ constructor(config: ClientConfig);
15
+ get needsTimer(): boolean;
16
+ pushTransactionEvents(events: DexEvent[], fallbackSlot: number, fallbackTxIndex: number, emit: (event: DexEvent) => void): void;
17
+ flushDue(emit: (event: DexEvent) => void): void;
18
+ flushAll(emit: (event: DexEvent) => void): void;
19
+ private pushOrdered;
20
+ private pushStreaming;
21
+ private pushMicroBatch;
22
+ private pushSlotBatch;
23
+ private flushBefore;
24
+ private flushAllSlots;
25
+ private flushMicroBatch;
26
+ private emitBatch;
27
+ }
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OrderDispatcher = void 0;
4
+ const dex_event_js_1 = require("../core/dex_event.js");
5
+ function eventSlotAndIndex(events, fallbackSlot, fallbackTxIndex) {
6
+ const meta = events.length > 0 ? (0, dex_event_js_1.metadataForDexEvent)(events[0]) : null;
7
+ return {
8
+ slot: Number.isFinite(meta?.slot) ? meta.slot : fallbackSlot,
9
+ txIndex: Number.isFinite(meta?.tx_index) ? meta.tx_index : fallbackTxIndex,
10
+ };
11
+ }
12
+ class OrderDispatcher {
13
+ mode;
14
+ timeoutMs;
15
+ microBatchUs;
16
+ slots = new Map();
17
+ streamingWatermarks = new Map();
18
+ microBatch = [];
19
+ microBatchStartUs = 0;
20
+ lastFlushMs = Date.now();
21
+ currentSlot = 0;
22
+ seq = 0;
23
+ constructor(config) {
24
+ this.mode = config.order_mode;
25
+ this.timeoutMs = Math.max(1, config.order_timeout_ms || 100);
26
+ this.microBatchUs = Math.max(1, config.micro_batch_us || 100);
27
+ }
28
+ get needsTimer() {
29
+ return this.mode !== "Unordered";
30
+ }
31
+ pushTransactionEvents(events, fallbackSlot, fallbackTxIndex, emit) {
32
+ if (events.length === 0)
33
+ return;
34
+ const { slot, txIndex } = eventSlotAndIndex(events, fallbackSlot, fallbackTxIndex);
35
+ const batch = { slot, txIndex, seq: this.seq++, events };
36
+ switch (this.mode) {
37
+ case "Unordered":
38
+ this.emitBatch(batch, emit);
39
+ return;
40
+ case "Ordered":
41
+ this.pushOrdered(batch, emit);
42
+ return;
43
+ case "StreamingOrdered":
44
+ this.pushStreaming(batch, emit);
45
+ return;
46
+ case "MicroBatch":
47
+ this.pushMicroBatch(batch, emit);
48
+ return;
49
+ }
50
+ }
51
+ flushDue(emit) {
52
+ const nowMs = Date.now();
53
+ if ((this.mode === "Ordered" || this.mode === "StreamingOrdered") && nowMs - this.lastFlushMs > this.timeoutMs) {
54
+ this.flushAllSlots(emit);
55
+ }
56
+ if (this.mode === "MicroBatch") {
57
+ const nowUs = Math.floor(nowMs * 1000);
58
+ if (this.microBatch.length > 0 && nowUs - this.microBatchStartUs >= this.microBatchUs) {
59
+ this.flushMicroBatch(emit);
60
+ }
61
+ }
62
+ }
63
+ flushAll(emit) {
64
+ this.flushAllSlots(emit);
65
+ this.flushMicroBatch(emit);
66
+ }
67
+ pushOrdered(batch, emit) {
68
+ if (batch.slot > this.currentSlot && this.currentSlot > 0) {
69
+ this.flushBefore(batch.slot, emit);
70
+ }
71
+ if (batch.slot > this.currentSlot)
72
+ this.currentSlot = batch.slot;
73
+ this.pushSlotBatch(batch);
74
+ }
75
+ pushStreaming(batch, emit) {
76
+ if (batch.slot > this.currentSlot && this.currentSlot > 0) {
77
+ this.flushBefore(batch.slot, emit);
78
+ for (const slot of [...this.streamingWatermarks.keys()]) {
79
+ if (slot < batch.slot)
80
+ this.streamingWatermarks.delete(slot);
81
+ }
82
+ }
83
+ if (batch.slot > this.currentSlot)
84
+ this.currentSlot = batch.slot;
85
+ const expected = this.streamingWatermarks.get(batch.slot) ?? 0;
86
+ if (batch.txIndex === expected) {
87
+ this.emitBatch(batch, emit);
88
+ let watermark = expected + 1;
89
+ const buffered = this.slots.get(batch.slot);
90
+ if (buffered) {
91
+ buffered.sort(compareBatch);
92
+ let pos = buffered.findIndex((b) => b.txIndex === watermark);
93
+ while (pos >= 0) {
94
+ const [next] = buffered.splice(pos, 1);
95
+ this.emitBatch(next, emit);
96
+ watermark += 1;
97
+ pos = buffered.findIndex((b) => b.txIndex === watermark);
98
+ }
99
+ if (buffered.length === 0)
100
+ this.slots.delete(batch.slot);
101
+ }
102
+ this.streamingWatermarks.set(batch.slot, watermark);
103
+ }
104
+ else if (batch.txIndex > expected) {
105
+ this.pushSlotBatch(batch);
106
+ }
107
+ }
108
+ pushMicroBatch(batch, emit) {
109
+ const nowUs = Math.floor(Date.now() * 1000);
110
+ if (this.microBatch.length === 0)
111
+ this.microBatchStartUs = nowUs;
112
+ this.microBatch.push(batch);
113
+ if (nowUs - this.microBatchStartUs >= this.microBatchUs) {
114
+ this.flushMicroBatch(emit);
115
+ }
116
+ }
117
+ pushSlotBatch(batch) {
118
+ const list = this.slots.get(batch.slot);
119
+ if (list)
120
+ list.push(batch);
121
+ else
122
+ this.slots.set(batch.slot, [batch]);
123
+ }
124
+ flushBefore(slot, emit) {
125
+ for (const s of [...this.slots.keys()].sort((a, b) => a - b)) {
126
+ if (s >= slot)
127
+ continue;
128
+ const batches = this.slots.get(s) ?? [];
129
+ batches.sort(compareBatch);
130
+ for (const batch of batches)
131
+ this.emitBatch(batch, emit);
132
+ this.slots.delete(s);
133
+ this.streamingWatermarks.delete(s);
134
+ }
135
+ this.lastFlushMs = Date.now();
136
+ }
137
+ flushAllSlots(emit) {
138
+ for (const s of [...this.slots.keys()].sort((a, b) => a - b)) {
139
+ const batches = this.slots.get(s) ?? [];
140
+ batches.sort(compareBatch);
141
+ for (const batch of batches)
142
+ this.emitBatch(batch, emit);
143
+ this.slots.delete(s);
144
+ this.streamingWatermarks.delete(s);
145
+ }
146
+ this.lastFlushMs = Date.now();
147
+ }
148
+ flushMicroBatch(emit) {
149
+ if (this.microBatch.length === 0)
150
+ return;
151
+ this.microBatch.sort(compareBatch);
152
+ for (const batch of this.microBatch)
153
+ this.emitBatch(batch, emit);
154
+ this.microBatch = [];
155
+ this.microBatchStartUs = 0;
156
+ this.lastFlushMs = Date.now();
157
+ }
158
+ emitBatch(batch, emit) {
159
+ for (const event of batch.events)
160
+ emit(event);
161
+ }
162
+ }
163
+ exports.OrderDispatcher = OrderDispatcher;
164
+ function compareBatch(a, b) {
165
+ return a.slot - b.slot || a.txIndex - b.txIndex || a.seq - b.seq;
166
+ }
@@ -6,15 +6,17 @@ import type { AccountFilter, TransactionFilter } from "./types.js";
6
6
  export declare const PUMPFUN_PROGRAM_ID = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P";
7
7
  export declare const PUMPSWAP_PROGRAM_ID = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA";
8
8
  export declare const PUMPSWAP_FEES_PROGRAM_ID = "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ";
9
- /** Rust `BONK_PROGRAM_ID`(`Protocol::Bonk`)一致 */
10
- export declare const BONK_PROGRAM_ID = "BSwp6bEBihVLdqJRKS58NaebUBSDNjN7MdpFwNaR6gn3";
9
+ export declare const PUMP_FEES_PROGRAM_ID = "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ";
10
+ /** Raydium LaunchLab program id. */
11
+ export declare const RAYDIUM_LAUNCHLAB_PROGRAM_ID = "LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj";
11
12
  export declare const RAYDIUM_CPMM_PROGRAM_ID = "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C";
12
- export declare const RAYDIUM_CLMM_PROGRAM_ID = "CAMMCzo5YL8w4VFF8KVHrK22GGUQtcaMpgYqJPXBDvfE";
13
+ export declare const RAYDIUM_CLMM_PROGRAM_ID = "CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK";
13
14
  export declare const RAYDIUM_AMM_V4_PROGRAM_ID = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8";
14
15
  export declare const ORCA_WHIRLPOOL_PROGRAM_ID = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc";
15
16
  export declare const METEORA_POOLS_PROGRAM_ID = "Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB";
16
17
  export declare const METEORA_DAMM_V2_PROGRAM_ID = "cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG";
17
18
  export declare const METEORA_DLMM_PROGRAM_ID = "LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo";
19
+ export declare const METEORA_DBC_PROGRAM_ID = "dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN";
18
20
  /** 与 Rust `PROTOCOL_PROGRAM_IDS` 一致(仅含 Rust 中存在的协议) */
19
21
  export declare const PROTOCOL_PROGRAM_IDS: Record<Protocol, readonly string[]>;
20
22
  /** 与 Rust `get_program_ids_for_protocols` 一致 */
@@ -1,30 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PROTOCOL_PROGRAM_IDS = exports.METEORA_DLMM_PROGRAM_ID = exports.METEORA_DAMM_V2_PROGRAM_ID = exports.METEORA_POOLS_PROGRAM_ID = exports.ORCA_WHIRLPOOL_PROGRAM_ID = exports.RAYDIUM_AMM_V4_PROGRAM_ID = exports.RAYDIUM_CLMM_PROGRAM_ID = exports.RAYDIUM_CPMM_PROGRAM_ID = exports.BONK_PROGRAM_ID = exports.PUMPSWAP_FEES_PROGRAM_ID = exports.PUMPSWAP_PROGRAM_ID = exports.PUMPFUN_PROGRAM_ID = void 0;
3
+ exports.PROTOCOL_PROGRAM_IDS = exports.METEORA_DBC_PROGRAM_ID = exports.METEORA_DLMM_PROGRAM_ID = exports.METEORA_DAMM_V2_PROGRAM_ID = exports.METEORA_POOLS_PROGRAM_ID = exports.ORCA_WHIRLPOOL_PROGRAM_ID = exports.RAYDIUM_AMM_V4_PROGRAM_ID = exports.RAYDIUM_CLMM_PROGRAM_ID = exports.RAYDIUM_CPMM_PROGRAM_ID = exports.RAYDIUM_LAUNCHLAB_PROGRAM_ID = exports.PUMP_FEES_PROGRAM_ID = exports.PUMPSWAP_FEES_PROGRAM_ID = exports.PUMPSWAP_PROGRAM_ID = exports.PUMPFUN_PROGRAM_ID = void 0;
4
4
  exports.getProgramIdsForProtocols = getProgramIdsForProtocols;
5
5
  exports.transactionFilterForProtocols = transactionFilterForProtocols;
6
6
  exports.accountFilterForProtocols = accountFilterForProtocols;
7
7
  exports.PUMPFUN_PROGRAM_ID = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P";
8
8
  exports.PUMPSWAP_PROGRAM_ID = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA";
9
9
  exports.PUMPSWAP_FEES_PROGRAM_ID = "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ";
10
- /** Rust `BONK_PROGRAM_ID`(`Protocol::Bonk`)一致 */
11
- exports.BONK_PROGRAM_ID = "BSwp6bEBihVLdqJRKS58NaebUBSDNjN7MdpFwNaR6gn3";
10
+ exports.PUMP_FEES_PROGRAM_ID = exports.PUMPSWAP_FEES_PROGRAM_ID;
11
+ /** Raydium LaunchLab program id. */
12
+ exports.RAYDIUM_LAUNCHLAB_PROGRAM_ID = "LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj";
12
13
  exports.RAYDIUM_CPMM_PROGRAM_ID = "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C";
13
- exports.RAYDIUM_CLMM_PROGRAM_ID = "CAMMCzo5YL8w4VFF8KVHrK22GGUQtcaMpgYqJPXBDvfE";
14
+ exports.RAYDIUM_CLMM_PROGRAM_ID = "CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK";
14
15
  exports.RAYDIUM_AMM_V4_PROGRAM_ID = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8";
15
16
  exports.ORCA_WHIRLPOOL_PROGRAM_ID = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc";
16
17
  exports.METEORA_POOLS_PROGRAM_ID = "Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB";
17
18
  exports.METEORA_DAMM_V2_PROGRAM_ID = "cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG";
18
19
  exports.METEORA_DLMM_PROGRAM_ID = "LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo";
20
+ exports.METEORA_DBC_PROGRAM_ID = "dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN";
19
21
  /** 与 Rust `PROTOCOL_PROGRAM_IDS` 一致(仅含 Rust 中存在的协议) */
20
22
  exports.PROTOCOL_PROGRAM_IDS = {
21
23
  PumpFun: [exports.PUMPFUN_PROGRAM_ID],
22
24
  PumpSwap: [exports.PUMPSWAP_PROGRAM_ID],
23
- Bonk: [exports.BONK_PROGRAM_ID],
25
+ PumpFees: [exports.PUMP_FEES_PROGRAM_ID],
26
+ RaydiumLaunchlab: [exports.RAYDIUM_LAUNCHLAB_PROGRAM_ID],
24
27
  RaydiumCpmm: [exports.RAYDIUM_CPMM_PROGRAM_ID],
25
28
  RaydiumClmm: [exports.RAYDIUM_CLMM_PROGRAM_ID],
26
29
  RaydiumAmmV4: [exports.RAYDIUM_AMM_V4_PROGRAM_ID],
30
+ OrcaWhirlpool: [exports.ORCA_WHIRLPOOL_PROGRAM_ID],
31
+ MeteoraPools: [exports.METEORA_POOLS_PROGRAM_ID],
27
32
  MeteoraDammV2: [exports.METEORA_DAMM_V2_PROGRAM_ID],
33
+ MeteoraDlmm: [exports.METEORA_DLMM_PROGRAM_ID],
34
+ MeteoraDbc: [exports.METEORA_DBC_PROGRAM_ID],
28
35
  };
29
36
  /** 与 Rust `get_program_ids_for_protocols` 一致 */
30
37
  function getProgramIdsForProtocols(protocols) {