Commit Graph

87 Commits

Author SHA1 Message Date
Anton Sauchyk d0dea6d4ac fix(blocks-listener): skip failed txs + use CreateEvent log for canonical creator
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) <noreply@anthropic.com>
2026-04-28 18:44:42 +02:00
Anton Sauchyk 22a0c23450 feat(pumpfun): align src/ with 2026-04-28 program upgrade + cashback path (#167)
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>
2026-04-27 20:39:17 +02:00
Anton Sauchyk 4a48f545c1 feat(pumpfun): update IDLs and add bonding_curve_v2 + cashback support (#159)
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>
2026-02-27 23:39:52 +01:00
Anton Sauchyk 0b6779ca34 Fix buy/sell transactions silently failing on-chain (#157)
* 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>
2026-02-17 10:37:04 +01:00
Alex Kuligowski 40ad32b8d0 feat(core): add RPC rate limiting and retry handling (#154)
* feat(core): add RPC rate limiting, retry logic, and 429 handling

Addresses #44 — users on free-tier RPC endpoints hit HTTP 429 errors
during buy transactions due to no rate limiting or retry handling.

- Add TokenBucketRateLimiter (new file: src/core/rpc_rate_limiter.py)
- Gate all RPC methods through rate limiter (both post_rpc and solana-py calls)
- Rewrite post_rpc() with retry loop, exponential backoff, jitter, and
  specific 429 detection with Retry-After header support
- Replace per-call aiohttp session with shared persistent session
- Wire node.max_rps from YAML bot config through to SolanaClient
- Fix cleanup manager and learning example to use SolanaClient abstraction
  instead of bypassing it via get_client()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(core): address CodeRabbitAI review feedback on rate limiting PR

Validate max_rps > 0 in TokenBucketRateLimiter to prevent ZeroDivisionError
and infinite loops with fractional values. Add asyncio.Lock to _get_session
to fix race condition, handle non-numeric Retry-After headers gracefully,
replace dead json.JSONDecodeError with aiohttp.ContentTypeError, and combine
burn+close into a single transaction in cleanup example.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: document RPC rate limiting feature in README

- Add section on built-in RPC rate limiting with token bucket algorithm
- Document configurable max RPS and automatic retry logic
- Update roadmap to mark "Configurable RPS" as completed
- Clarify benefits of rate limiting for provider compliance

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: use math.ceil for burst_size to handle fractional max_rps

- Replace int(max_rps) with math.ceil(max_rps) in burst_size calculation
- Prevents infinite loop when max_rps < 1.0 (e.g., 0.5 RPS would result in burst_size=0)
- Ensures burst_size is always at least 1 for valid fractional rates
- Addresses CodeRabbit feedback on rpc_rate_limiter.py:27

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(core): validate burst_size and fix table pipe consistency

Address remaining CodeRabbitAI review feedback: add burst_size
validation guard, fix TRY003 lint (use msg variable for ValueError),
break long line under 88 chars, and fix MD055 table pipe style in README.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(core): separate 429 retry budget from error retries in post_rpc

429 responses no longer count against max_retries — they use a dedicated
max_429_retries counter (default 10) so free-tier users hitting rate
limits won't exhaust retries prematurely. Also refresh the aiohttp
session inside the retry loop to avoid stale references after network
failures, and fix cleanup log message accuracy.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Anton Sauchyk <antonsauchyk@gmail.com>
2026-02-17 10:02:11 +01:00
Anton Sauchyk 31955103dc feat: add Windows compatibility for uvloop dependency (#155)
Fixes chainstacklabs/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>
2026-02-09 16:58:24 +04:00
Anton Sauchyk 9d93d859a8 Reduce RPC delays when selling (#150)
* 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
2025-11-23 12:02:29 +01:00
Anton Sauchyk 03a4e7bcbc Add mayhem mode support and Token2022 integration (#149)
* feat: mayhem update in idl

* feat(examples): update bonding curve scripts

* feat(example): update listen_blocksubscribe

* feat(examples): update geyser listener

* feat(examples): update all new token listeners

* feat(examples): add comments, fix printing, formatting

* feat(examples): pumpswap buy and sell update with mayhem mode

* fix(examples): sell pump amm fee recipient

* feat(examples): update decode scripts

* feat(examples): update fetch price

* feat(examples): buy and sell bonding curve scripts

* feat(examples): add mint with mayhem mode enabled

* feat(examples): improve listening to wallet txs

* feat(examples): migration listener improvements

* feat(examples): global vol accumulator is not writable

* feat(examples): support token/token2022 programs in buy instructions

* feat(examples): token/token2022 for pumpswap buy

* feat(examples): token/token2022 supprot for sell instructions

* feat(bot): support create_v2 with token2022, mayhem mode, other fixes

* fix(bot): support only token2022 in logs and pumportal listeners

* feat(bot): token2022 support in cleanup flow

* fix(bot): update token program handling and improve price validation in trading logic

* feat(bot): enhance token program handling for LetsBonk integration
2025-11-18 13:09:37 +01:00
Anton Sauchyk b6928d1f5f feat(core): integrate account data size limit (#144)
* feat(core): integrate account data size limit in buyer and seller transaction

* refactor: format code for improved readability and consistency
2025-10-28 21:21:21 +01:00
Anton 68cac87aad Fix/update letsbonk fun instructions in the bot (#142)
* 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
2025-10-26 16:21:58 +01:00
smypmsa 9731b179cc feat(core): add configurable cu limits 2025-09-03 15:05:12 +00:00
smypmsa e1e15dd539 feat(pumpfun): add fee_config and fee_program, close #132 2025-08-29 15:21:36 +00:00
smypmsa f8e0414ee7 fix(core): handle block listener errors 2025-08-14 09:49:01 +00:00
smypmsa 8ab8932168 docs(claude): add claude code rules 2025-08-11 05:35:25 +00:00
smypmsa a9c58faf9e fix(pump): derive associated bonding curve 2025-08-05 20:30:41 +00:00
smypmsa 329266611c fix(core): minor fixes in hardcoded values 2025-08-05 20:19:00 +00:00
smypmsa 874d148777 fix(core): use logger exception 2025-08-05 16:09:05 +00:00
smypmsa 53763b7123 fix(core): remove unused args, improve logging 2025-08-05 14:56:59 +00:00
smypmsa 7e644286a8 fix(core): remove redundant kwargs 2025-08-05 14:53:53 +00:00
smypmsa 2c2306e80b fix(core): add missing method to event parser interface 2025-08-05 14:53:07 +00:00
smypmsa 3e82cfa128 fix(core): replace os with pathlib 2025-08-05 14:51:48 +00:00
smypmsa 80b03748b0 fix(core): refactor dataclass to use class vars 2025-08-05 14:44:06 +00:00
smypmsa a831cafaf4 fix(core) import level 2025-08-05 14:41:36 +00:00
smypmsa 49c5085764 fix(core): remove silent failures 2025-08-05 14:40:43 +00:00
smypmsa ea1d6b469a feat(core): pump portal fully integrated 2025-08-04 05:40:02 +00:00
smypmsa 2c6da58eb7 fix(core): fix event idl parser for logs 2025-08-04 05:02:53 +00:00
smypmsa 9b6563cecc feat(core): add event idl parser 2025-08-02 19:19:20 +00:00
smypmsa bae03c3fab fix(core): block event processor account keys bytes 2025-08-02 16:41:23 +00:00
smypmsa 26c048c86a fix(core): platform listener check 2025-08-02 16:12:45 +00:00
smypmsa e7107751f5 fix(letsbonk): buy/sell instructions 2025-08-02 15:38:53 +00:00
smypmsa 93332794a3 feat(pump): integrate idl parser manager 2025-08-02 15:10:24 +00:00
smypmsa 9a09862f0d feat(letsbonk): add idl manager 2025-08-02 14:52:40 +00:00
smypmsa 1ddadcd0af feat(letsbonk): integrate idl parser 2025-08-02 14:38:54 +00:00
smypmsa 4acabfb1af wip(letsbonk): idl parser in parser, builder 2025-08-02 14:33:44 +00:00
smypmsa f92f68fc41 wip(core): dynamic idl parser 2025-08-02 14:21:16 +00:00
smypmsa 04342fee5a fix(pump): fix curve management 2025-08-02 14:17:29 +00:00
smypmsa 8ee6b95d2d feat(core): cleanup address management system 2025-08-02 14:03:41 +00:00
smypmsa 227ef0b3bd wip(core): platform aware trading 2025-08-02 13:27:07 +00:00
smypmsa 9ec9eeb793 wip(core): platform aware trading 2025-08-02 11:30:30 +00:00
smypmsa bb35101a8f wip(core): platform aware trading 2025-08-02 09:25:39 +00:00
smypmsa 60c452da0f fix(core): increase cu limit 2025-08-01 12:00:17 +00:00
smypmsa 3faeb1338e feat(core): update buy instruction, add volume_accumulator accounts 2025-08-01 05:25:54 +00:00
smypmsa 536a5dd6a5 docs(cursor): add uv rules, formatting 2025-07-18 12:03:00 +00:00
Bukhtiiarov b74d8df0a9 chore: update generated protobuf files 2025-06-30 15:10:59 +03:00
smypmsa 984f43b757 fix: remove coderabbit syntax bugs 2025-06-15 20:12:54 +00:00
Anton 2ad0f37912 Update src/trading/buyer.py
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-06-15 21:28:23 +02:00
Anton ec1c3afae4 Update src/trading/buyer.py
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-06-15 21:28:03 +02:00
Anton 8f8fa2a526 Update src/trading/position.py
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-06-15 20:50:38 +02:00
Anton 578c24b17f Update src/trading/buyer.py
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-06-15 20:49:40 +02:00
Anton 4bb6b6ae99 Update src/monitoring/pumpportal_listener.py
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-06-15 20:48:32 +02:00