sol-parser-sdk-nodejs 0.4.0 → 0.4.4

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 (50) hide show
  1. package/README.md +6 -0
  2. package/README_CN.md +6 -0
  3. package/dist/accounts/mod.d.ts +1 -0
  4. package/dist/accounts/mod.js +14 -1
  5. package/dist/accounts/pumpfun.d.ts +6 -0
  6. package/dist/accounts/pumpfun.js +157 -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_fill_pumpfun.js +17 -0
  10. package/dist/core/dex_event.d.ts +147 -0
  11. package/dist/core/pumpfun_fee_enrich.d.ts +4 -0
  12. package/dist/core/pumpfun_fee_enrich.js +80 -0
  13. package/dist/core/unified_parser.js +2 -0
  14. package/dist/grpc/client.d.ts +26 -1
  15. package/dist/grpc/client.js +279 -0
  16. package/dist/grpc/log_instr_dedup.d.ts +2 -0
  17. package/dist/grpc/log_instr_dedup.js +330 -0
  18. package/dist/grpc/order_buffer.d.ts +27 -0
  19. package/dist/grpc/order_buffer.js +166 -0
  20. package/dist/grpc/program_ids.d.ts +1 -0
  21. package/dist/grpc/program_ids.js +2 -1
  22. package/dist/grpc/types.d.ts +5 -1
  23. package/dist/grpc/types.js +101 -0
  24. package/dist/grpc/yellowstone_parse.d.ts +3 -1
  25. package/dist/grpc/yellowstone_parse.js +13 -10
  26. package/dist/index.d.ts +8 -7
  27. package/dist/index.js +16 -4
  28. package/dist/instr/mod.d.ts +1 -0
  29. package/dist/instr/mod.js +9 -1
  30. package/dist/instr/program_ids.d.ts +1 -1
  31. package/dist/instr/program_ids.js +2 -1
  32. package/dist/instr/pump_fees_ix.d.ts +2 -0
  33. package/dist/instr/pump_fees_ix.js +166 -0
  34. package/dist/instr/pumpfun_ix.js +57 -0
  35. package/dist/instr/raydium_clmm_ix.js +73 -52
  36. package/dist/instr/rust_aliases.d.ts +1 -0
  37. package/dist/instr/rust_aliases.js +3 -1
  38. package/dist/logs/discriminator_lut.d.ts +1 -1
  39. package/dist/logs/discriminator_lut.js +2 -0
  40. package/dist/logs/optimized_matcher.js +120 -20
  41. package/dist/logs/program_log_discriminators.d.ts +10 -0
  42. package/dist/logs/program_log_discriminators.js +10 -0
  43. package/dist/logs/pump.d.ts +2 -0
  44. package/dist/logs/pump.js +51 -4
  45. package/dist/logs/pump_fees.d.ts +23 -0
  46. package/dist/logs/pump_fees.js +364 -0
  47. package/dist/rpc_transaction.d.ts +2 -0
  48. package/dist/rpc_transaction.js +14 -6
  49. package/dist/shredstream/instruction_parse.js +2 -0
  50. package/package.json +1 -1
package/dist/instr/mod.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.parseBonkInstruction = exports.parseOrcaWhirlpoolInstruction = exports.parseRaydiumAmmV4Instruction = exports.parseRaydiumCpmmInstruction = exports.parseRaydiumClmmInstruction = exports.parseMeteoraDammInstruction = exports.parsePumpswapInstruction = exports.parsePumpfunInstruction = void 0;
17
+ exports.parsePumpFeesInstruction = exports.parseBonkInstruction = exports.parseOrcaWhirlpoolInstruction = exports.parseRaydiumAmmV4Instruction = exports.parseRaydiumCpmmInstruction = exports.parseRaydiumClmmInstruction = exports.parseMeteoraDammInstruction = exports.parsePumpswapInstruction = exports.parsePumpfunInstruction = void 0;
18
18
  exports.parseInstructionUnified = parseInstructionUnified;
19
19
  const types_js_1 = require("../grpc/types.js");
20
20
  const program_ids_js_1 = require("./program_ids.js");
@@ -26,6 +26,7 @@ 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
+ const pump_fees_ix_js_1 = require("./pump_fees_ix.js");
29
30
  function isBonkProgram(programId) {
30
31
  return (programId === program_ids_js_1.BONK_PROGRAM_ID ||
31
32
  programId === program_ids_js_1.BONK_LAUNCHPAD_PROGRAM_ID ||
@@ -47,6 +48,8 @@ var orca_whirlpool_ix_js_2 = require("./orca_whirlpool_ix.js");
47
48
  Object.defineProperty(exports, "parseOrcaWhirlpoolInstruction", { enumerable: true, get: function () { return orca_whirlpool_ix_js_2.parseOrcaWhirlpoolInstruction; } });
48
49
  var bonk_ix_js_2 = require("./bonk_ix.js");
49
50
  Object.defineProperty(exports, "parseBonkInstruction", { enumerable: true, get: function () { return bonk_ix_js_2.parseBonkInstruction; } });
51
+ var pump_fees_ix_js_2 = require("./pump_fees_ix.js");
52
+ Object.defineProperty(exports, "parsePumpFeesInstruction", { enumerable: true, get: function () { return pump_fees_ix_js_2.parsePumpFeesInstruction; } });
50
53
  __exportStar(require("./program_ids.js"), exports);
51
54
  function parseInstructionUnified(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs, eventTypeFilter, programId) {
52
55
  if (instructionData.length === 0)
@@ -71,6 +74,11 @@ function parseInstructionUnified(instructionData, accounts, signature, slot, txI
71
74
  return null;
72
75
  return (0, meteora_damm_ix_js_1.parseMeteoraDammInstruction)(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs);
73
76
  }
77
+ if (programId === program_ids_js_1.PUMP_FEES_PROGRAM_ID) {
78
+ if (eventTypeFilter && !(0, types_js_1.eventTypeFilterIncludesPumpFees)(eventTypeFilter))
79
+ return null;
80
+ return (0, pump_fees_ix_js_1.parsePumpFeesInstruction)(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs);
81
+ }
74
82
  if (programId === program_ids_js_1.RAYDIUM_CLMM_PROGRAM_ID) {
75
83
  if (eventTypeFilter && !(0, types_js_1.eventTypeFilterIncludesRaydiumClmm)(eventTypeFilter))
76
84
  return null;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 各 DEX 程序 ID(Base58)。与 Rust 对齐的常量来自 `grpc/program_ids.ts`。
3
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";
4
+ export { PUMPFUN_PROGRAM_ID, PUMPSWAP_PROGRAM_ID, PUMPSWAP_FEES_PROGRAM_ID, PUMP_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
5
  /** Launchpad 等场景使用的程序 ID(非 Rust `Protocol` 映射项) */
6
6
  export declare const BONK_LAUNCHPAD_PROGRAM_ID = "LanCh3hDdY7M6x8urBSLJhsQBgPNGKHNqJqGwzAEmBm";
7
7
  /** 旧版 TS 包中的 Bonk ID,仅作兼容保留 */
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
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;
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.PUMP_FEES_PROGRAM_ID = exports.PUMPSWAP_FEES_PROGRAM_ID = exports.PUMPSWAP_PROGRAM_ID = exports.PUMPFUN_PROGRAM_ID = void 0;
4
4
  /**
5
5
  * 各 DEX 程序 ID(Base58)。与 Rust 对齐的常量来自 `grpc/program_ids.ts`。
6
6
  */
@@ -8,6 +8,7 @@ var program_ids_js_1 = require("../grpc/program_ids.js");
8
8
  Object.defineProperty(exports, "PUMPFUN_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.PUMPFUN_PROGRAM_ID; } });
9
9
  Object.defineProperty(exports, "PUMPSWAP_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.PUMPSWAP_PROGRAM_ID; } });
10
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, "PUMP_FEES_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.PUMP_FEES_PROGRAM_ID; } });
11
12
  Object.defineProperty(exports, "BONK_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.BONK_PROGRAM_ID; } });
12
13
  Object.defineProperty(exports, "RAYDIUM_CPMM_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.RAYDIUM_CPMM_PROGRAM_ID; } });
13
14
  Object.defineProperty(exports, "RAYDIUM_CLMM_PROGRAM_ID", { enumerable: true, get: function () { return program_ids_js_1.RAYDIUM_CLMM_PROGRAM_ID; } });
@@ -0,0 +1,2 @@
1
+ import type { DexEvent } from "../core/dex_event.js";
2
+ export declare function parsePumpFeesInstruction(instructionData: Uint8Array, accounts: string[], signature: string, slot: number, txIndex: number, blockTimeUs: number | undefined, grpcRecvUs: number): DexEvent | null;
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parsePumpFeesInstruction = parsePumpFeesInstruction;
4
+ const metadata_js_1 = require("../core/metadata.js");
5
+ const dex_event_js_1 = require("../core/dex_event.js");
6
+ const binary_js_1 = require("../util/binary.js");
7
+ const pump_fees_js_1 = require("../logs/pump_fees.js");
8
+ const program_log_discriminators_js_1 = require("../logs/program_log_discriminators.js");
9
+ const CREATE_FEE_SHARING_IX = (0, program_log_discriminators_js_1.u64leDiscriminator)([195, 78, 86, 76, 111, 52, 251, 213]);
10
+ const INITIALIZE_FEE_CONFIG_IX = (0, program_log_discriminators_js_1.u64leDiscriminator)([62, 162, 20, 133, 121, 65, 145, 27]);
11
+ const RESET_FEE_SHARING_IX = (0, program_log_discriminators_js_1.u64leDiscriminator)([10, 2, 182, 95, 16, 127, 129, 186]);
12
+ const REVOKE_FEE_SHARING_IX = (0, program_log_discriminators_js_1.u64leDiscriminator)([18, 233, 158, 39, 185, 207, 58, 104]);
13
+ const TRANSFER_FEE_SHARING_IX = (0, program_log_discriminators_js_1.u64leDiscriminator)([202, 10, 75, 200, 164, 34, 210, 96]);
14
+ const UPDATE_ADMIN_IX = (0, program_log_discriminators_js_1.u64leDiscriminator)([161, 176, 40, 213, 60, 184, 179, 228]);
15
+ const UPDATE_FEE_CONFIG_IX = (0, program_log_discriminators_js_1.u64leDiscriminator)([104, 184, 103, 242, 88, 151, 107, 20]);
16
+ const UPDATE_FEE_SHARES_IX = (0, program_log_discriminators_js_1.u64leDiscriminator)([189, 13, 136, 99, 187, 164, 237, 35]);
17
+ const UPSERT_FEE_TIERS_IX = (0, program_log_discriminators_js_1.u64leDiscriminator)([227, 23, 150, 12, 77, 86, 94, 4]);
18
+ function account(accounts, index) {
19
+ return accounts[index] ?? null;
20
+ }
21
+ function accountOrDefault(accounts, index) {
22
+ return accounts[index] ?? (0, dex_event_js_1.defaultPubkey)();
23
+ }
24
+ function parsePumpFeesInstruction(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs) {
25
+ const disc = (0, binary_js_1.readDiscriminatorU64)(instructionData);
26
+ if (disc === null)
27
+ return null;
28
+ const metadata = (0, metadata_js_1.makeMetadata)(signature, slot, txIndex, blockTimeUs, grpcRecvUs);
29
+ if (disc === CREATE_FEE_SHARING_IX) {
30
+ const admin = account(accounts, 2);
31
+ const mint = account(accounts, 4);
32
+ if (!admin || !mint)
33
+ return null;
34
+ return {
35
+ PumpFeesCreateFeeSharingConfig: {
36
+ metadata,
37
+ timestamp: 0n,
38
+ mint,
39
+ bonding_curve: accountOrDefault(accounts, 7),
40
+ pool: account(accounts, 10) ?? undefined,
41
+ sharing_config: accountOrDefault(accounts, 5),
42
+ admin,
43
+ initial_shareholders: [],
44
+ status: "Active",
45
+ },
46
+ };
47
+ }
48
+ if (disc === UPDATE_FEE_SHARES_IX) {
49
+ const admin = account(accounts, 2);
50
+ const mint = account(accounts, 4);
51
+ const sharing_config = account(accounts, 5);
52
+ if (!admin || !mint || !sharing_config)
53
+ return null;
54
+ const shareholders = (0, pump_fees_js_1.readShareholdersVec)(instructionData, 8);
55
+ if (!shareholders || shareholders.next !== instructionData.length)
56
+ return null;
57
+ return {
58
+ PumpFeesUpdateFeeShares: {
59
+ metadata,
60
+ timestamp: 0n,
61
+ mint,
62
+ sharing_config,
63
+ admin,
64
+ bonding_curve: accountOrDefault(accounts, 6),
65
+ pump_creator_vault: accountOrDefault(accounts, 7),
66
+ new_shareholders: shareholders.value,
67
+ },
68
+ };
69
+ }
70
+ if (disc === INITIALIZE_FEE_CONFIG_IX) {
71
+ const admin = account(accounts, 0);
72
+ const fee_config = account(accounts, 1);
73
+ if (!admin || !fee_config)
74
+ return null;
75
+ return { PumpFeesInitializeFeeConfig: { metadata, timestamp: 0n, admin, fee_config } };
76
+ }
77
+ if (disc === RESET_FEE_SHARING_IX) {
78
+ const old_admin = account(accounts, 0);
79
+ const new_admin = account(accounts, 2);
80
+ const mint = account(accounts, 3);
81
+ const sharing_config = account(accounts, 4);
82
+ if (!old_admin || !new_admin || !mint || !sharing_config)
83
+ return null;
84
+ return {
85
+ PumpFeesResetFeeSharingConfig: {
86
+ metadata,
87
+ timestamp: 0n,
88
+ mint,
89
+ sharing_config,
90
+ old_admin,
91
+ old_shareholders: [],
92
+ new_admin,
93
+ new_shareholders: [],
94
+ },
95
+ };
96
+ }
97
+ if (disc === REVOKE_FEE_SHARING_IX) {
98
+ const admin = account(accounts, 0);
99
+ const mint = account(accounts, 2);
100
+ const sharing_config = account(accounts, 3);
101
+ if (!admin || !mint || !sharing_config)
102
+ return null;
103
+ return { PumpFeesRevokeFeeSharingAuthority: { metadata, timestamp: 0n, mint, sharing_config, admin } };
104
+ }
105
+ if (disc === TRANSFER_FEE_SHARING_IX) {
106
+ const old_admin = account(accounts, 0);
107
+ const mint = account(accounts, 2);
108
+ const sharing_config = account(accounts, 3);
109
+ const new_admin = account(accounts, 4);
110
+ if (!old_admin || !mint || !sharing_config || !new_admin)
111
+ return null;
112
+ return {
113
+ PumpFeesTransferFeeSharingAuthority: {
114
+ metadata,
115
+ timestamp: 0n,
116
+ mint,
117
+ sharing_config,
118
+ old_admin,
119
+ new_admin,
120
+ },
121
+ };
122
+ }
123
+ if (disc === UPDATE_ADMIN_IX) {
124
+ const old_admin = account(accounts, 0);
125
+ const new_admin = account(accounts, 2);
126
+ if (!old_admin || !new_admin)
127
+ return null;
128
+ return { PumpFeesUpdateAdmin: { metadata, timestamp: 0n, old_admin, new_admin } };
129
+ }
130
+ if (disc === UPDATE_FEE_CONFIG_IX) {
131
+ const fee_config = account(accounts, 0);
132
+ const admin = account(accounts, 1);
133
+ if (!fee_config || !admin)
134
+ return null;
135
+ const fee_tiers = (0, pump_fees_js_1.readFeeTiersVec)(instructionData, 8);
136
+ if (!fee_tiers)
137
+ return null;
138
+ const flat_fees = (0, pump_fees_js_1.readFeesAt)(instructionData, fee_tiers.next);
139
+ if (!flat_fees || flat_fees.next !== instructionData.length)
140
+ return null;
141
+ return {
142
+ PumpFeesUpdateFeeConfig: {
143
+ metadata,
144
+ timestamp: 0n,
145
+ admin,
146
+ fee_config,
147
+ fee_tiers: fee_tiers.value,
148
+ flat_fees: flat_fees.value,
149
+ },
150
+ };
151
+ }
152
+ if (disc === UPSERT_FEE_TIERS_IX) {
153
+ const fee_config = account(accounts, 0);
154
+ const admin = account(accounts, 1);
155
+ if (!fee_config || !admin)
156
+ return null;
157
+ const fee_tiers = (0, pump_fees_js_1.readFeeTiersVec)(instructionData, 8);
158
+ if (!fee_tiers)
159
+ return null;
160
+ const offset = (0, binary_js_1.readU8)(instructionData, fee_tiers.next);
161
+ if (offset === null || fee_tiers.next + 1 !== instructionData.length)
162
+ return null;
163
+ return { PumpFeesUpsertFeeTiers: { metadata, timestamp: 0n, admin, fee_config, fee_tiers: fee_tiers.value, offset } };
164
+ }
165
+ return null;
166
+ }
@@ -8,6 +8,9 @@ const Z = (0, dex_event_js_1.defaultPubkey)();
8
8
  const DISC = {
9
9
  CREATE: Uint8Array.from([24, 30, 200, 40, 5, 28, 7, 119]),
10
10
  CREATE_V2: Uint8Array.from([214, 144, 76, 236, 95, 139, 49, 180]),
11
+ BUY_V2: Uint8Array.from([184, 23, 238, 97, 103, 197, 211, 61]),
12
+ SELL_V2: Uint8Array.from([93, 246, 130, 60, 231, 233, 64, 178]),
13
+ BUY_EXACT_QUOTE_IN_V2: Uint8Array.from([194, 171, 28, 70, 104, 77, 91, 47]),
11
14
  MIGRATE_EVENT_LOG: Uint8Array.from([189, 233, 93, 185, 92, 148, 234, 148]),
12
15
  };
13
16
  function discEq(data, disc) {
@@ -29,6 +32,50 @@ function createNumericDefaults() {
29
32
  is_cashback_enabled: false,
30
33
  };
31
34
  }
35
+ function parsePumpfunTradeV2Instruction(ixName, data, accounts, metadata) {
36
+ const minAccounts = ixName === "sell_v2" ? 26 : 27;
37
+ if (accounts.length < minAccounts)
38
+ return null;
39
+ const first = data.length >= 8 ? (0, utils_js_1.readU64LE)(data, 0) ?? 0n : 0n;
40
+ const second = data.length >= 16 ? (0, utils_js_1.readU64LE)(data, 8) ?? 0n : 0n;
41
+ const tokenAmount = ixName === "buy_exact_quote_in_v2" ? second : first;
42
+ const solAmount = ixName === "buy_exact_quote_in_v2" ? first : second;
43
+ const trade = {
44
+ metadata,
45
+ mint: accounts[1] ?? Z,
46
+ bonding_curve: accounts[10] ?? Z,
47
+ user: accounts[13] ?? Z,
48
+ sol_amount: solAmount,
49
+ token_amount: tokenAmount,
50
+ fee_recipient: accounts[6] ?? Z,
51
+ is_buy: ixName !== "sell_v2",
52
+ is_created_buy: false,
53
+ timestamp: 0n,
54
+ virtual_sol_reserves: 0n,
55
+ virtual_token_reserves: 0n,
56
+ real_sol_reserves: 0n,
57
+ real_token_reserves: 0n,
58
+ fee_basis_points: 0n,
59
+ fee: 0n,
60
+ creator: Z,
61
+ creator_fee_basis_points: 0n,
62
+ creator_fee: 0n,
63
+ track_volume: false,
64
+ total_unclaimed_tokens: 0n,
65
+ total_claimed_tokens: 0n,
66
+ current_sol_volume: 0n,
67
+ last_update_timestamp: 0n,
68
+ ix_name: ixName,
69
+ mayhem_mode: false,
70
+ cashback_fee_basis_points: 0n,
71
+ cashback: 0n,
72
+ is_cashback_coin: false,
73
+ associated_bonding_curve: accounts[11] ?? Z,
74
+ token_program: accounts[3] ?? Z,
75
+ creator_vault: accounts[16] ?? Z,
76
+ };
77
+ return { PumpFunTrade: trade };
78
+ }
32
79
  function parsePumpfunInstruction(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs) {
33
80
  if (instructionData.length < 8)
34
81
  return null;
@@ -75,10 +122,20 @@ function parsePumpfunInstruction(instructionData, accounts, signature, slot, txI
75
122
  mayhem_token_vault: accounts[13] ?? Z,
76
123
  event_authority: accounts[14] ?? Z,
77
124
  program: accounts[15] ?? Z,
125
+ observed_fee_recipient: Z,
78
126
  ...createNumericDefaults(),
79
127
  };
80
128
  return { PumpFunCreateV2: ev };
81
129
  }
130
+ if (discEq(outer, DISC.BUY_V2)) {
131
+ return parsePumpfunTradeV2Instruction("buy_v2", data, accounts, meta);
132
+ }
133
+ if (discEq(outer, DISC.BUY_EXACT_QUOTE_IN_V2)) {
134
+ return parsePumpfunTradeV2Instruction("buy_exact_quote_in_v2", data, accounts, meta);
135
+ }
136
+ if (discEq(outer, DISC.SELL_V2)) {
137
+ return parsePumpfunTradeV2Instruction("sell_v2", data, accounts, meta);
138
+ }
82
139
  if (discEq(outer, DISC.CREATE)) {
83
140
  if (accounts.length < 8)
84
141
  return null;
@@ -6,10 +6,14 @@ const program_log_discriminators_js_1 = require("../logs/program_log_discriminat
6
6
  const utils_js_1 = require("./utils.js");
7
7
  const Z = (0, dex_event_js_1.defaultPubkey)();
8
8
  const DISC = {
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
- CREATE_POOL: program_log_discriminators_js_1.PROGRAM_LOG_DISC.RAYDIUM_CLMM_CREATE_POOL,
9
+ SWAP: (0, program_log_discriminators_js_1.u64leDiscriminator)([248, 198, 158, 145, 225, 117, 135, 200]),
10
+ SWAP_V2: (0, program_log_discriminators_js_1.u64leDiscriminator)([43, 4, 237, 11, 26, 201, 30, 98]),
11
+ INCREASE_LIQUIDITY_V2: (0, program_log_discriminators_js_1.u64leDiscriminator)([133, 29, 89, 223, 69, 238, 176, 10]),
12
+ DECREASE_LIQUIDITY_V2: (0, program_log_discriminators_js_1.u64leDiscriminator)([58, 127, 188, 62, 79, 82, 196, 96]),
13
+ CREATE_POOL: (0, program_log_discriminators_js_1.u64leDiscriminator)([233, 146, 209, 142, 207, 104, 64, 188]),
14
+ OPEN_POSITION_V2: (0, program_log_discriminators_js_1.u64leDiscriminator)([77, 184, 74, 214, 112, 86, 241, 199]),
15
+ OPEN_POSITION_WITH_TOKEN_22_NFT: (0, program_log_discriminators_js_1.u64leDiscriminator)([77, 255, 174, 82, 125, 29, 201, 46]),
16
+ CLOSE_POSITION: (0, program_log_discriminators_js_1.u64leDiscriminator)([123, 134, 81, 0, 49, 68, 98, 98]),
13
17
  };
14
18
  function discEq(data, disc) {
15
19
  if (data.length < 8)
@@ -17,38 +21,27 @@ function discEq(data, disc) {
17
21
  const v = (0, utils_js_1.readU64LE)(data, 0);
18
22
  return v === disc;
19
23
  }
20
- /** Whirlpool 系 swap 指令账户:0 program, 1 authority, 2 pool, 3 user_ata_a, 4 vault_a, 5 user_ata_b, … */
21
- const SWAP_ACC = {
22
- POOL: 2,
23
- SENDER: 1,
24
- TOKEN_A_USER: 3,
25
- TOKEN_B_USER: 5,
26
- };
27
24
  function parseRaydiumClmmInstruction(instructionData, accounts, signature, slot, txIndex, blockTimeUs, grpcRecvUs) {
28
25
  if (instructionData.length < 8)
29
26
  return null;
30
27
  const meta = (0, utils_js_1.ixMeta)(signature, slot, txIndex, blockTimeUs, grpcRecvUs);
31
- if (discEq(instructionData, DISC.SWAP)) {
32
- // Anchor swap:amount, other_amount_threshold, sqrt_price_limit(u128), amount_specified_is_input, a_to_b
33
- if (instructionData.length < 42)
28
+ if (discEq(instructionData, DISC.SWAP) || discEq(instructionData, DISC.SWAP_V2)) {
29
+ if (instructionData.length < 8 + 8 + 8 + 8 + 1)
34
30
  return null;
35
- const amount = (0, utils_js_1.readU64LE)(instructionData, 8) ?? 0n;
36
- const other = (0, utils_js_1.readU64LE)(instructionData, 16) ?? 0n;
37
- const sqrt_limit = (0, utils_js_1.readU128LE)(instructionData, 24) ?? 0n;
38
- const _amount_specified_is_input = (0, utils_js_1.readBool)(instructionData, 40);
39
- const a_to_b = (0, utils_js_1.readBool)(instructionData, 41);
40
- if (_amount_specified_is_input === null || a_to_b === null)
31
+ const sqrt_limit = (0, utils_js_1.readU64LE)(instructionData, 24) ?? 0n;
32
+ const is_base_input = (0, utils_js_1.readBool)(instructionData, 32);
33
+ if (is_base_input === null)
41
34
  return null;
42
35
  return {
43
36
  RaydiumClmmSwap: {
44
37
  metadata: meta,
45
- pool_state: (0, utils_js_1.getAccount)(accounts, SWAP_ACC.POOL) ?? Z,
46
- sender: (0, utils_js_1.getAccount)(accounts, SWAP_ACC.SENDER) ?? Z,
47
- token_account_0: (0, utils_js_1.getAccount)(accounts, SWAP_ACC.TOKEN_A_USER) ?? Z,
48
- token_account_1: (0, utils_js_1.getAccount)(accounts, SWAP_ACC.TOKEN_B_USER) ?? Z,
49
- amount_0: amount,
50
- amount_1: other,
51
- zero_for_one: a_to_b,
38
+ pool_state: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
39
+ sender: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
40
+ token_account_0: Z,
41
+ token_account_1: Z,
42
+ amount_0: 0n,
43
+ amount_1: 0n,
44
+ zero_for_one: is_base_input,
52
45
  sqrt_price_x64: sqrt_limit,
53
46
  liquidity: 0n,
54
47
  transfer_fee_0: 0n,
@@ -57,38 +50,36 @@ function parseRaydiumClmmInstruction(instructionData, accounts, signature, slot,
57
50
  },
58
51
  };
59
52
  }
60
- if (discEq(instructionData, DISC.INCREASE_LIQUIDITY)) {
61
- // increase_liquidity_v2:liquidity (u128), token_max_a, token_max_b
62
- if (instructionData.length < 8 + 16 + 8 + 8)
53
+ if (discEq(instructionData, DISC.INCREASE_LIQUIDITY_V2)) {
54
+ if (instructionData.length < 8 + 8 + 8 + 8)
63
55
  return null;
64
- const liquidity = (0, utils_js_1.readU128LE)(instructionData, 8) ?? 0n;
65
- const amount0_max = (0, utils_js_1.readU64LE)(instructionData, 24) ?? 0n;
66
- const amount1_max = (0, utils_js_1.readU64LE)(instructionData, 32) ?? 0n;
56
+ const liquidity = (0, utils_js_1.readU64LE)(instructionData, 8) ?? 0n;
57
+ const amount0_max = (0, utils_js_1.readU64LE)(instructionData, 16) ?? 0n;
58
+ const amount1_max = (0, utils_js_1.readU64LE)(instructionData, 24) ?? 0n;
67
59
  return {
68
60
  RaydiumClmmIncreaseLiquidity: {
69
61
  metadata: meta,
70
- pool: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
71
- position_nft_mint: (0, utils_js_1.getAccount)(accounts, 3) ?? Z,
72
- user: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
62
+ pool: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
63
+ position_nft_mint: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
64
+ user: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
73
65
  liquidity,
74
66
  amount0_max,
75
67
  amount1_max,
76
68
  },
77
69
  };
78
70
  }
79
- if (discEq(instructionData, DISC.DECREASE_LIQUIDITY)) {
80
- // decrease_liquidity:liquidity (u128), token_min_a, token_min_b
81
- if (instructionData.length < 8 + 16 + 8 + 8)
71
+ if (discEq(instructionData, DISC.DECREASE_LIQUIDITY_V2)) {
72
+ if (instructionData.length < 8 + 8 + 8 + 8)
82
73
  return null;
83
- const liquidity = (0, utils_js_1.readU128LE)(instructionData, 8) ?? 0n;
84
- const amount0_min = (0, utils_js_1.readU64LE)(instructionData, 24) ?? 0n;
85
- const amount1_min = (0, utils_js_1.readU64LE)(instructionData, 32) ?? 0n;
74
+ const liquidity = (0, utils_js_1.readU64LE)(instructionData, 8) ?? 0n;
75
+ const amount0_min = (0, utils_js_1.readU64LE)(instructionData, 16) ?? 0n;
76
+ const amount1_min = (0, utils_js_1.readU64LE)(instructionData, 24) ?? 0n;
86
77
  return {
87
78
  RaydiumClmmDecreaseLiquidity: {
88
79
  metadata: meta,
89
- pool: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
90
- position_nft_mint: (0, utils_js_1.getAccount)(accounts, 3) ?? Z,
91
- user: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
80
+ pool: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
81
+ position_nft_mint: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
82
+ user: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
92
83
  liquidity,
93
84
  amount0_min,
94
85
  amount1_min,
@@ -96,23 +87,53 @@ function parseRaydiumClmmInstruction(instructionData, accounts, signature, slot,
96
87
  };
97
88
  }
98
89
  if (discEq(instructionData, DISC.CREATE_POOL)) {
99
- if (instructionData.length < 8 + 16 + 8)
90
+ if (instructionData.length < 8 + 8 + 8)
100
91
  return null;
101
- const sqrt_price_x64 = (0, utils_js_1.readU128LE)(instructionData, 8) ?? 0n;
102
- const open_time = (0, utils_js_1.readU64LE)(instructionData, 24) ?? 0n;
92
+ const sqrt_price_x64 = (0, utils_js_1.readU64LE)(instructionData, 8) ?? 0n;
93
+ const open_time = (0, utils_js_1.readU64LE)(instructionData, 16) ?? 0n;
103
94
  return {
104
95
  RaydiumClmmCreatePool: {
105
96
  metadata: meta,
106
- pool: (0, utils_js_1.getAccount)(accounts, 4) ?? Z,
107
- token_0_mint: Z,
108
- token_1_mint: Z,
97
+ pool: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
98
+ token_0_mint: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
99
+ token_1_mint: (0, utils_js_1.getAccount)(accounts, 3) ?? Z,
109
100
  tick_spacing: 0,
110
101
  fee_rate: 0,
111
- creator: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
102
+ creator: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
112
103
  sqrt_price_x64,
113
104
  open_time,
114
105
  },
115
106
  };
116
107
  }
108
+ if (discEq(instructionData, DISC.OPEN_POSITION_V2) || discEq(instructionData, DISC.OPEN_POSITION_WITH_TOKEN_22_NFT)) {
109
+ if (instructionData.length < 8 + 4 + 4 + 4 + 4 + 8 + 8 + 8)
110
+ return null;
111
+ const tick_lower_index = (0, utils_js_1.readI32LE)(instructionData, 8);
112
+ const tick_upper_index = (0, utils_js_1.readI32LE)(instructionData, 12);
113
+ const liquidity = (0, utils_js_1.readU64LE)(instructionData, 24) ?? 0n;
114
+ if (tick_lower_index === null || tick_upper_index === null)
115
+ return null;
116
+ return {
117
+ RaydiumClmmOpenPosition: {
118
+ metadata: meta,
119
+ pool: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
120
+ user: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
121
+ position_nft_mint: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
122
+ tick_lower_index,
123
+ tick_upper_index,
124
+ liquidity,
125
+ },
126
+ };
127
+ }
128
+ if (discEq(instructionData, DISC.CLOSE_POSITION)) {
129
+ return {
130
+ RaydiumClmmClosePosition: {
131
+ metadata: meta,
132
+ pool: (0, utils_js_1.getAccount)(accounts, 0) ?? Z,
133
+ user: (0, utils_js_1.getAccount)(accounts, 1) ?? Z,
134
+ position_nft_mint: (0, utils_js_1.getAccount)(accounts, 2) ?? Z,
135
+ },
136
+ };
137
+ }
117
138
  return null;
118
139
  }
@@ -5,3 +5,4 @@ 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 { 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_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_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,3 +12,5 @@ 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 pump_fees_ix_js_1 = require("./pump_fees_ix.js");
16
+ Object.defineProperty(exports, "parse_pump_fees_instruction", { enumerable: true, get: function () { return pump_fees_ix_js_1.parsePumpFeesInstruction; } });
@@ -1,5 +1,5 @@
1
1
  /** 与 Rust `discriminator_lut::Protocol` 变体名一致(字符串联合,便于 JSON / 日志)。 */
2
- export type LogProtocol = "PumpFun" | "PumpSwap" | "RaydiumClmm" | "RaydiumCpmm" | "RaydiumAmm" | "OrcaWhirlpool" | "MeteoraAmm" | "MeteoraDamm";
2
+ export type LogProtocol = "PumpFun" | "PumpFees" | "PumpSwap" | "RaydiumClmm" | "RaydiumCpmm" | "RaydiumAmm" | "OrcaWhirlpool" | "MeteoraAmm" | "MeteoraDamm";
3
3
  /** Rust `discriminator_to_name` */
4
4
  export declare function discriminatorToName(discriminator: bigint): string | undefined;
5
5
  /** Rust `discriminator_to_protocol` */
@@ -12,6 +12,8 @@ const program_log_discriminators_js_1 = require("./program_log_discriminators.js
12
12
  function protocolForProgramLogKey(key) {
13
13
  if (key.startsWith("PUMPFUN_"))
14
14
  return "PumpFun";
15
+ if (key.startsWith("PUMP_FEES_"))
16
+ return "PumpFees";
15
17
  if (key.startsWith("PUMPSWAP_"))
16
18
  return "PumpSwap";
17
19
  if (key.startsWith("RAYDIUM_CLMM_"))