sol-parser-sdk-nodejs 0.4.4 → 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 (52) hide show
  1. package/README.md +16 -4
  2. package/README_CN.md +16 -4
  3. package/dist/accounts/mod.d.ts +1 -1
  4. package/dist/accounts/mod.js +43 -9
  5. package/dist/accounts/pumpfun.d.ts +10 -0
  6. package/dist/accounts/pumpfun.js +384 -3
  7. package/dist/core/account_dispatcher_rpc.js +5 -26
  8. package/dist/core/account_fill_meteora.d.ts +1 -2
  9. package/dist/core/account_fill_meteora.js +0 -2
  10. package/dist/core/account_fill_pumpfun.js +86 -24
  11. package/dist/core/account_fill_pumpswap.js +50 -0
  12. package/dist/core/account_fill_raydium_launchlab.d.ts +4 -0
  13. package/dist/core/account_fill_raydium_launchlab.js +20 -0
  14. package/dist/core/dex_event.d.ts +136 -17
  15. package/dist/core/pumpfun_fee_enrich.d.ts +1 -0
  16. package/dist/core/pumpfun_fee_enrich.js +51 -0
  17. package/dist/grpc/log_instr_dedup.js +62 -14
  18. package/dist/grpc/program_ids.d.ts +4 -3
  19. package/dist/grpc/program_ids.js +11 -5
  20. package/dist/grpc/types.d.ts +13 -6
  21. package/dist/grpc/types.js +250 -239
  22. package/dist/index.d.ts +6 -5
  23. package/dist/index.js +21 -7
  24. package/dist/instr/meteora_damm_ix.js +4 -1
  25. package/dist/instr/meteora_dlmm_ix.d.ts +2 -0
  26. package/dist/instr/meteora_dlmm_ix.js +134 -0
  27. package/dist/instr/meteora_pools_ix.d.ts +2 -0
  28. package/dist/instr/meteora_pools_ix.js +78 -0
  29. package/dist/instr/mod.d.ts +3 -1
  30. package/dist/instr/mod.js +38 -19
  31. package/dist/instr/program_ids.d.ts +1 -5
  32. package/dist/instr/program_ids.js +3 -6
  33. package/dist/instr/pumpfun_ix.js +219 -5
  34. package/dist/instr/pumpswap_ix.js +36 -2
  35. package/dist/instr/raydium_launchlab_ix.d.ts +8 -0
  36. package/dist/instr/raydium_launchlab_ix.js +125 -0
  37. package/dist/instr/rust_aliases.d.ts +2 -0
  38. package/dist/instr/rust_aliases.js +5 -1
  39. package/dist/logs/optimized_matcher.js +14 -9
  40. package/dist/logs/pump.js +76 -3
  41. package/dist/logs/pump_amm.js +1 -1
  42. package/dist/logs/raydium_launchlab.d.ts +10 -0
  43. package/dist/logs/raydium_launchlab.js +84 -0
  44. package/dist/shredstream/client.d.ts +4 -1
  45. package/dist/shredstream/client.js +18 -14
  46. package/dist/shredstream/index.d.ts +1 -1
  47. package/dist/shredstream/index.js +1 -1
  48. package/dist/shredstream/instruction_parse.d.ts +3 -3
  49. package/dist/shredstream/instruction_parse.js +36 -13
  50. package/dist/util/market.d.ts +18 -0
  51. package/dist/util/market.js +54 -0
  52. package/package.json +1 -1
@@ -6,8 +6,11 @@ const utils_js_1 = require("./utils.js");
6
6
  const binary_js_1 = require("../util/binary.js");
7
7
  const Z = (0, dex_event_js_1.defaultPubkey)();
8
8
  const DISC = {
9
+ BUY: Uint8Array.from([102, 6, 61, 18, 1, 218, 235, 234]),
10
+ SELL: Uint8Array.from([51, 230, 133, 164, 1, 127, 131, 173]),
9
11
  CREATE: Uint8Array.from([24, 30, 200, 40, 5, 28, 7, 119]),
10
12
  CREATE_V2: Uint8Array.from([214, 144, 76, 236, 95, 139, 49, 180]),
13
+ BUY_EXACT_SOL_IN: Uint8Array.from([56, 252, 116, 8, 158, 223, 205, 95]),
11
14
  BUY_V2: Uint8Array.from([184, 23, 238, 97, 103, 197, 211, 61]),
12
15
  SELL_V2: Uint8Array.from([93, 246, 130, 60, 231, 233, 64, 178]),
13
16
  BUY_EXACT_QUOTE_IN_V2: Uint8Array.from([194, 171, 28, 70, 104, 77, 91, 47]),
@@ -30,12 +33,14 @@ function createNumericDefaults() {
30
33
  token_total_supply: 0n,
31
34
  is_mayhem_mode: false,
32
35
  is_cashback_enabled: false,
36
+ quote_mint: Z,
37
+ virtual_quote_reserves: 0n,
33
38
  };
34
39
  }
35
40
  function parsePumpfunTradeV2Instruction(ixName, data, accounts, metadata) {
36
- const minAccounts = ixName === "sell_v2" ? 26 : 27;
37
- if (accounts.length < minAccounts)
41
+ if (!accounts[1])
38
42
  return null;
43
+ const normalizedIxName = ixName === "buy_v2" ? "buy" : ixName === "sell_v2" ? "sell" : "buy_exact_quote_in";
39
44
  const first = data.length >= 8 ? (0, utils_js_1.readU64LE)(data, 0) ?? 0n : 0n;
40
45
  const second = data.length >= 16 ? (0, utils_js_1.readU64LE)(data, 8) ?? 0n : 0n;
41
46
  const tokenAmount = ixName === "buy_exact_quote_in_v2" ? second : first;
@@ -43,10 +48,20 @@ function parsePumpfunTradeV2Instruction(ixName, data, accounts, metadata) {
43
48
  const trade = {
44
49
  metadata,
45
50
  mint: accounts[1] ?? Z,
51
+ quote_mint: accounts[2] ?? Z,
52
+ global: accounts[0] ?? Z,
46
53
  bonding_curve: accounts[10] ?? Z,
54
+ bonding_curve_v2: Z,
47
55
  user: accounts[13] ?? Z,
48
56
  sol_amount: solAmount,
49
57
  token_amount: tokenAmount,
58
+ amount: ixName === "buy_exact_quote_in_v2" ? second : first,
59
+ max_sol_cost: ixName === "buy_exact_quote_in_v2" ? 0n : ixName === "sell_v2" ? 0n : second,
60
+ min_sol_output: ixName === "sell_v2" ? second : 0n,
61
+ spendable_sol_in: 0n,
62
+ spendable_quote_in: ixName === "buy_exact_quote_in_v2" ? first : 0n,
63
+ min_tokens_out: ixName === "buy_exact_quote_in_v2" ? second : 0n,
64
+ quote_amount: ixName === "buy_exact_quote_in_v2" ? first : 0n,
50
65
  fee_recipient: accounts[6] ?? Z,
51
66
  is_buy: ixName !== "sell_v2",
52
67
  is_created_buy: false,
@@ -65,16 +80,194 @@ function parsePumpfunTradeV2Instruction(ixName, data, accounts, metadata) {
65
80
  total_claimed_tokens: 0n,
66
81
  current_sol_volume: 0n,
67
82
  last_update_timestamp: 0n,
68
- ix_name: ixName,
83
+ ix_name: normalizedIxName,
69
84
  mayhem_mode: false,
70
85
  cashback_fee_basis_points: 0n,
71
86
  cashback: 0n,
72
87
  is_cashback_coin: false,
73
88
  associated_bonding_curve: accounts[11] ?? Z,
89
+ associated_user: accounts[14] ?? Z,
90
+ system_program: accounts[ixName === "sell_v2" ? 23 : 24] ?? Z,
74
91
  token_program: accounts[3] ?? Z,
92
+ quote_token_program: accounts[4] ?? Z,
93
+ associated_token_program: accounts[5] ?? Z,
75
94
  creator_vault: accounts[16] ?? Z,
95
+ associated_quote_fee_recipient: accounts[7] ?? Z,
96
+ buyback_fee_recipient: accounts[8] ?? Z,
97
+ associated_quote_buyback_fee_recipient: accounts[9] ?? Z,
98
+ associated_quote_bonding_curve: accounts[12] ?? Z,
99
+ associated_quote_user: accounts[15] ?? Z,
100
+ associated_creator_vault: accounts[17] ?? Z,
101
+ sharing_config: accounts[18] ?? Z,
102
+ event_authority: accounts[ixName === "sell_v2" ? 24 : 25] ?? Z,
103
+ program: accounts[ixName === "sell_v2" ? 25 : 26] ?? Z,
104
+ global_volume_accumulator: ixName === "sell_v2" ? Z : accounts[19] ?? Z,
105
+ user_volume_accumulator: accounts[ixName === "sell_v2" ? 19 : 20] ?? Z,
106
+ associated_user_volume_accumulator: accounts[ixName === "sell_v2" ? 20 : 21] ?? Z,
107
+ fee_config: accounts[ixName === "sell_v2" ? 21 : 22] ?? Z,
108
+ fee_program: accounts[ixName === "sell_v2" ? 22 : 23] ?? Z,
109
+ };
110
+ if (normalizedIxName === "buy")
111
+ return { PumpFunBuy: trade };
112
+ if (normalizedIxName === "sell")
113
+ return { PumpFunSell: trade };
114
+ return { PumpFunBuy: trade };
115
+ }
116
+ function parsePumpfunLegacyBuyInstruction(ixName, data, accounts, metadata) {
117
+ if (accounts.length < 16)
118
+ return null;
119
+ const first = data.length >= 8 ? (0, utils_js_1.readU64LE)(data, 0) ?? 0n : 0n;
120
+ const second = data.length >= 16 ? (0, utils_js_1.readU64LE)(data, 8) ?? 0n : 0n;
121
+ const exactSolIn = ixName === "buy_exact_sol_in";
122
+ const buybackFeeRecipient = accounts[17] ?? Z;
123
+ const trade = {
124
+ metadata,
125
+ mint: accounts[2] ?? Z,
126
+ global: accounts[0] ?? Z,
127
+ bonding_curve: accounts[3] ?? Z,
128
+ bonding_curve_v2: accounts[16] ?? Z,
129
+ associated_bonding_curve: accounts[4] ?? Z,
130
+ associated_user: accounts[5] ?? Z,
131
+ user: accounts[6] ?? Z,
132
+ system_program: accounts[7] ?? Z,
133
+ token_program: accounts[8] ?? Z,
134
+ creator_vault: accounts[9] ?? Z,
135
+ event_authority: accounts[10] ?? Z,
136
+ program: accounts[11] ?? Z,
137
+ global_volume_accumulator: accounts[12] ?? Z,
138
+ user_volume_accumulator: accounts[13] ?? Z,
139
+ fee_config: accounts[14] ?? Z,
140
+ fee_program: accounts[15] ?? Z,
141
+ buyback_fee_recipient: buybackFeeRecipient,
142
+ is_buy: true,
143
+ is_created_buy: false,
144
+ sol_amount: exactSolIn ? first : second,
145
+ token_amount: exactSolIn ? second : first,
146
+ amount: exactSolIn ? second : first,
147
+ max_sol_cost: exactSolIn ? first : second,
148
+ spendable_sol_in: exactSolIn ? first : 0n,
149
+ spendable_quote_in: 0n,
150
+ min_tokens_out: exactSolIn ? second : 0n,
151
+ min_sol_output: 0n,
152
+ quote_amount: 0n,
153
+ fee_recipient: accounts[1] ?? Z,
154
+ timestamp: 0n,
155
+ virtual_sol_reserves: 0n,
156
+ virtual_token_reserves: 0n,
157
+ real_sol_reserves: 0n,
158
+ real_token_reserves: 0n,
159
+ fee_basis_points: 0n,
160
+ fee: 0n,
161
+ creator: Z,
162
+ creator_fee_basis_points: 0n,
163
+ creator_fee: 0n,
164
+ track_volume: (data[16] ?? 0) !== 0,
165
+ total_unclaimed_tokens: 0n,
166
+ total_claimed_tokens: 0n,
167
+ current_sol_volume: 0n,
168
+ last_update_timestamp: 0n,
169
+ ix_name: ixName,
170
+ mayhem_mode: false,
171
+ cashback_fee_basis_points: 0n,
172
+ cashback: 0n,
173
+ is_cashback_coin: false,
174
+ quote_mint: Z,
175
+ quote_token_program: Z,
176
+ associated_token_program: Z,
177
+ associated_quote_fee_recipient: Z,
178
+ associated_quote_buyback_fee_recipient: Z,
179
+ associated_quote_bonding_curve: Z,
180
+ associated_quote_user: Z,
181
+ associated_creator_vault: Z,
182
+ sharing_config: Z,
183
+ associated_user_volume_accumulator: Z,
184
+ ...(buybackFeeRecipient !== Z ? { account: buybackFeeRecipient } : {}),
185
+ };
186
+ if (exactSolIn)
187
+ return { PumpFunBuyExactSolIn: trade };
188
+ return { PumpFunBuy: trade };
189
+ }
190
+ function parsePumpfunLegacySellInstruction(data, accounts, metadata) {
191
+ if (accounts.length < 14)
192
+ return null;
193
+ const amount = data.length >= 8 ? (0, utils_js_1.readU64LE)(data, 0) ?? 0n : 0n;
194
+ const minSolOutput = data.length >= 16 ? (0, utils_js_1.readU64LE)(data, 8) ?? 0n : 0n;
195
+ let legacyUserVolumeAccumulator = Z;
196
+ let legacyBondingCurveV2 = accounts[14] ?? Z;
197
+ let legacyBuybackFeeRecipient = Z;
198
+ if (accounts.length >= 17) {
199
+ legacyUserVolumeAccumulator = accounts[14] ?? Z;
200
+ legacyBondingCurveV2 = accounts[15] ?? Z;
201
+ legacyBuybackFeeRecipient = accounts[16] ?? Z;
202
+ }
203
+ else if (accounts.length >= 16) {
204
+ legacyBondingCurveV2 = accounts[14] ?? Z;
205
+ legacyBuybackFeeRecipient = accounts[15] ?? Z;
206
+ }
207
+ const trade = {
208
+ metadata,
209
+ mint: accounts[2] ?? Z,
210
+ quote_mint: Z,
211
+ is_buy: false,
212
+ is_created_buy: false,
213
+ global: accounts[0] ?? Z,
214
+ bonding_curve: accounts[3] ?? Z,
215
+ bonding_curve_v2: legacyBondingCurveV2,
216
+ associated_bonding_curve: accounts[4] ?? Z,
217
+ associated_user: accounts[5] ?? Z,
218
+ user: accounts[6] ?? Z,
219
+ system_program: accounts[7] ?? Z,
220
+ fee_recipient: accounts[1] ?? Z,
221
+ token_program: accounts[9] ?? Z,
222
+ quote_token_program: Z,
223
+ associated_token_program: Z,
224
+ creator_vault: accounts[8] ?? Z,
225
+ associated_quote_fee_recipient: Z,
226
+ buyback_fee_recipient: legacyBuybackFeeRecipient,
227
+ associated_quote_buyback_fee_recipient: Z,
228
+ associated_quote_bonding_curve: Z,
229
+ associated_quote_user: Z,
230
+ associated_creator_vault: Z,
231
+ sharing_config: Z,
232
+ event_authority: accounts[10] ?? Z,
233
+ program: accounts[11] ?? Z,
234
+ global_volume_accumulator: Z,
235
+ user_volume_accumulator: legacyUserVolumeAccumulator,
236
+ associated_user_volume_accumulator: Z,
237
+ fee_config: accounts[12] ?? Z,
238
+ fee_program: accounts[13] ?? Z,
239
+ sol_amount: minSolOutput,
240
+ token_amount: amount,
241
+ amount,
242
+ max_sol_cost: 0n,
243
+ min_sol_output: minSolOutput,
244
+ spendable_sol_in: 0n,
245
+ spendable_quote_in: 0n,
246
+ min_tokens_out: 0n,
247
+ quote_amount: 0n,
248
+ timestamp: 0n,
249
+ virtual_sol_reserves: 0n,
250
+ virtual_token_reserves: 0n,
251
+ real_sol_reserves: 0n,
252
+ real_token_reserves: 0n,
253
+ fee_basis_points: 0n,
254
+ fee: 0n,
255
+ creator: Z,
256
+ creator_fee_basis_points: 0n,
257
+ creator_fee: 0n,
258
+ track_volume: false,
259
+ total_unclaimed_tokens: 0n,
260
+ total_claimed_tokens: 0n,
261
+ current_sol_volume: 0n,
262
+ last_update_timestamp: 0n,
263
+ ix_name: "sell",
264
+ mayhem_mode: false,
265
+ cashback_fee_basis_points: 0n,
266
+ cashback: 0n,
267
+ is_cashback_coin: false,
268
+ ...(legacyBuybackFeeRecipient !== Z ? { account: legacyBuybackFeeRecipient } : {}),
76
269
  };
77
- return { PumpFunTrade: trade };
270
+ return { PumpFunSell: trade };
78
271
  }
79
272
  function parsePumpfunInstruction(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs) {
80
273
  if (instructionData.length < 8)
@@ -98,7 +291,17 @@ function parsePumpfunInstruction(instructionData, accounts, signature, slot, txI
98
291
  if (!n3)
99
292
  return null;
100
293
  o = n3.next;
101
- const creator = o + 32 <= data.length ? (0, utils_js_1.readPubkeyIx)(data, o) ?? Z : Z;
294
+ if (o + 33 > data.length)
295
+ return null;
296
+ const creator = (0, utils_js_1.readPubkeyIx)(data, o);
297
+ if (!creator)
298
+ return null;
299
+ o += 32;
300
+ const isMayhemMode = (0, utils_js_1.readBool)(data, o);
301
+ if (isMayhemMode === null)
302
+ return null;
303
+ o += 1;
304
+ const isCashbackEnabled = (0, utils_js_1.readBool)(data, o) ?? false;
102
305
  const mint = accounts[0];
103
306
  const ev = {
104
307
  metadata: meta,
@@ -124,9 +327,20 @@ function parsePumpfunInstruction(instructionData, accounts, signature, slot, txI
124
327
  program: accounts[15] ?? Z,
125
328
  observed_fee_recipient: Z,
126
329
  ...createNumericDefaults(),
330
+ is_mayhem_mode: isMayhemMode,
331
+ is_cashback_enabled: isCashbackEnabled,
127
332
  };
128
333
  return { PumpFunCreateV2: ev };
129
334
  }
335
+ if (discEq(outer, DISC.BUY)) {
336
+ return parsePumpfunLegacyBuyInstruction("buy", data, accounts, meta);
337
+ }
338
+ if (discEq(outer, DISC.BUY_EXACT_SOL_IN)) {
339
+ return parsePumpfunLegacyBuyInstruction("buy_exact_sol_in", data, accounts, meta);
340
+ }
341
+ if (discEq(outer, DISC.SELL)) {
342
+ return parsePumpfunLegacySellInstruction(data, accounts, meta);
343
+ }
130
344
  if (discEq(outer, DISC.BUY_V2)) {
131
345
  return parsePumpfunTradeV2Instruction("buy_v2", data, accounts, meta);
132
346
  }
@@ -5,6 +5,38 @@ const dex_event_js_1 = require("../core/dex_event.js");
5
5
  const utils_js_1 = require("./utils.js");
6
6
  const ZP = (0, dex_event_js_1.defaultPubkey)();
7
7
  const Z = ZP;
8
+ function fillBuyUpgradeAccounts(ev, accounts) {
9
+ const g = (i) => (0, utils_js_1.getAccount)(accounts, i) ?? ZP;
10
+ if (accounts.length >= 27) {
11
+ ev.pool_v2 = g(24);
12
+ ev.fee_recipient = g(25);
13
+ ev.fee_recipient_quote_token_account = g(26);
14
+ }
15
+ else if (accounts.length >= 26) {
16
+ ev.pool_v2 = g(23);
17
+ ev.fee_recipient = g(24);
18
+ ev.fee_recipient_quote_token_account = g(25);
19
+ }
20
+ else if (accounts.length >= 24) {
21
+ ev.pool_v2 = g(23);
22
+ }
23
+ }
24
+ function fillSellUpgradeAccounts(ev, accounts) {
25
+ const g = (i) => (0, utils_js_1.getAccount)(accounts, i) ?? ZP;
26
+ if (accounts.length >= 26) {
27
+ ev.pool_v2 = g(23);
28
+ ev.fee_recipient = g(24);
29
+ ev.fee_recipient_quote_token_account = g(25);
30
+ }
31
+ else if (accounts.length >= 24) {
32
+ ev.pool_v2 = g(21);
33
+ ev.fee_recipient = g(22);
34
+ ev.fee_recipient_quote_token_account = g(23);
35
+ }
36
+ else if (accounts.length >= 22) {
37
+ ev.pool_v2 = g(21);
38
+ }
39
+ }
8
40
  function disc8(a) {
9
41
  return Uint8Array.from(a);
10
42
  }
@@ -50,7 +82,7 @@ function buyLike(data, accounts, meta, swapOrder) {
50
82
  user_quote_token_account: g(6),
51
83
  protocol_fee_recipient: g(9),
52
84
  protocol_fee_recipient_token_account: g(10),
53
- coin_creator: accounts.length > 16 ? g(16) : Z,
85
+ coin_creator: Z,
54
86
  coin_creator_fee_basis_points: 0n,
55
87
  coin_creator_fee: 0n,
56
88
  track_volume: false,
@@ -72,6 +104,7 @@ function buyLike(data, accounts, meta, swapOrder) {
72
104
  base_token_program: g(11),
73
105
  quote_token_program: g(12),
74
106
  };
107
+ fillBuyUpgradeAccounts(ev, accounts);
75
108
  return ev;
76
109
  }
77
110
  function parsePumpswapInstruction(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs = 0) {
@@ -119,7 +152,7 @@ function parsePumpswapInstruction(instructionData, accounts, signature, slot, tx
119
152
  user_quote_token_account: g(6),
120
153
  protocol_fee_recipient: g(9),
121
154
  protocol_fee_recipient_token_account: g(10),
122
- coin_creator: accounts.length > 16 ? g(16) : Z,
155
+ coin_creator: Z,
123
156
  coin_creator_fee_basis_points: 0n,
124
157
  coin_creator_fee: 0n,
125
158
  cashback_fee_basis_points: 0n,
@@ -134,6 +167,7 @@ function parsePumpswapInstruction(instructionData, accounts, signature, slot, tx
134
167
  base_token_program: g(11),
135
168
  quote_token_program: g(12),
136
169
  };
170
+ fillSellUpgradeAccounts(ev, accounts);
137
171
  return { PumpSwapSell: ev };
138
172
  }
139
173
  if (discEq(head, PS.CREATE_POOL)) {
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Raydium LaunchLab 指令解析
3
+ *
4
+ * 1) **Program data 日志形载荷**(与 `logs/raydium_launchlab` 一致):前 8 字节为事件 disc,后跟 pool/user/金额…
5
+ * 2) **Anchor 外层指令**:`global:buy` / `sell` / `create_pool` / `migrate_to_amm` 等(sha256 前 8 字节),参数多为 Borsh u64。
6
+ */
7
+ import type { DexEvent } from "../core/dex_event.js";
8
+ export declare function parseRaydiumLaunchlabInstruction(instructionData: Uint8Array, accounts: string[], signature: string, slot: number, txIndex: number, blockTimeUs: number | undefined, grpcRecvUs: number): DexEvent | null;
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseRaydiumLaunchlabInstruction = parseRaydiumLaunchlabInstruction;
4
+ const dex_event_js_1 = require("../core/dex_event.js");
5
+ const raydium_launchlab_js_1 = require("../logs/raydium_launchlab.js");
6
+ const utils_js_1 = require("./utils.js");
7
+ const Z = (0, dex_event_js_1.defaultPubkey)();
8
+ /** Anchor `sha256("global:<name>")[0..8]`,与链上 LaunchLab / pAMM 系指令一致 */
9
+ const ANCHOR = {
10
+ BUY_EXACT_IN: [250, 234, 13, 123, 213, 156, 19, 236],
11
+ BUY_EXACT_OUT: [24, 211, 116, 40, 105, 3, 153, 56],
12
+ INITIALIZE: [175, 175, 109, 31, 13, 152, 155, 237],
13
+ INITIALIZE_V2: [67, 153, 175, 39, 218, 16, 38, 32],
14
+ INITIALIZE_WITH_TOKEN_2022: [37, 190, 126, 222, 44, 154, 171, 17],
15
+ SELL_EXACT_OUT: [95, 200, 71, 34, 8, 9, 11, 166],
16
+ SELL_EXACT_IN: [149, 39, 222, 155, 211, 124, 152, 26],
17
+ MIGRATE_TO_AMM: [207, 82, 192, 145, 254, 207, 145, 223],
18
+ MIGRATE_TO_CPSWAP: [136, 92, 200, 103, 28, 218, 144, 140],
19
+ };
20
+ function discEqU64(data, disc) {
21
+ if (data.length < 8)
22
+ return false;
23
+ const v = (0, utils_js_1.readU64LE)(data, 0);
24
+ return v === disc;
25
+ }
26
+ function headEq(data, bytes) {
27
+ if (data.length < 8)
28
+ return false;
29
+ for (let i = 0; i < 8; i++)
30
+ if (data[i] !== bytes[i])
31
+ return false;
32
+ return true;
33
+ }
34
+ /** 与 PumpSwap buy/sell 一致:两 u64(base / quote 侧限额) */
35
+ function parseMintParams(payload) {
36
+ const decimals = (0, utils_js_1.readU8)(payload, 0);
37
+ if (decimals === null)
38
+ return null;
39
+ let o = 1;
40
+ const name = (0, utils_js_1.readBorshStrAt)(payload, o);
41
+ if (!name)
42
+ return null;
43
+ o = name.next;
44
+ const symbol = (0, utils_js_1.readBorshStrAt)(payload, o);
45
+ if (!symbol)
46
+ return null;
47
+ o = symbol.next;
48
+ const uri = (0, utils_js_1.readBorshStrAt)(payload, o);
49
+ if (!uri)
50
+ return null;
51
+ return { symbol: symbol.s, name: name.s, uri: uri.s, decimals };
52
+ }
53
+ function tradeFromTwoU64(payload, accounts, meta, isBuy, exactIn) {
54
+ const first = (0, utils_js_1.readU64LE)(payload, 0) ?? 0n;
55
+ const second = (0, utils_js_1.readU64LE)(payload, 8) ?? 0n;
56
+ const amount_in = exactIn ? first : second;
57
+ const amount_out = exactIn ? second : first;
58
+ const pool = (0, utils_js_1.getAccount)(accounts, 4) ?? Z;
59
+ const user = (0, utils_js_1.getAccount)(accounts, 0) ?? Z;
60
+ return {
61
+ RaydiumLaunchlabTrade: {
62
+ metadata: meta,
63
+ pool_state: pool,
64
+ user,
65
+ amount_in,
66
+ amount_out,
67
+ is_buy: isBuy,
68
+ trade_direction: isBuy ? "Buy" : "Sell",
69
+ exact_in: exactIn,
70
+ },
71
+ };
72
+ }
73
+ function parseRaydiumLaunchlabInstruction(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs) {
74
+ if (instructionData.length < 8)
75
+ return null;
76
+ const meta = (0, utils_js_1.ixMeta)(signature, slot, txIndex, blockTimeUs, grpcRecvUs);
77
+ // --- Program data 事件形(与链上 emit 载荷一致,偶见于外层) ---
78
+ if (discEqU64(instructionData, raydium_launchlab_js_1.RAYDIUM_LAUNCHLAB_DISC.TRADE)) {
79
+ return (0, raydium_launchlab_js_1.parseRaydiumLaunchlabTradeFromData)(instructionData.subarray(8), meta);
80
+ }
81
+ if (discEqU64(instructionData, raydium_launchlab_js_1.RAYDIUM_LAUNCHLAB_DISC.POOL_CREATE)) {
82
+ return (0, raydium_launchlab_js_1.parseRaydiumLaunchlabPoolCreateFromData)(instructionData.subarray(8), meta);
83
+ }
84
+ const rest = instructionData.subarray(8);
85
+ // --- Anchor:买卖(两 u64) ---
86
+ if (headEq(instructionData, ANCHOR.BUY_EXACT_IN)) {
87
+ if (rest.length < 16)
88
+ return null;
89
+ return tradeFromTwoU64(rest, accounts, meta, true, true);
90
+ }
91
+ if (headEq(instructionData, ANCHOR.BUY_EXACT_OUT)) {
92
+ if (rest.length < 16)
93
+ return null;
94
+ return tradeFromTwoU64(rest, accounts, meta, true, false);
95
+ }
96
+ if (headEq(instructionData, ANCHOR.SELL_EXACT_IN)) {
97
+ if (rest.length < 16)
98
+ return null;
99
+ return tradeFromTwoU64(rest, accounts, meta, false, true);
100
+ }
101
+ if (headEq(instructionData, ANCHOR.SELL_EXACT_OUT)) {
102
+ if (rest.length < 16)
103
+ return null;
104
+ return tradeFromTwoU64(rest, accounts, meta, false, false);
105
+ }
106
+ if (headEq(instructionData, ANCHOR.INITIALIZE) ||
107
+ headEq(instructionData, ANCHOR.INITIALIZE_V2) ||
108
+ headEq(instructionData, ANCHOR.INITIALIZE_WITH_TOKEN_2022)) {
109
+ const base_mint_param = parseMintParams(rest);
110
+ if (!base_mint_param)
111
+ return null;
112
+ return {
113
+ RaydiumLaunchlabPoolCreate: {
114
+ metadata: meta,
115
+ base_mint_param,
116
+ pool_state: (0, utils_js_1.getAccount)(accounts, 5) ?? Z,
117
+ creator: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
118
+ },
119
+ };
120
+ }
121
+ if (headEq(instructionData, ANCHOR.MIGRATE_TO_AMM) || headEq(instructionData, ANCHOR.MIGRATE_TO_CPSWAP)) {
122
+ return null;
123
+ }
124
+ return null;
125
+ }
@@ -5,4 +5,6 @@ export { parseInstructionUnified as parse_instruction_unified } from "./mod.js";
5
5
  export { parsePumpfunInstruction as parse_pumpfun_instruction } from "./pumpfun_ix.js";
6
6
  export { parsePumpswapInstruction as parse_pumpswap_instruction } from "./pumpswap_ix.js";
7
7
  export { parseMeteoraDammInstruction as parse_meteora_damm_instruction } from "./meteora_damm_ix.js";
8
+ export { parseMeteoraDlmmInstruction as parse_meteora_dlmm_instruction } from "./meteora_dlmm_ix.js";
9
+ export { parseMeteoraPoolsInstruction as parse_meteora_pools_instruction } from "./meteora_pools_ix.js";
8
10
  export { parsePumpFeesInstruction as parse_pump_fees_instruction } from "./pump_fees_ix.js";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parse_pump_fees_instruction = exports.parse_meteora_damm_instruction = exports.parse_pumpswap_instruction = exports.parse_pumpfun_instruction = exports.parse_instruction_unified = void 0;
3
+ exports.parse_pump_fees_instruction = exports.parse_meteora_pools_instruction = exports.parse_meteora_dlmm_instruction = exports.parse_meteora_damm_instruction = exports.parse_pumpswap_instruction = exports.parse_pumpfun_instruction = exports.parse_instruction_unified = void 0;
4
4
  /**
5
5
  * Rust `instr` 根模块 re-export 的蛇形命名(与 `parse_pumpfun_instruction` 等对应)。
6
6
  */
@@ -12,5 +12,9 @@ var pumpswap_ix_js_1 = require("./pumpswap_ix.js");
12
12
  Object.defineProperty(exports, "parse_pumpswap_instruction", { enumerable: true, get: function () { return pumpswap_ix_js_1.parsePumpswapInstruction; } });
13
13
  var meteora_damm_ix_js_1 = require("./meteora_damm_ix.js");
14
14
  Object.defineProperty(exports, "parse_meteora_damm_instruction", { enumerable: true, get: function () { return meteora_damm_ix_js_1.parseMeteoraDammInstruction; } });
15
+ var meteora_dlmm_ix_js_1 = require("./meteora_dlmm_ix.js");
16
+ Object.defineProperty(exports, "parse_meteora_dlmm_instruction", { enumerable: true, get: function () { return meteora_dlmm_ix_js_1.parseMeteoraDlmmInstruction; } });
17
+ var meteora_pools_ix_js_1 = require("./meteora_pools_ix.js");
18
+ Object.defineProperty(exports, "parse_meteora_pools_instruction", { enumerable: true, get: function () { return meteora_pools_ix_js_1.parseMeteoraPoolsInstruction; } });
15
19
  var pump_fees_ix_js_1 = require("./pump_fees_ix.js");
16
20
  Object.defineProperty(exports, "parse_pump_fees_instruction", { enumerable: true, get: function () { return pump_fees_ix_js_1.parsePumpFeesInstruction; } });
@@ -19,7 +19,7 @@ const orca_js_1 = require("./orca.js");
19
19
  const meteora_amm_js_1 = require("./meteora_amm.js");
20
20
  const meteora_damm_js_1 = require("./meteora_damm.js");
21
21
  const meteora_dlmm_js_1 = require("./meteora_dlmm.js");
22
- const raydium_launchpad_js_1 = require("./raydium_launchpad.js");
22
+ const raydium_launchlab_js_1 = require("./raydium_launchlab.js");
23
23
  const binary_js_1 = require("../util/binary.js");
24
24
  const program_log_discriminators_js_1 = require("./program_log_discriminators.js");
25
25
  function discriminatorToEventType(disc) {
@@ -147,6 +147,14 @@ function eventTypeFromDexEvent(ev) {
147
147
  const key = Object.keys(ev)[0];
148
148
  return key ? key : null;
149
149
  }
150
+ function applyActualEventTypeFilter(ev, filter) {
151
+ if (!ev || !filter)
152
+ return ev;
153
+ const actual = eventTypeFromDexEvent(ev);
154
+ if (actual && !filter.shouldInclude(actual))
155
+ return null;
156
+ return ev;
157
+ }
150
158
  function applyPumpfunSecondaryFilter(ev, filter) {
151
159
  if (!ev || !filter)
152
160
  return ev;
@@ -155,10 +163,7 @@ function applyPumpfunSecondaryFilter(ev, filter) {
155
163
  if (hasSpecific && !pumpfunTradeMatchesFilter(ev, filter.include_only))
156
164
  return null;
157
165
  }
158
- const actual = eventTypeFromDexEvent(ev);
159
- if (actual && !filter.shouldInclude(actual))
160
- return null;
161
- return ev;
166
+ return applyActualEventTypeFilter(ev, filter);
162
167
  }
163
168
  function parseLogOptimized(log, signature, slot, txIndex, blockTimeUs, grpcRecvUs, eventTypeFilter, isCreatedBuy, recentBlockhash) {
164
169
  const buf = (0, program_data_js_1.decodeProgramDataLine)(log);
@@ -277,12 +282,12 @@ function parseLogOptimized(log, signature, slot, txIndex, blockTimeUs, grpcRecvU
277
282
  case program_log_discriminators_js_1.PROGRAM_LOG_DISC.METEORA_DAMM_CLOSE_POSITION:
278
283
  return (0, meteora_damm_js_1.parseMeteoraDammLog)(log, signature, slot, txIndex, blockTimeUs, grpcRecvUs);
279
284
  default: {
280
- const bonk = (0, raydium_launchpad_js_1.parseBonkFromDiscriminator)(disc, data, metadata);
281
- if (bonk)
282
- return bonk;
285
+ const raydium_launchlab = (0, raydium_launchlab_js_1.parseRaydiumLaunchlabFromDiscriminator)(disc, data, metadata);
286
+ if (raydium_launchlab)
287
+ return applyActualEventTypeFilter(raydium_launchlab, eventTypeFilter);
283
288
  const dlmm = (0, meteora_dlmm_js_1.parseDlmmFromDecoded)(buf, metadata);
284
289
  if (dlmm)
285
- return dlmm;
290
+ return applyActualEventTypeFilter(dlmm, eventTypeFilter);
286
291
  return null;
287
292
  }
288
293
  }