From d0dea6d4ac86e358416a2f5723f6a4cb8e3cd5f2 Mon Sep 17 00:00:00 2001 From: Anton Sauchyk Date: Tue, 28 Apr 2026 18:44:42 +0200 Subject: [PATCH] fix(blocks-listener): skip failed txs + use CreateEvent log for canonical creator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two bugs found by mainnet validation post-2026-04-28 cutover: 1. Blocks listener processed failed txs, including failed create_v2s. The bot then tried to buy a non-existent mint (InvalidMint at ATA creation). Fix: filter `meta.err is not None` in _process_block_transactions. 2. Blocks listener parsed `args.creator` from the create_v2 ix payload to derive creator_vault. Post-cutover, BC.creator is sometimes set to a PFEE-program-owned PDA distinct from args.creator (e.g., Companions: args.creator=DdZG8dw, BC.creator=3hPZm9). The Anchor seeds constraint on creator_vault then fails with ConstraintSeeds (0x7d6). Fix: in parse_token_creation_from_block, prefer parsing the CreateEvent log (which carries the canonical creator the program wrote to BC.creator) over args.creator from the ix payload. Mainnet validation: - buy 2uBrNqqW…bPDG, sell 32EKJjrK…9fXv on PUMP (Pumpcoin), err=None. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/monitoring/universal_block_listener.py | 6 ++++++ src/platforms/pumpfun/event_parser.py | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/monitoring/universal_block_listener.py b/src/monitoring/universal_block_listener.py index 0403c9d..a538f8f 100644 --- a/src/monitoring/universal_block_listener.py +++ b/src/monitoring/universal_block_listener.py @@ -258,6 +258,12 @@ class UniversalBlockListener(BaseTokenListener): if not isinstance(tx, dict) or "transaction" not in tx: continue + # Skip failed txs — sniping a failed create yields a non-existent + # mint and the buy-side tx then fails with InvalidMint. + meta = tx.get("meta") + if isinstance(meta, dict) and meta.get("err") is not None: + continue + tx_data = tx["transaction"] # Handle base64 encoded transaction data diff --git a/src/platforms/pumpfun/event_parser.py b/src/platforms/pumpfun/event_parser.py index 0753efc..678244e 100644 --- a/src/platforms/pumpfun/event_parser.py +++ b/src/platforms/pumpfun/event_parser.py @@ -477,6 +477,22 @@ class PumpFunEventParser(EventParser): if not isinstance(tx, dict) or "transaction" not in tx: continue + # Prefer parsing the CreateEvent from logs — args.creator on the + # ix is user-supplied and post-2026-04-28 may differ from the + # canonical BC.creator (which the program writes as a PFEE PDA + # in some cases). The CreateEvent log carries the canonical + # creator, so creator_vault derived from it matches the program + # constraint. + meta = tx.get("meta") + if isinstance(meta, dict): + logs = meta.get("logMessages") or meta.get("log_messages") + if logs: + token_info = self.parse_token_creation_from_logs( + logs, signature="" + ) + if token_info: + return token_info + # Decode base64 transaction data if needed tx_data = tx["transaction"] if isinstance(tx_data, list) and len(tx_data) > 0: