sol-parser-sdk-nodejs 0.3.0 → 0.4.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 (93) hide show
  1. package/.env.example +24 -0
  2. package/README.md +94 -352
  3. package/README_CN.md +101 -253
  4. package/dist/accounts/mod.d.ts +2 -0
  5. package/dist/accounts/mod.js +5 -1
  6. package/dist/accounts/rpc_wallet.d.ts +5 -0
  7. package/dist/accounts/rpc_wallet.js +18 -0
  8. package/dist/accounts/rust_aliases.d.ts +9 -0
  9. package/dist/accounts/rust_aliases.js +19 -0
  10. package/dist/accounts/wallet_resolve.d.ts +1 -0
  11. package/dist/accounts/wallet_resolve.js +28 -0
  12. package/dist/common/constants.d.ts +10 -0
  13. package/dist/common/constants.js +13 -0
  14. package/dist/core/account_dispatcher_rpc.js +26 -5
  15. package/dist/core/account_fill_meteora.d.ts +4 -2
  16. package/dist/core/account_fill_meteora.js +5 -2
  17. package/dist/core/account_pubkey_cache.d.ts +12 -0
  18. package/dist/core/account_pubkey_cache.js +26 -0
  19. package/dist/core/clock.d.ts +6 -0
  20. package/dist/core/clock.js +13 -0
  21. package/dist/core/dex_event.d.ts +25 -44
  22. package/dist/core/metadata.d.ts +1 -0
  23. package/dist/core/unified_parser.d.ts +2 -2
  24. package/dist/core/unified_parser.js +6 -6
  25. package/dist/grpc/client.d.ts +6 -0
  26. package/dist/grpc/client.js +121 -64
  27. package/dist/grpc/event_parser.d.ts +6 -0
  28. package/dist/grpc/event_parser.js +15 -0
  29. package/dist/grpc/geyser_connect.d.ts +30 -0
  30. package/dist/grpc/geyser_connect.js +40 -0
  31. package/dist/grpc/program_ids.d.ts +25 -0
  32. package/dist/grpc/program_ids.js +54 -0
  33. package/dist/grpc/rpc_to_grpc.d.ts +18 -0
  34. package/dist/grpc/rpc_to_grpc.js +127 -0
  35. package/dist/grpc/subscribe_builder.d.ts +13 -0
  36. package/dist/grpc/subscribe_builder.js +66 -0
  37. package/dist/grpc/transaction_meta.d.ts +29 -0
  38. package/dist/grpc/transaction_meta.js +208 -0
  39. package/dist/grpc/types.d.ts +53 -2
  40. package/dist/grpc/types.js +98 -7
  41. package/dist/grpc/yellowstone_parse.d.ts +5 -0
  42. package/dist/grpc/yellowstone_parse.js +15 -2
  43. package/dist/index.d.ts +36 -6
  44. package/dist/index.js +172 -2
  45. package/dist/instr/bonk_ix.d.ts +4 -1
  46. package/dist/instr/bonk_ix.js +106 -27
  47. package/dist/instr/meteora_damm_ix.d.ts +4 -2
  48. package/dist/instr/meteora_damm_ix.js +248 -13
  49. package/dist/instr/mod.js +7 -2
  50. package/dist/instr/orca_whirlpool_ix.d.ts +4 -1
  51. package/dist/instr/orca_whirlpool_ix.js +45 -16
  52. package/dist/instr/program_ids.d.ts +7 -13
  53. package/dist/instr/program_ids.js +19 -15
  54. package/dist/instr/pumpswap_ix.d.ts +1 -1
  55. package/dist/instr/pumpswap_ix.js +78 -57
  56. package/dist/instr/raydium_amm_v4_ix.d.ts +1 -1
  57. package/dist/instr/raydium_amm_v4_ix.js +94 -28
  58. package/dist/instr/raydium_clmm_ix.d.ts +1 -1
  59. package/dist/instr/raydium_clmm_ix.js +59 -26
  60. package/dist/instr/raydium_cpmm_ix.d.ts +1 -1
  61. package/dist/instr/raydium_cpmm_ix.js +46 -12
  62. package/dist/instr/rust_aliases.d.ts +7 -0
  63. package/dist/instr/rust_aliases.js +14 -0
  64. package/dist/instr/utils.d.ts +1 -1
  65. package/dist/instr/utils.js +2 -1
  66. package/dist/logs/discriminator_lut.d.ts +19 -0
  67. package/dist/logs/discriminator_lut.js +60 -0
  68. package/dist/logs/meteora_damm.d.ts +3 -4
  69. package/dist/logs/meteora_damm.js +3 -369
  70. package/dist/logs/optimized_matcher.d.ts +2 -2
  71. package/dist/logs/optimized_matcher.js +3 -3
  72. package/dist/logs/rust_aliases.d.ts +6 -0
  73. package/dist/logs/rust_aliases.js +13 -0
  74. package/dist/rpc_parser.d.ts +1 -0
  75. package/dist/rpc_parser.js +4 -1
  76. package/dist/shredstream/alt_lookup.d.ts +9 -0
  77. package/dist/shredstream/alt_lookup.js +70 -0
  78. package/dist/shredstream/client.d.ts +62 -0
  79. package/dist/shredstream/client.js +399 -0
  80. package/dist/shredstream/config.d.ts +30 -0
  81. package/dist/shredstream/config.js +34 -0
  82. package/dist/shredstream/entries_decode.d.ts +28 -0
  83. package/dist/shredstream/entries_decode.js +251 -0
  84. package/dist/shredstream/index.d.ts +17 -0
  85. package/dist/shredstream/index.js +33 -0
  86. package/dist/shredstream/instruction_parse.d.ts +34 -0
  87. package/dist/shredstream/instruction_parse.js +47 -0
  88. package/dist/shredstream/proto_types.d.ts +9 -0
  89. package/dist/shredstream/proto_types.js +2 -0
  90. package/dist/shredstream/shredstream.proto +15 -0
  91. package/dist/shredstream/wire_to_shred_tx.d.ts +2 -0
  92. package/dist/shredstream/wire_to_shred_tx.js +59 -0
  93. package/package.json +28 -11
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseMeteoraDammInstruction = parseMeteoraDammInstruction;
4
4
  const dex_event_js_1 = require("../core/dex_event.js");
5
- const meteora_damm_js_1 = require("../logs/meteora_damm.js");
6
5
  const utils_js_1 = require("./utils.js");
7
6
  const Z = (0, dex_event_js_1.defaultPubkey)();
8
7
  function disc8(a) {
@@ -15,8 +14,28 @@ const CPI = {
15
14
  CLOSE_POSITION_LOG: disc8([20, 145, 144, 68, 143, 142, 214, 178]),
16
15
  ADD_LIQUIDITY_LOG: disc8([175, 242, 8, 157, 30, 247, 185, 169]),
17
16
  REMOVE_LIQUIDITY_LOG: disc8([87, 46, 88, 98, 175, 96, 34, 91]),
18
- INITIALIZE_POOL_LOG: disc8([228, 50, 246, 85, 203, 66, 134, 37]),
19
17
  };
18
+ /** 与 cp_amm Anchor IDL `instructions[].discriminator` 一致(用户直接调用的外层指令) */
19
+ const ANCHOR = {
20
+ SWAP: disc8([248, 198, 158, 145, 225, 117, 135, 200]),
21
+ /** `swap2` — `SwapParameters2`(amount_0, amount_1, swap_mode) */
22
+ SWAP2: disc8([65, 75, 63, 76, 235, 91, 91, 136]),
23
+ ADD_LIQUIDITY: disc8([181, 157, 89, 67, 143, 182, 52, 72]),
24
+ REMOVE_LIQUIDITY: disc8([80, 85, 209, 72, 24, 206, 177, 108]),
25
+ REMOVE_ALL_LIQUIDITY: disc8([10, 51, 61, 35, 112, 105, 24, 85]),
26
+ INITIALIZE_POOL: disc8([95, 180, 10, 172, 84, 174, 232, 40]),
27
+ /** `create_position` / `close_position` 无额外 Borsh 参数,仅 8 字节 disc */
28
+ CREATE_POSITION: disc8([48, 215, 197, 153, 96, 203, 180, 133]),
29
+ CLOSE_POSITION: disc8([123, 134, 81, 0, 49, 68, 98, 98]),
30
+ };
31
+ function headEq(data, disc) {
32
+ if (data.length < 8)
33
+ return false;
34
+ for (let i = 0; i < 8; i++)
35
+ if (data[i] !== disc[i])
36
+ return false;
37
+ return true;
38
+ }
20
39
  function discEq(h, d) {
21
40
  for (let i = 0; i < 8; i++)
22
41
  if (h[i] !== d[i])
@@ -33,7 +52,200 @@ function vaults() {
33
52
  token_b_program: Z,
34
53
  };
35
54
  }
36
- function parseSwapCpi(data, meta) {
55
+ /**
56
+ * cp_amm 外层 `swap` / `swap2` 账户顺序(见 `idls/meteora_damm_v2.json`):
57
+ * 0 pool_authority, 1 pool, 2 input_token_account, 3 output_token_account,
58
+ * 4 token_a_vault, 5 token_b_vault, 6–7 mints, 8 payer, 9–10 token programs;
59
+ * 11 起为可选 referral、event_authority、program 等。
60
+ */
61
+ function meteoraSwapVaultsFromAccounts(accounts) {
62
+ if (accounts.length < 11) {
63
+ return vaults();
64
+ }
65
+ return {
66
+ token_a_vault: (0, utils_js_1.getAccount)(accounts, 4) ?? Z,
67
+ token_b_vault: (0, utils_js_1.getAccount)(accounts, 5) ?? Z,
68
+ token_a_mint: (0, utils_js_1.getAccount)(accounts, 6) ?? Z,
69
+ token_b_mint: (0, utils_js_1.getAccount)(accounts, 7) ?? Z,
70
+ token_a_program: (0, utils_js_1.getAccount)(accounts, 9) ?? Z,
71
+ token_b_program: (0, utils_js_1.getAccount)(accounts, 10) ?? Z,
72
+ };
73
+ }
74
+ /**
75
+ * 外层 `swap`:`SwapParameters` = amount_in (u64) + minimum_amount_out (u64)。
76
+ * 成交额、手续费、`next_sqrt_price` 等仅在程序 `emit!`(日志 / 内联 CPI 载荷)中;**仅解析外层指令时这些字段保持 0**(与无日志的 ShredStream 一致)。
77
+ */
78
+ function parseOuterSwapIx(instructionData, accounts, meta) {
79
+ const amount_in = (0, utils_js_1.readU64LE)(instructionData, 8) ?? 0n;
80
+ const minimum_amount_out = (0, utils_js_1.readU64LE)(instructionData, 16) ?? 0n;
81
+ const pool = (0, utils_js_1.getAccount)(accounts, 1) ?? Z;
82
+ const ev = {
83
+ metadata: meta,
84
+ pool,
85
+ trade_direction: 0,
86
+ has_referral: false,
87
+ amount_in,
88
+ minimum_amount_out,
89
+ output_amount: 0n,
90
+ next_sqrt_price: 0n,
91
+ lp_fee: 0n,
92
+ protocol_fee: 0n,
93
+ partner_fee: 0n,
94
+ referral_fee: 0n,
95
+ actual_amount_in: amount_in,
96
+ current_timestamp: 0n,
97
+ ...meteoraSwapVaultsFromAccounts(accounts),
98
+ };
99
+ return { MeteoraDammV2Swap: ev };
100
+ }
101
+ /** 外层 `swap2`:`SwapParameters2` = amount_0 + amount_1 + swap_mode (u8) */
102
+ function parseOuterSwap2Ix(instructionData, accounts, meta) {
103
+ if (instructionData.length < 25)
104
+ return null;
105
+ const amount_0 = (0, utils_js_1.readU64LE)(instructionData, 8) ?? 0n;
106
+ const amount_1 = (0, utils_js_1.readU64LE)(instructionData, 16) ?? 0n;
107
+ const swap_mode = (0, utils_js_1.readU8)(instructionData, 24);
108
+ if (swap_mode === null)
109
+ return null;
110
+ const [amount_in, minimum_amount_out] = swap_mode === 0 ? [amount_0, amount_1] : [amount_1, amount_0];
111
+ const pool = (0, utils_js_1.getAccount)(accounts, 1) ?? Z;
112
+ const ev = {
113
+ metadata: meta,
114
+ pool,
115
+ trade_direction: 0,
116
+ has_referral: false,
117
+ amount_in,
118
+ minimum_amount_out,
119
+ output_amount: 0n,
120
+ next_sqrt_price: 0n,
121
+ lp_fee: 0n,
122
+ protocol_fee: 0n,
123
+ partner_fee: 0n,
124
+ referral_fee: 0n,
125
+ actual_amount_in: amount_in,
126
+ current_timestamp: 0n,
127
+ ...meteoraSwapVaultsFromAccounts(accounts),
128
+ };
129
+ return { MeteoraDammV2Swap: ev };
130
+ }
131
+ /** 外层 `add_liquidity`:`AddLiquidityParameters` = u128 + u64 + u64;pool(0), position(1), owner(9) */
132
+ function parseOuterAddLiquidityIx(instructionData, accounts, meta) {
133
+ const liquidity_delta = (0, utils_js_1.readU128LE)(instructionData, 8) ?? 0n;
134
+ const token_a_amount_threshold = (0, utils_js_1.readU64LE)(instructionData, 24) ?? 0n;
135
+ const token_b_amount_threshold = (0, utils_js_1.readU64LE)(instructionData, 32) ?? 0n;
136
+ return {
137
+ MeteoraDammV2AddLiquidity: {
138
+ metadata: meta,
139
+ pool: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
140
+ position: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
141
+ owner: (0, utils_js_1.getAccount)(accounts, 9) ?? Z,
142
+ liquidity_delta,
143
+ token_a_amount_threshold,
144
+ token_b_amount_threshold,
145
+ token_a_amount: 0n,
146
+ token_b_amount: 0n,
147
+ total_amount_a: 0n,
148
+ total_amount_b: 0n,
149
+ },
150
+ };
151
+ }
152
+ /** 外层 `remove_all_liquidity`:两 u64 阈值;账户顺序同 `remove_liquidity` */
153
+ function parseOuterRemoveAllLiquidityIx(instructionData, accounts, meta) {
154
+ const token_a_amount_threshold = (0, utils_js_1.readU64LE)(instructionData, 8) ?? 0n;
155
+ const token_b_amount_threshold = (0, utils_js_1.readU64LE)(instructionData, 16) ?? 0n;
156
+ return {
157
+ MeteoraDammV2RemoveAllLiquidity: {
158
+ metadata: meta,
159
+ pool: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
160
+ position: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
161
+ owner: (0, utils_js_1.getAccount)(accounts, 10) ?? Z,
162
+ token_a_amount_threshold,
163
+ token_b_amount_threshold,
164
+ },
165
+ };
166
+ }
167
+ /** 外层 `initialize_pool`:`InitializePoolParameters` = u128 + u128 + Option(u64);creator(0), pool(6), position(7), mints(8,9) */
168
+ function parseOuterInitializePoolIx(instructionData, accounts, meta) {
169
+ if (instructionData.length < 41)
170
+ return null;
171
+ const liquidity = (0, utils_js_1.readU128LE)(instructionData, 8) ?? 0n;
172
+ const sqrt_price = (0, utils_js_1.readU128LE)(instructionData, 24) ?? 0n;
173
+ const tag = (0, utils_js_1.readU8)(instructionData, 40);
174
+ if (tag === null)
175
+ return null;
176
+ let activation_point = null;
177
+ if (tag === 1) {
178
+ if (instructionData.length < 49)
179
+ return null;
180
+ activation_point = (0, utils_js_1.readU64LE)(instructionData, 41) ?? 0n;
181
+ }
182
+ else if (tag !== 0)
183
+ return null;
184
+ if (accounts.length < 10)
185
+ return null;
186
+ return {
187
+ MeteoraDammV2InitializePool: {
188
+ metadata: meta,
189
+ creator: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
190
+ position_nft_mint: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
191
+ pool: (0, utils_js_1.getAccount)(accounts, 6) ?? Z,
192
+ position: (0, utils_js_1.getAccount)(accounts, 7) ?? Z,
193
+ token_a_mint: (0, utils_js_1.getAccount)(accounts, 8) ?? Z,
194
+ token_b_mint: (0, utils_js_1.getAccount)(accounts, 9) ?? Z,
195
+ liquidity,
196
+ sqrt_price,
197
+ activation_point,
198
+ },
199
+ };
200
+ }
201
+ /** 外层 `remove_liquidity`:同上 Borsh;pool_authority(0), pool(1), position(2), owner(10) */
202
+ function parseOuterRemoveLiquidityIx(instructionData, accounts, meta) {
203
+ const liquidity_delta = (0, utils_js_1.readU128LE)(instructionData, 8) ?? 0n;
204
+ const token_a_amount_threshold = (0, utils_js_1.readU64LE)(instructionData, 24) ?? 0n;
205
+ const token_b_amount_threshold = (0, utils_js_1.readU64LE)(instructionData, 32) ?? 0n;
206
+ return {
207
+ MeteoraDammV2RemoveLiquidity: {
208
+ metadata: meta,
209
+ pool: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
210
+ position: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
211
+ owner: (0, utils_js_1.getAccount)(accounts, 10) ?? Z,
212
+ liquidity_delta,
213
+ token_a_amount_threshold,
214
+ token_b_amount_threshold,
215
+ token_a_amount: 0n,
216
+ token_b_amount: 0n,
217
+ },
218
+ };
219
+ }
220
+ /** 外层 `create_position`:无 args;owner(0), position_nft_mint(1), position_nft_account(2), pool(3), position(4) */
221
+ function parseOuterCreatePositionIx(accounts, meta) {
222
+ if (accounts.length < 5)
223
+ return null;
224
+ return {
225
+ MeteoraDammV2CreatePosition: {
226
+ metadata: meta,
227
+ owner: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
228
+ position_nft_mint: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
229
+ pool: (0, utils_js_1.getAccount)(accounts, 3) ?? Z,
230
+ position: (0, utils_js_1.getAccount)(accounts, 4) ?? Z,
231
+ },
232
+ };
233
+ }
234
+ /** 外层 `close_position`:无 args;position_nft_mint(0), …, pool(2), position(3), …, owner(6) */
235
+ function parseOuterClosePositionIx(accounts, meta) {
236
+ if (accounts.length < 7)
237
+ return null;
238
+ return {
239
+ MeteoraDammV2ClosePosition: {
240
+ metadata: meta,
241
+ position_nft_mint: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
242
+ pool: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
243
+ position: (0, utils_js_1.getAccount)(accounts, 3) ?? Z,
244
+ owner: (0, utils_js_1.getAccount)(accounts, 6) ?? Z,
245
+ },
246
+ };
247
+ }
248
+ function parseSwapCpi(data, accounts, meta) {
37
249
  let o = 0;
38
250
  const pool = (0, utils_js_1.readPubkeyIx)(data, o);
39
251
  if (!pool)
@@ -101,11 +313,11 @@ function parseSwapCpi(data, meta) {
101
313
  referral_fee,
102
314
  actual_amount_in,
103
315
  current_timestamp,
104
- ...vaults(),
316
+ ...meteoraSwapVaultsFromAccounts(accounts),
105
317
  };
106
318
  return { MeteoraDammV2Swap: ev };
107
319
  }
108
- function parseSwap2Cpi(data, meta) {
320
+ function parseSwap2Cpi(data, accounts, meta) {
109
321
  let o = 0;
110
322
  const pool = (0, utils_js_1.readPubkeyIx)(data, o);
111
323
  if (!pool)
@@ -182,20 +394,46 @@ function parseSwap2Cpi(data, meta) {
182
394
  referral_fee,
183
395
  actual_amount_in: included_fee_input_amount,
184
396
  current_timestamp,
185
- ...vaults(),
397
+ ...meteoraSwapVaultsFromAccounts(accounts),
186
398
  };
187
399
  return { MeteoraDammV2Swap: ev };
188
400
  }
189
- function parseMeteoraDammInstruction(instructionData, _accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs) {
401
+ function parseMeteoraDammInstruction(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs) {
402
+ if (instructionData.length < 8)
403
+ return null;
404
+ const meta = (0, utils_js_1.ixMeta)(signature, slot, txIndex, blockTimeUs, grpcRecvUs);
405
+ if (instructionData.length >= 24 && headEq(instructionData, ANCHOR.SWAP)) {
406
+ return parseOuterSwapIx(instructionData, accounts, meta);
407
+ }
408
+ if (instructionData.length >= 25 && headEq(instructionData, ANCHOR.SWAP2)) {
409
+ return parseOuterSwap2Ix(instructionData, accounts, meta);
410
+ }
411
+ if (instructionData.length >= 41 && headEq(instructionData, ANCHOR.INITIALIZE_POOL)) {
412
+ return parseOuterInitializePoolIx(instructionData, accounts, meta);
413
+ }
414
+ if (instructionData.length >= 40 && headEq(instructionData, ANCHOR.ADD_LIQUIDITY)) {
415
+ return parseOuterAddLiquidityIx(instructionData, accounts, meta);
416
+ }
417
+ if (instructionData.length >= 40 && headEq(instructionData, ANCHOR.REMOVE_LIQUIDITY)) {
418
+ return parseOuterRemoveLiquidityIx(instructionData, accounts, meta);
419
+ }
420
+ if (instructionData.length >= 24 && headEq(instructionData, ANCHOR.REMOVE_ALL_LIQUIDITY)) {
421
+ return parseOuterRemoveAllLiquidityIx(instructionData, accounts, meta);
422
+ }
423
+ if (instructionData.length >= 8 && headEq(instructionData, ANCHOR.CREATE_POSITION)) {
424
+ return parseOuterCreatePositionIx(accounts, meta);
425
+ }
426
+ if (instructionData.length >= 8 && headEq(instructionData, ANCHOR.CLOSE_POSITION)) {
427
+ return parseOuterClosePositionIx(accounts, meta);
428
+ }
190
429
  if (instructionData.length < 16)
191
430
  return null;
192
431
  const cpiHead = instructionData.subarray(8, 16);
193
432
  const cpiData = instructionData.subarray(16);
194
- const meta = (0, utils_js_1.ixMeta)(signature, slot, txIndex, blockTimeUs, grpcRecvUs);
195
433
  if (discEq(cpiHead, CPI.SWAP_LOG))
196
- return parseSwapCpi(cpiData, meta);
434
+ return parseSwapCpi(cpiData, accounts, meta);
197
435
  if (discEq(cpiHead, CPI.SWAP2_LOG))
198
- return parseSwap2Cpi(cpiData, meta);
436
+ return parseSwap2Cpi(cpiData, accounts, meta);
199
437
  if (discEq(cpiHead, CPI.CREATE_POSITION_LOG)) {
200
438
  let o = 0;
201
439
  const pool = (0, utils_js_1.readPubkeyIx)(cpiData, o);
@@ -342,8 +580,5 @@ function parseMeteoraDammInstruction(instructionData, _accounts, signature, slot
342
580
  },
343
581
  };
344
582
  }
345
- if (discEq(cpiHead, CPI.INITIALIZE_POOL_LOG)) {
346
- return (0, meteora_damm_js_1.parseInitializePoolEvent)(cpiData, meta);
347
- }
348
583
  return null;
349
584
  }
package/dist/instr/mod.js CHANGED
@@ -26,6 +26,11 @@ const raydium_cpmm_ix_js_1 = require("./raydium_cpmm_ix.js");
26
26
  const raydium_amm_v4_ix_js_1 = require("./raydium_amm_v4_ix.js");
27
27
  const orca_whirlpool_ix_js_1 = require("./orca_whirlpool_ix.js");
28
28
  const bonk_ix_js_1 = require("./bonk_ix.js");
29
+ function isBonkProgram(programId) {
30
+ return (programId === program_ids_js_1.BONK_PROGRAM_ID ||
31
+ programId === program_ids_js_1.BONK_LAUNCHPAD_PROGRAM_ID ||
32
+ programId === program_ids_js_1.BONK_PROGRAM_ID_LEGACY);
33
+ }
29
34
  var pumpfun_ix_js_2 = require("./pumpfun_ix.js");
30
35
  Object.defineProperty(exports, "parsePumpfunInstruction", { enumerable: true, get: function () { return pumpfun_ix_js_2.parsePumpfunInstruction; } });
31
36
  var pumpswap_ix_js_2 = require("./pumpswap_ix.js");
@@ -59,7 +64,7 @@ function parseInstructionUnified(instructionData, accounts, signature, slot, txI
59
64
  if (programId === program_ids_js_1.PUMPSWAP_PROGRAM_ID) {
60
65
  if (eventTypeFilter && !(0, types_js_1.eventTypeFilterIncludesPumpswap)(eventTypeFilter))
61
66
  return null;
62
- return (0, pumpswap_ix_js_1.parsePumpswapInstruction)(instructionData, accounts, signature, slot, txIndex, blockTimeUs);
67
+ return (0, pumpswap_ix_js_1.parsePumpswapInstruction)(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs);
63
68
  }
64
69
  if (programId === program_ids_js_1.METEORA_DAMM_V2_PROGRAM_ID) {
65
70
  if (eventTypeFilter && !(0, types_js_1.eventTypeFilterIncludesMeteoraDammV2)(eventTypeFilter))
@@ -86,7 +91,7 @@ function parseInstructionUnified(instructionData, accounts, signature, slot, txI
86
91
  return null;
87
92
  return (0, orca_whirlpool_ix_js_1.parseOrcaWhirlpoolInstruction)(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs);
88
93
  }
89
- if (programId === program_ids_js_1.BONK_LAUNCHPAD_PROGRAM_ID) {
94
+ if (isBonkProgram(programId)) {
90
95
  if (eventTypeFilter && !(0, types_js_1.eventTypeFilterIncludesBonk)(eventTypeFilter))
91
96
  return null;
92
97
  return (0, bonk_ix_js_1.parseBonkInstruction)(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs);
@@ -1,5 +1,8 @@
1
1
  /**
2
- * Orca Whirlpool 指令解析
2
+ * Orca Whirlpool 指令解析(Anchor swap / 增减流动性)
3
+ *
4
+ * 注意:链上指令 discriminator 与 `emit!` 的 Program data 日志 discriminator 不同;
5
+ * Whirlpool 的 `swap` / `increase_liquidity_v2` / `decrease_liquidity` 与 Raydium CLMM 同源,复用同一组 Anchor 前 8 字节。
3
6
  */
4
7
  import type { DexEvent } from "../core/dex_event.js";
5
8
  export declare function parseOrcaWhirlpoolInstruction(instructionData: Uint8Array, accounts: string[], signature: string, slot: number, txIndex: number, blockTimeUs: number | undefined, grpcRecvUs: number): DexEvent | null;
@@ -2,13 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseOrcaWhirlpoolInstruction = parseOrcaWhirlpoolInstruction;
4
4
  const dex_event_js_1 = require("../core/dex_event.js");
5
+ const program_log_discriminators_js_1 = require("../logs/program_log_discriminators.js");
5
6
  const utils_js_1 = require("./utils.js");
6
7
  const Z = (0, dex_event_js_1.defaultPubkey)();
7
- // Discriminators (little-endian u64)
8
8
  const DISC = {
9
- SWAP: 10853759504616839521n, // disc8(225, 202, 73, 175, 147, 43, 160, 150)
10
- INCREASE_LIQUIDITY: 11605574446925869086n, // disc8(30, 7, 144, 181, 102, 254, 155, 161)
11
- DECREASE_LIQUIDITY: 12404363784710077478n, // disc8(166, 1, 36, 71, 112, 202, 181, 171)
9
+ SWAP: program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CLMM_SWAP,
10
+ INCREASE_LIQUIDITY: program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CLMM_INCREASE_LIQUIDITY,
11
+ DECREASE_LIQUIDITY: program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CLMM_DECREASE_LIQUIDITY,
12
12
  };
13
13
  function discEq(data, disc) {
14
14
  if (data.length < 8)
@@ -16,20 +16,37 @@ function discEq(data, disc) {
16
16
  const v = (0, utils_js_1.readU64LE)(data, 0);
17
17
  return v === disc;
18
18
  }
19
+ const SWAP_ACC = {
20
+ WHIRLPOOL: 2,
21
+ SENDER: 1,
22
+ TOKEN_A_USER: 3,
23
+ TOKEN_B_USER: 5,
24
+ };
19
25
  function parseOrcaWhirlpoolInstruction(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs) {
20
26
  if (instructionData.length < 8)
21
27
  return null;
22
28
  const meta = (0, utils_js_1.ixMeta)(signature, slot, txIndex, blockTimeUs, grpcRecvUs);
23
29
  if (discEq(instructionData, DISC.SWAP)) {
30
+ if (instructionData.length < 42)
31
+ return null;
32
+ const amount = (0, utils_js_1.readU64LE)(instructionData, 8) ?? 0n;
33
+ const other_threshold = (0, utils_js_1.readU64LE)(instructionData, 16) ?? 0n;
34
+ const sqrt_price_limit = (0, utils_js_1.readU128LE)(instructionData, 24) ?? 0n;
35
+ const amount_specified_is_input = (0, utils_js_1.readBool)(instructionData, 40);
36
+ const a_to_b = (0, utils_js_1.readBool)(instructionData, 41);
37
+ if (amount_specified_is_input === null || a_to_b === null)
38
+ return null;
39
+ const input_amount = amount_specified_is_input ? amount : other_threshold;
40
+ const output_amount = amount_specified_is_input ? other_threshold : amount;
24
41
  return {
25
42
  OrcaWhirlpoolSwap: {
26
43
  metadata: meta,
27
- whirlpool: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
28
- a_to_b: true,
44
+ whirlpool: (0, utils_js_1.getAccount)(accounts, SWAP_ACC.WHIRLPOOL) ?? Z,
45
+ a_to_b,
29
46
  pre_sqrt_price: 0n,
30
47
  post_sqrt_price: 0n,
31
- input_amount: 0n,
32
- output_amount: 0n,
48
+ input_amount,
49
+ output_amount,
33
50
  input_transfer_fee: 0n,
34
51
  output_transfer_fee: 0n,
35
52
  lp_fee: 0n,
@@ -38,32 +55,44 @@ function parseOrcaWhirlpoolInstruction(instructionData, accounts, signature, slo
38
55
  };
39
56
  }
40
57
  if (discEq(instructionData, DISC.INCREASE_LIQUIDITY)) {
58
+ // increase_liquidity_v2:liquidity_amount (u128), token_max_a, token_max_b
59
+ if (instructionData.length < 8 + 16 + 8 + 8)
60
+ return null;
61
+ const liquidity = (0, utils_js_1.readU128LE)(instructionData, 8) ?? 0n;
62
+ const token_max_a = (0, utils_js_1.readU64LE)(instructionData, 24) ?? 0n;
63
+ const token_max_b = (0, utils_js_1.readU64LE)(instructionData, 32) ?? 0n;
41
64
  return {
42
65
  OrcaWhirlpoolLiquidityIncreased: {
43
66
  metadata: meta,
44
- whirlpool: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
67
+ whirlpool: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
45
68
  position: (0, utils_js_1.getAccount)(accounts, 3) ?? Z,
46
69
  tick_lower_index: 0,
47
70
  tick_upper_index: 0,
48
- liquidity: 0n,
49
- token_a_amount: 0n,
50
- token_b_amount: 0n,
71
+ liquidity,
72
+ token_a_amount: token_max_a,
73
+ token_b_amount: token_max_b,
51
74
  token_a_transfer_fee: 0n,
52
75
  token_b_transfer_fee: 0n,
53
76
  },
54
77
  };
55
78
  }
56
79
  if (discEq(instructionData, DISC.DECREASE_LIQUIDITY)) {
80
+ // decrease_liquidity:liquidity_amount (u128), token_min_a, token_min_b
81
+ if (instructionData.length < 8 + 16 + 8 + 8)
82
+ return null;
83
+ const liquidity = (0, utils_js_1.readU128LE)(instructionData, 8) ?? 0n;
84
+ const token_min_a = (0, utils_js_1.readU64LE)(instructionData, 24) ?? 0n;
85
+ const token_min_b = (0, utils_js_1.readU64LE)(instructionData, 32) ?? 0n;
57
86
  return {
58
87
  OrcaWhirlpoolLiquidityDecreased: {
59
88
  metadata: meta,
60
- whirlpool: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
89
+ whirlpool: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
61
90
  position: (0, utils_js_1.getAccount)(accounts, 3) ?? Z,
62
91
  tick_lower_index: 0,
63
92
  tick_upper_index: 0,
64
- liquidity: 0n,
65
- token_a_amount: 0n,
66
- token_b_amount: 0n,
93
+ liquidity,
94
+ token_a_amount: token_min_a,
95
+ token_b_amount: token_min_b,
67
96
  token_a_transfer_fee: 0n,
68
97
  token_b_transfer_fee: 0n,
69
98
  },
@@ -1,14 +1,8 @@
1
- /** 各 DEX 程序 ID(Base58) */
2
- export declare const PUMPFUN_PROGRAM_ID = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P";
3
- /** Pump AMM(PumpSwap),与 `sol-parser-sdk` / `pump_amm.json` 一致 */
4
- export declare const PUMPSWAP_PROGRAM_ID = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA";
5
- export declare const METEORA_DAMM_V2_PROGRAM_ID = "cpamdpZCGKUy5JxQXB2MWgCm3hcnGjEJbYTJgfm4E8a";
6
- export declare const RAYDIUM_CLMM_PROGRAM_ID = "CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK";
7
- export declare const RAYDIUM_CPMM_PROGRAM_ID = "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C";
8
- export declare const RAYDIUM_AMM_V4_PROGRAM_ID = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8";
9
- export declare const ORCA_WHIRLPOOL_PROGRAM_ID = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc";
1
+ /**
2
+ * DEX 程序 ID(Base58)。与 Rust 对齐的常量来自 `grpc/program_ids.ts`。
3
+ */
4
+ export { PUMPFUN_PROGRAM_ID, PUMPSWAP_PROGRAM_ID, PUMPSWAP_FEES_PROGRAM_ID, BONK_PROGRAM_ID, RAYDIUM_CPMM_PROGRAM_ID, RAYDIUM_CLMM_PROGRAM_ID, RAYDIUM_AMM_V4_PROGRAM_ID, ORCA_WHIRLPOOL_PROGRAM_ID, METEORA_POOLS_PROGRAM_ID, METEORA_DAMM_V2_PROGRAM_ID, METEORA_DLMM_PROGRAM_ID, } from "../grpc/program_ids.js";
5
+ /** Launchpad 等场景使用的程序 ID(非 Rust `Protocol` 映射项) */
10
6
  export declare const BONK_LAUNCHPAD_PROGRAM_ID = "LanCh3hDdY7M6x8urBSLJhsQBgPNGKHNqJqGwzAEmBm";
11
- export declare const BONK_PROGRAM_ID = "DjVE6JNiYqPL2QXyCUUh8rNjHrbz9hXHNYt99MQ59qw1";
12
- export declare const PUMPSWAP_FEES_PROGRAM_ID = "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ";
13
- export declare const METEORA_POOLS_PROGRAM_ID = "Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB";
14
- export declare const METEORA_DLMM_PROGRAM_ID = "LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo";
7
+ /** 旧版 TS 包中的 Bonk ID,仅作兼容保留 */
8
+ export declare const BONK_PROGRAM_ID_LEGACY = "DjVE6JNiYqPL2QXyCUUh8rNjHrbz9hXHNYt99MQ59qw1";
@@ -1,18 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.METEORA_DLMM_PROGRAM_ID = exports.METEORA_POOLS_PROGRAM_ID = exports.PUMPSWAP_FEES_PROGRAM_ID = exports.BONK_PROGRAM_ID = exports.BONK_LAUNCHPAD_PROGRAM_ID = exports.ORCA_WHIRLPOOL_PROGRAM_ID = exports.RAYDIUM_AMM_V4_PROGRAM_ID = exports.RAYDIUM_CPMM_PROGRAM_ID = exports.RAYDIUM_CLMM_PROGRAM_ID = exports.METEORA_DAMM_V2_PROGRAM_ID = exports.PUMPSWAP_PROGRAM_ID = exports.PUMPFUN_PROGRAM_ID = void 0;
4
- /** 各 DEX 程序 ID(Base58) */
5
- exports.PUMPFUN_PROGRAM_ID = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P";
6
- /** Pump AMM(PumpSwap),与 `sol-parser-sdk` / `pump_amm.json` 一致 */
7
- exports.PUMPSWAP_PROGRAM_ID = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA";
8
- exports.METEORA_DAMM_V2_PROGRAM_ID = "cpamdpZCGKUy5JxQXB2MWgCm3hcnGjEJbYTJgfm4E8a";
9
- exports.RAYDIUM_CLMM_PROGRAM_ID = "CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK";
10
- exports.RAYDIUM_CPMM_PROGRAM_ID = "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C";
11
- exports.RAYDIUM_AMM_V4_PROGRAM_ID = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8";
12
- exports.ORCA_WHIRLPOOL_PROGRAM_ID = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc";
3
+ exports.BONK_PROGRAM_ID_LEGACY = exports.BONK_LAUNCHPAD_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.BONK_PROGRAM_ID = exports.PUMPSWAP_FEES_PROGRAM_ID = exports.PUMPSWAP_PROGRAM_ID = exports.PUMPFUN_PROGRAM_ID = void 0;
4
+ /**
5
+ * 各 DEX 程序 ID(Base58)。与 Rust 对齐的常量来自 `grpc/program_ids.ts`。
6
+ */
7
+ var program_ids_js_1 = require("../grpc/program_ids.js");
8
+ Object.defineProperty(exports, "PUMPFUN_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.PUMPFUN_PROGRAM_ID; } });
9
+ Object.defineProperty(exports, "PUMPSWAP_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.PUMPSWAP_PROGRAM_ID; } });
10
+ Object.defineProperty(exports, "PUMPSWAP_FEES_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.PUMPSWAP_FEES_PROGRAM_ID; } });
11
+ Object.defineProperty(exports, "BONK_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.BONK_PROGRAM_ID; } });
12
+ Object.defineProperty(exports, "RAYDIUM_CPMM_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.RAYDIUM_CPMM_PROGRAM_ID; } });
13
+ Object.defineProperty(exports, "RAYDIUM_CLMM_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.RAYDIUM_CLMM_PROGRAM_ID; } });
14
+ Object.defineProperty(exports, "RAYDIUM_AMM_V4_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.RAYDIUM_AMM_V4_PROGRAM_ID; } });
15
+ Object.defineProperty(exports, "ORCA_WHIRLPOOL_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.ORCA_WHIRLPOOL_PROGRAM_ID; } });
16
+ Object.defineProperty(exports, "METEORA_POOLS_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.METEORA_POOLS_PROGRAM_ID; } });
17
+ Object.defineProperty(exports, "METEORA_DAMM_V2_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.METEORA_DAMM_V2_PROGRAM_ID; } });
18
+ Object.defineProperty(exports, "METEORA_DLMM_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.METEORA_DLMM_PROGRAM_ID; } });
19
+ /** Launchpad 等场景使用的程序 ID(非 Rust `Protocol` 映射项) */
13
20
  exports.BONK_LAUNCHPAD_PROGRAM_ID = "LanCh3hDdY7M6x8urBSLJhsQBgPNGKHNqJqGwzAEmBm";
14
- // Legacy/alternative program IDs (kept for compatibility)
15
- exports.BONK_PROGRAM_ID = "DjVE6JNiYqPL2QXyCUUh8rNjHrbz9hXHNYt99MQ59qw1";
16
- exports.PUMPSWAP_FEES_PROGRAM_ID = "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ";
17
- exports.METEORA_POOLS_PROGRAM_ID = "Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB";
18
- exports.METEORA_DLMM_PROGRAM_ID = "LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo";
21
+ /** 旧版 TS 包中的 Bonk ID,仅作兼容保留 */
22
+ exports.BONK_PROGRAM_ID_LEGACY = "DjVE6JNiYqPL2QXyCUUh8rNjHrbz9hXHNYt99MQ59qw1";
@@ -2,4 +2,4 @@
2
2
  * PumpSwap 指令解析
3
3
  */
4
4
  import type { DexEvent } from "../core/dex_event.js";
5
- export declare function parsePumpswapInstruction(instructionData: Uint8Array, accounts: string[], signature: string, slot: number, txIndex: number, blockTimeUs: number | undefined): DexEvent | null;
5
+ export declare function parsePumpswapInstruction(instructionData: Uint8Array, accounts: string[], signature: string, slot: number, txIndex: number, blockTimeUs: number | undefined, grpcRecvUs?: number): DexEvent | null;