* chore(pumpswap+docs): post-2026-04-28-cutover PumpSwap unlock + IDL docs
Drops the `INCLUDE_BREAKING_FEE_ACCOUNTS = False` gate in the PumpSwap
learning examples so the +2 breaking-fee accounts (fee recipient
readonly + its quote-mint ATA mutable) are always appended after
`pool-v2`. Mainnet pump-amm rejects this format pre-cutover (verified
6023 Overflow), so this PR is intentionally **draft until 2026-04-28
16:00 UTC** when the cutover happens; mark it ready-for-review and live-
test then.
Also captures the protocol gotchas we learned during this migration:
- README: a new "2026-04-28 program upgrade" section + an explicit note
that the vendored IDL is incomplete (missing `bonding-curve-v2` and
`pool-v2` PDAs that the on-chain program actually requires) with
pointers to cross-check against on-chain txs.
- CLAUDE.md: a new "Pump.fun protocol notes" subsection summarising
the same gotchas plus the BC/Pool/CreateEvent layout details and the
extreme_fast_mode gotcha.
Open question (call out at review time, resolve post-cutover):
- BREAKING_FEE_RECIPIENT.md shows PumpSwap cashback account counts of
27 buy / 26 sell vs 26 / 24 non-cashback — the extra cashback account
seed/position isn't documented. Need to sample a real successful
cashback PumpSwap tx after cutover and add the branch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(pumpswap): wire cashback layout for post-2026-04-28 program upgrade
Cashback PumpSwap pools require extra writable accounts inserted before
pool-v2. Identified layouts by sampling on-chain post-cutover txs:
- buy: insert user_volume_accumulator_quote_ata (27 accounts vs 26)
ref tx 4JaWdExj…fvjK
- sell: insert user_volume_accumulator_quote_ata + user_volume_accumulator
(26 accounts vs 24)
ref tx 4ei1cJV7…NP3
Detect via pool account byte 244 (is_cashback_coin). Adds the standalone
sample_cashback_pumpswap.py used to reverse-engineer the layouts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the four learning-examples commits (9b48418, c25e2ed, 57ffe8b,
ad6d2cc) into the production code paths under src/. Affects only pump_fun;
lets_bonk untouched. PumpSwap is not implemented under src/ so the
pool-v2 + breaking-fee-recipient pumpswap accounts are out of scope here.
Changes
-------
src/platforms/pumpfun/address_provider.py
- Adds BREAKING_FEE_RECIPIENTS: ClassVar[list[Pubkey]] with the 8
addresses pump.fun published for the 2026-04-28 upgrade.
- Adds pick_breaking_fee_recipient() (random.choice across the 8 to
spread program-tx throughput per pump.fun's recommendation).
- get_buy_instruction_accounts and get_sell_instruction_accounts now
expose "breaking_fee_recipient" alongside the existing keys.
src/platforms/pumpfun/instruction_builder.py
- BC buy ix: appends breaking_fee_recipient (mutable) AFTER
bonding_curve_v2 → 18 accounts total (was 17).
- BC sell ix: appends breaking_fee_recipient (mutable) AFTER
bonding_curve_v2 for both cashback and non-cashback paths
→ 16 accounts non-cashback / 17 cashback (was 15 / 16).
- get_required_accounts_for_{buy,sell} updated to include the new
account so priority-fee scraping covers it.
src/platforms/pumpfun/event_parser.py
- is_mayhem_mode now extracted into TokenInfo on both paths
(CreateEvent logs path and create / create_v2 instruction path);
previously only is_cashback_coin was carried forward, leaving
extreme_fast_mode buys to use the wrong fee_recipient on
Mayhem-Mode tokens.
src/trading/platform_aware.py
- Buy non-extreme path now also refreshes is_cashback_coin from
pool_state (was only refreshing is_mayhem_mode).
- Sell path now refreshes both flags from curve state before building
the sell ix, so a coin that flips cashback after buy still gets the
correct 16-vs-17-account layout. Wrapped in try/except so a transient
RPC failure logs a warning and falls back to token_info defaults
rather than failing the sell outright.
Live-validation (mainnet, all four bots/*.yaml configs)
-------------------------------------------------------
bot-sniper-2-logs.yaml buy 4GVJJwYtGixSPAQimgUhNYjEUBG6TB9XeQjKxs9EWpw2QfWuq7LHmUivPrsjhESgaPsPJQ9N6CCxECqxm9csqrH9 (18 accts) → sell 2ijgoPgxPmcSX4mFqz1PVkZ3yAvu36vj3Jy1yWZofxrK7jR92j2DWP3tRNy9PmUd1kiTaoYzVsrpGr6286KCnTp7 (16 accts) ✓
bot-sniper-3-blocks.yaml buy 4siRLG7tYk9iHyXAvnp3DH54vQXVEDHmCqZRmFgYhnRB9mVGjhh43ywohKjg8CpWctt5TyCtDkLRTRWT6VDwVyZi → sell 46jShWJ3sfuCP4YgTcpXWZdyqVmw4ULQSTC3Kwvbc9hE2y4yDosBww8Un8anXZpR1Xf96rN9QusV1G92oNcbp1o3 ✓
bot-sniper-1-geyser.yaml buy 4UEZy7LPm7Rxgw22d1bduQHTWHHHYJSpuaoq2iCyPFpnBPGt4C3QUCu9x77vwWugXnyGv4pQQeTbEZEjvyxxiDH2 → sell 21hSHVPKtqse25XybxhdGrpqK1fSxKKeNZGDCD5j568mzRPfyYR1TQs6mAc2moHKT7kaAAfdMC8DPt8VXmu2rviF ✓
bot-sniper-4-pp.yaml buy 4P91y4iPK6y1gPjz65VL6XAcVkT4DbqjHE5vHfX8PLnzqViCy1qZQ44eWiNDUPzoWCejibB7UJPKYAEj4K3Z3c3S ✓ ; sell hit slippage protection (Custom 6003 — program-side, the ix passed deserialization)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(examples): add bonding_curve_v2 remaining account to learning examples
Add the required bonding_curve_v2 PDA as a remaining account to buy/sell
instructions in manual_buy, manual_sell, mint_and_buy, and mint_and_buy_v2
learning examples, matching the pump.fun program upgrade.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(examples): add bonding_curve_v2 to manual_buy_geyser and manual_buy_cu_optimized
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Update all 3 pump.fun IDL files (pump_fun, pump_swap, pump_fees) with
new cashback rewards and fee-sharing features. Fix IDL parser to handle
tuple struct types (OptionBool). Add bonding_curve_v2 remaining account
to all buy/sell instructions as required by the pump.fun program upgrade.
Key changes:
- Fix IDL parser crash on tuple struct fields (string vs dict)
- Add bonding_curve_v2 PDA derivation and append as remaining account
- Add is_cashback_coin field to TokenInfo and BondingCurve decoding
- Propagate is_cashback_enabled from CreateEvent/create_v2 to TokenInfo
- Conditionally include user_volume_accumulator for cashback sell txs
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(core): disable account_data_size limit and add meta.err checking
The 12.5MB setLoadedAccountsDataSizeLimit was causing all buy transactions
to fail with MaxLoadedAccountsDataSizeExceeded since pump.fun migrated to
Token-2022. Transactions landed on-chain (fees paid) but inner instructions
were rejected — the bot paid gas for nothing.
Changes:
- Disable account_data_size in all bot configs (Token-2022 needs >12.5MB)
- Add meta.err check in get_buy_transaction_details() for clear error
reporting when transactions fail on-chain
- Include tx signature in platform_aware.py error messages for debugging
Tested: full buy→sell→cleanup cycle works on pump_fun with geyser listener.
* fix(core): check meta.err in confirm_transaction to detect failed txs
Solana transactions can be "confirmed" (included in a block) but still
fail execution if inner program instructions are rejected. Previously,
confirm_transaction only checked that the tx landed on-chain, causing
silent failures in buy, sell, and cleanup operations.
Now fetches the transaction result after confirmation and checks
meta.err, returning False when the transaction failed. This fixes
the ATA cleanup issue where sells were silently failing with
Custom: 6003 errors, leaving non-zero token balances.
* fix(core): treat failed tx fetch as unconfirmed in confirm_transaction
When _get_transaction_result returns None (RPC failure, timeout, etc.),
the function was falling through to return True — silently treating an
unknown state as success. Now returns False with a warning log.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Fixeschainstacklabs/pumpfun-bonkfun-bot#152
Changes:
- Make uvloop optional with platform-specific markers (Unix only)
- Add winloop as Windows alternative for performance optimization
- Update code to gracefully fall back to standard asyncio when event loop
libraries are unavailable
- Both bot_runner.py and universal_trader.py now detect platform and use
appropriate event loop implementation
This resolves the blocking installation issue for Windows users while
maintaining performance benefits on all platforms. Windows users can now
install and run the bot with winloop for improved performance, or use
standard asyncio as fallback.
Related: https://github.com/smypmsa/gh-triage-reports/blob/main/issues/chainstacklabs-pumpfun-bonkfun-bot/issue-152-2026-02-08.md
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* feat(trading): enhance sell execution with token amount and price parameters to reduce RPC delays
* feat(trading): add method to fetch actual token balance after transaction to improve accuracy
* feat(trading): update account data size limit and enhance price calculations
* feat(core): support multiple initialize instruction variants in LetsBonkEventParser
* feat(core): add creator and platform fee vault derivation methods and update account handling in buy/sell instructions
* feat(letsbonk): add global_config and platform_config to TokenInfo and update address provider logic