sol-parser-sdk 0.5.16 → 0.5.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,6 +44,13 @@
44
44
 
45
45
  ## Release notes
46
46
 
47
+ ### v0.5.17
48
+
49
+ - Matches PumpFun create/create_v2 accounts by the actual instruction discriminator and event mint, including CPI calls; ambiguous matches are left unspecified.
50
+ - Stops inferring quote mint/vault/token-program fields from arbitrary remaining create_v2 accounts and preserves authoritative decoded fields.
51
+ - Restores historical CreateEvent decoding and verifies successful and failed transactions using saved mainnet fixtures.
52
+ - Suppresses rolled-back DEX events from failed transactions and preserves failure status through RPC/gRPC adapters.
53
+
47
54
  ### v0.5.16
48
55
 
49
56
  - Adds native gRPC lifecycle and block metadata support, instruction-level route analysis and StonkFun registry/snapshot examples.
@@ -96,7 +103,7 @@
96
103
  **From npm**
97
104
 
98
105
  ```bash
99
- npm install sol-parser-sdk@0.5.16
106
+ npm install sol-parser-sdk@0.5.17
100
107
  ```
101
108
 
102
109
  **From source** (folder may be named `sol-parser-sdk-ts` in a monorepo)
package/README_CN.md CHANGED
@@ -44,6 +44,13 @@
44
44
 
45
45
  ## 发布说明
46
46
 
47
+ ### v0.5.17
48
+
49
+ - 按实际指令 discriminator 和事件 mint 匹配 PumpFun create/create_v2 账户,支持 CPI,并拒绝猜测有歧义的匹配。
50
+ - 停止从 create_v2 的任意尾部账户推断 quote mint、vault、token program,保留权威解码字段。
51
+ - 恢复历史 CreateEvent 布局,并通过保存的真实主网成功、失败交易验证。
52
+ - 过滤失败交易中已经回滚的 Create/Buy 等 DEX 事件,并在 RPC/gRPC 转换中保留失败状态。
53
+
47
54
  ### v0.5.16
48
55
 
49
56
  - Adds native gRPC lifecycle and block metadata support, instruction-level route analysis and StonkFun registry/snapshot examples.
@@ -96,7 +103,7 @@
96
103
  **npm**
97
104
 
98
105
  ```bash
99
- npm install sol-parser-sdk@0.5.16
106
+ npm install sol-parser-sdk@0.5.17
100
107
  ```
101
108
 
102
109
  **源码**(monorepo 里目录可能是 `sol-parser-sdk-ts`)
@@ -40,6 +40,30 @@ function tryFill(programId, programInvokes, message, meta, resolver, fn, anchor,
40
40
  }
41
41
  /** 就地修改事件体内字段 */
42
42
  function fillAccountsFromTransactionDataRpc(ev, message, meta, programInvokes, resolver) {
43
+ const fillCreate = (e, v2Only = false) => {
44
+ let selected;
45
+ for (const invoke of programInvokes.get(program_ids_js_1.PUMPFUN_PROGRAM_ID) ?? []) {
46
+ const raw = (0, rpc_invoke_map_js_1.getInstructionDataBytes)(message, meta, invoke);
47
+ const matches = (disc) => raw && disc.every((b, i) => raw[i] === b);
48
+ const v2 = !!matches([214, 144, 76, 236, 95, 139, 49, 180]);
49
+ if (!v2 && (v2Only || !matches([24, 30, 200, 40, 5, 28, 7, 119])))
50
+ continue;
51
+ if ((0, rpc_invoke_map_js_1.countInstructionAccounts)(message, meta, invoke) < (v2 ? 16 : 14))
52
+ continue;
53
+ const get = (0, rpc_invoke_map_js_1.makeInvokeAccountGetter)(resolver, invoke, message, meta);
54
+ if (!get || (e.mint && e.mint !== "11111111111111111111111111111111" && get(0) !== e.mint))
55
+ continue;
56
+ if (selected)
57
+ return;
58
+ selected = { get, v2 };
59
+ }
60
+ if (selected) {
61
+ if (selected.v2)
62
+ (0, account_fill_pumpfun_js_1.fillPumpfunCreateV2Accounts)(e, selected.get);
63
+ else
64
+ (0, account_fill_pumpfun_js_1.fillPumpfunCreateAccounts)(e, selected.get);
65
+ }
66
+ };
43
67
  if ("PumpFunTrade" in ev) {
44
68
  tryFill(program_ids_js_1.PUMPFUN_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_pumpfun_js_1.fillPumpfunTradeAccounts)(ev.PumpFunTrade, g));
45
69
  }
@@ -53,10 +77,10 @@ function fillAccountsFromTransactionDataRpc(ev, message, meta, programInvokes, r
53
77
  tryFill(program_ids_js_1.PUMPFUN_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_pumpfun_js_1.fillPumpfunTradeAccounts)(ev.PumpFunBuyExactSolIn, g));
54
78
  }
55
79
  else if ("PumpFunCreate" in ev) {
56
- tryFill(program_ids_js_1.PUMPFUN_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_pumpfun_js_1.fillPumpfunCreateAccounts)(ev.PumpFunCreate, g));
80
+ fillCreate(ev.PumpFunCreate);
57
81
  }
58
82
  else if ("PumpFunCreateV2" in ev) {
59
- tryFill(program_ids_js_1.PUMPFUN_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_pumpfun_js_1.fillPumpfunCreateV2Accounts)(ev.PumpFunCreateV2, g));
83
+ fillCreate(ev.PumpFunCreateV2, true);
60
84
  }
61
85
  else if ("PumpFunMigrate" in ev) {
62
86
  tryFill(program_ids_js_1.PUMPFUN_PROGRAM_ID, programInvokes, message, meta, resolver, (g) => (0, account_fill_pumpfun_js_1.fillPumpfunMigrateAccounts)(ev.PumpFunMigrate, g));
@@ -106,16 +106,14 @@ function fillPumpfunTradeAccounts(e, get) {
106
106
  }
107
107
  function fillPumpfunCreateAccounts(e, get) {
108
108
  const zero = Z();
109
- if (get(15) === "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P") {
110
- fillPumpfunCreateV2Accounts(e, get);
111
- return;
109
+ const accounts = e;
110
+ for (const [field, index] of Object.entries({ mint: 0, mint_authority: 1, bonding_curve: 2,
111
+ associated_bonding_curve: 3, global: 4, user: 7, system_program: 8, token_program: 9,
112
+ associated_token_program: 10, event_authority: 12, program: 13 })) {
113
+ const key = field;
114
+ if (!accounts[key] || accounts[key] === zero)
115
+ accounts[field] = get(index);
112
116
  }
113
- if (!e.mint || e.mint === zero)
114
- e.mint = get(0);
115
- if (!e.bonding_curve || e.bonding_curve === zero)
116
- e.bonding_curve = get(2);
117
- if (!e.user || e.user === zero)
118
- e.user = get(7);
119
117
  }
120
118
  function fillPumpfunCreateV2Accounts(e, get) {
121
119
  const zero = Z();
@@ -153,13 +151,6 @@ function fillPumpfunCreateV2Accounts(e, get) {
153
151
  e.event_authority = get(14);
154
152
  if (!e.program || e.program === zero)
155
153
  e.program = get(15);
156
- if (!e.quote_mint || e.quote_mint === zero || e.quote_mint === "So11111111111111111111111111111111111111111") {
157
- e.quote_mint = get(16);
158
- }
159
- if (!e.quote_vault || e.quote_vault === zero)
160
- e.quote_vault = get(17);
161
- if (!e.quote_token_program || e.quote_token_program === zero)
162
- e.quote_token_program = get(18);
163
154
  if (!e.ix_name || e.ix_name === "create")
164
155
  e.ix_name = "create_v2";
165
156
  }
@@ -7,7 +7,7 @@ exports.convert_rpc_to_grpc = void 0;
7
7
  exports.convertRpcToGrpc = convertRpcToGrpc;
8
8
  /**
9
9
  * 将 `@solana/web3.js` 的 `VersionedTransactionResponse` 转为 Yellowstone `Transaction` + `TransactionStatusMeta`,
10
- * 与 Rust `rpc_parser::convert_rpc_to_grpc` 字段取舍一致(token balances / rewards 置空,err 置空等)。
10
+ * 与 Rust `rpc_parser::convert_rpc_to_grpc` 字段取舍一致(token balances / rewards 置空;保留失败状态)。
11
11
  */
12
12
  const bs58_1 = __importDefault(require("bs58"));
13
13
  const rpc_invoke_map_js_1 = require("../core/rpc_invoke_map.js");
@@ -77,7 +77,8 @@ function metaToYellowstone(meta) {
77
77
  const loadedReadonly = loaded?.readonly.map((k) => new Uint8Array(k.toBytes())) ?? [];
78
78
  const logs = meta.logMessages ?? [];
79
79
  return {
80
- err: undefined,
80
+ // Preserve failure presence without inventing a Yellowstone binary error enum.
81
+ err: meta.err != null ? { err: new Uint8Array() } : undefined,
81
82
  fee: String(meta.fee),
82
83
  preBalances: meta.preBalances.map(String),
83
84
  postBalances: meta.postBalances.map(String),
@@ -52,7 +52,7 @@ function versionedMessage(message) {
52
52
  }
53
53
  function transactionMeta(meta) {
54
54
  return {
55
- err: null,
55
+ err: meta.err ? "Yellowstone transaction failed" : null,
56
56
  fee: Number(meta.fee),
57
57
  preBalances: meta.preBalances.map(Number),
58
58
  postBalances: meta.postBalances.map(Number),
@@ -346,9 +346,9 @@ function parsePumpfunInstruction(instructionData, accounts, signature, slot, txI
346
346
  program: accounts[15] ?? Z,
347
347
  observed_fee_recipient: Z,
348
348
  ...createNumericDefaults(),
349
- quote_mint: accounts[16] ?? exports.PUMPFUN_SOL_QUOTE_MINT,
350
- quote_vault: accounts[17] ?? Z,
351
- quote_token_program: accounts[18] ?? Z,
349
+ quote_mint: exports.PUMPFUN_SOL_QUOTE_MINT,
350
+ quote_vault: Z,
351
+ quote_token_program: Z,
352
352
  ix_name: "create_v2",
353
353
  is_mayhem_mode: isMayhemMode,
354
354
  is_cashback_enabled: isCashbackEnabled,
package/dist/logs/pump.js CHANGED
@@ -241,6 +241,17 @@ function parseCreateFromData(data, metadata) {
241
241
  if (!n3)
242
242
  return null;
243
243
  o = n3.next;
244
+ if (data.length - o === 96) {
245
+ return { PumpFunCreate: {
246
+ metadata, name: n1.s, symbol: n2.s, uri: n3.s,
247
+ mint: (0, binary_js_1.readPubkey)(data, o), bonding_curve: (0, binary_js_1.readPubkey)(data, o + 32), user: (0, binary_js_1.readPubkey)(data, o + 64),
248
+ creator: (0, dex_event_js_1.defaultPubkey)(), timestamp: 0n, virtual_token_reserves: 0n, virtual_sol_reserves: 0n,
249
+ real_token_reserves: 0n, token_total_supply: 0n, token_program: (0, dex_event_js_1.defaultPubkey)(),
250
+ is_mayhem_mode: false, is_cashback_enabled: false, quote_mint: normalizePumpfunQuoteMint((0, dex_event_js_1.defaultPubkey)()),
251
+ quote_vault: (0, dex_event_js_1.defaultPubkey)(), quote_token_program: (0, dex_event_js_1.defaultPubkey)(), virtual_quote_reserves: 0n,
252
+ creator_fee_bps: 0n, is_holder_reward: false, ix_name: "create",
253
+ } };
254
+ }
244
255
  if (data.length < o + 32 * 4 + 8 * 5 + 32 + 1)
245
256
  return null;
246
257
  const mint = (0, binary_js_1.readPubkey)(data, o);
@@ -473,6 +473,9 @@ function applyAccountFillsToLogEvents(events, msg, meta) {
473
473
  * 解析已获取的 `VersionedTransactionResponse`(顺序:指令 → 日志 → 账户/数据填充)。
474
474
  */
475
475
  function parseRpcTransaction(tx, signature, filter, options) {
476
+ // Failed transactions roll back every instruction, including earlier create logs.
477
+ if (tx.meta?.err != null)
478
+ return { ok: true, events: [] };
476
479
  const msg = tx.transaction?.message;
477
480
  if (!msg || !(0, rpc_invoke_map_js_1.isCompiledVersionedMessage)(msg)) {
478
481
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sol-parser-sdk",
3
- "version": "0.5.16",
3
+ "version": "0.5.17",
4
4
  "description": "High-performance Solana DEX event parser for Node.js/TypeScript (Yellowstone gRPC, log parsing)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",