67 Commits

Author SHA1 Message Date
Anton Sauchyk cc85daaeb3 chore(pumpswap): post-2026-04-28 cutover + cashback layout (#168)
* 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>
2026-04-28 18:20:53 +02:00
Anton Sauchyk bda9099275 chore(examples): accept argv override and bump RPC timeouts
Three small ergonomic fixes uncovered while running every learning
example end-to-end:

  copytrading/listen_wallet_transactions.py
    Was hardcoded to WALLET_TO_TRACK = "...". Now accepts argv[1] so
    you can run it without editing the file.

  pumpswap/get_pumpswap_pools.py
    Same pattern (TOKEN_MINT placeholder) and the underlying
    getProgramAccounts call would also time out at the default 30s
    on busy mainnet RPCs — bumped both AsyncClient timeouts to 120s.

  bonding-curve-progress/get_graduating_tokens.py
    Bumped RPC timeout 120s → 240s for the same reason. The threshold
    scan over all pump.fun bonding curves still occasionally exceeds
    even that on overloaded RPCs (it's a known-heavy query); a smaller
    threshold or memcmp-narrowed filter is the proper long-term fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 19:52:41 +02:00
Anton Sauchyk ad6d2cc755 fix(examples): add pool-v2 account to pumpswap, repair geyser listener
PumpSwap (manual_buy_pumpswap.py / manual_sell_pumpswap.py)
  - Real on-chain pump-swap buys use 24 accounts; the IDL is incomplete
    (lists 23). Missing 24th account is pool-v2 PDA, derived from seed
    ["pool-v2", base_mint] under the pump-amm program.
  - Without it, pump-amm throws AnchorError 6023 (Overflow) at buy.rs:400/414
    after the trade transfers complete (the source of the earlier "pre-existing
    overflow" — was actually a missing account, not a math bug).
  - find_pool_v2(base_mint) added; appended to both buy and sell account lists
    after fee_program. The April-28 breaking-fee accounts (still gated behind
    INCLUDE_BREAKING_FEE_ACCOUNTS) come after pool-v2 — matching the doc's
    "All accounts till bonding-curve-v2 and pool-v2 remain the same."
  - AsyncClient timeout bumped to 120s so the heavy getProgramAccounts pool
    lookup doesn't time out on slower RPC paths.
  - Live-verified on mainnet with 9PwadsGz...pump:
      buy   2xgdJJsDMzoMyxJzrCATKwGfpX7M... err=None (24 accounts)
      sell  4vdBkGpCMQYEWncj5k1suGzKPUMQ... err=None (24 accounts)

manual_buy_geyser.py
  - Fixes IndexError when create tx references ALT-loaded keys
    (matches the same fix applied to manual_buy.py).
  - Re-enables the 15s sleep + on-chain price/fee_recipient lookup that
    were commented out for testing — needed for buys on real pools.
  - Live-verified: 45wSgX2Pu1LLZWLgu3e9qdhRaGJjqwMqQP5HdeV7zMBqNXziB2uEgxQd5bAqvAhBLFnAqzbuK3LAWowhxZxdemJ
    (18-account buy, err=None) on Token-2022 cashback-enabled INSIDER mint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 18:35:13 +02:00
Anton Sauchyk 57ffe8bfbb feat(examples): apply 18-account buy upgrade to mint_and_buy + pumpswap
Extends the 2026-04-28 program-upgrade prep (commit c25e2ed) to the
remaining trade scripts:
  mint_and_buy.py              — 18-account buy after bonding-curve-v2.
                                 Tested live with a fresh TEST mint (Solscan
                                 sig 62EZFCKVuxvqmzj...), succeeded.
  mint_and_buy_v2.py           — 18-account buy. Tested live with a
                                 mayhem-mode TEST2 token (Token-2022 + 5
                                 mayhem accounts), Solscan sig 44SvQSrhmHy...,
                                 succeeded.
  pumpswap/manual_buy_pumpswap.py / manual_sell_pumpswap.py
                               — Adds the 2 new pump-swap accounts (fee
                                 recipient + its quote-mint ATA) gated behind
                                 INCLUDE_BREAKING_FEE_ACCOUNTS = False; flip
                                 to True after 2026-04-28 16:00 UTC.
                                 Pre-existing program-side overflow at
                                 buy.rs:400 (AnchorError 6023) flagged in
                                 a comment — affects current pump-swap
                                 buys, unrelated to this upgrade.

Both pumpswap scripts now also accept TOKEN_MINT via argv[1].

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 18:09:14 +02:00
Anton Sauchyk c25e2edb57 feat(examples): add 18-account buy / 16-17-account sell for 2026-04-28 upgrade
pump.fun program upgrade scheduled for 2026-04-28 16:00 UTC adds one new
mutable account (one of 8 fee recipients) at the end of buy/sell ixs,
after bonding-curve-v2. The new format is already accepted on mainnet
ahead of the cutover, so applying now keeps scripts working on both
sides of the upgrade.

Doc: github.com/pump-fun/pump-public-docs/blob/main/docs/BREAKING_FEE_RECIPIENT.md

Per file:
  manual_buy.py            — 18-account buy. Also fixes a pre-existing
                             listener crash on Address-Lookup-Table create
                             txs (skips them) and adds bool/OptionBool
                             handling to decode_create_instruction so
                             create_v2 doesn't raise on its trailing args.
  manual_buy_cu_optimized.py — 18-account buy. Bumps the CU-optimization
                             account-data limit to 16MB (tested) — older
                             values trigger MaxLoadedAccountsDataSizeExceeded
                             on Token-2022/cashback coins. Same listener
                             ALT-skip and decoder bool fixes.
  manual_buy_geyser.py     — 18-account buy. Re-enables price calculation
                             and mayhem-mode-aware fee_recipient detection
                             (was scaffolded out for testing).
  manual_sell.py           — 16-account non-cashback / 17-account cashback
                             sell. Reads is_cashback_coin from BC byte 82
                             and inserts user_volume_accumulator before
                             bonding-curve-v2 when needed. TOKEN_MINT now
                             accepts argv[1] override.

Live-verified on mainnet:
  buy   manual_buy.py             3AVnLC3sdBD598cs3... + 3bWU9bB8U9aemA2BFhS2...
  buy   manual_buy_cu_optimized   2PfH5rHw62o3KkQ3N4z8...
  sell  manual_sell.py            3E7dyPBPBRe95BtPQXmb... + 5L4wWSzPV36m6XqXAswB...
All four show the expected 18 (buy) / 16 (sell non-cashback) account count
with one of the 8 BREAKING_FEE_RECIPIENTS as the trailing mutable account.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 17:43:31 +02:00
Anton Sauchyk 9b4841890c fix(examples): align listeners and decoders with refreshed pump.fun IDL
Refreshes the read-only learning examples (Phase A3) against the post
Feb–Apr 2026 IDL changes:
  - CreateEvent now has 15 fields (timestamp, 4×u64 reserves, token_program,
    is_mayhem_mode, is_cashback_enabled). Listener parsers were truncating
    after `creator`; the v2 ones were also reading is_mayhem_mode at the
    wrong offset.
  - BondingCurve account is now 83 bytes (added is_cashback_coin).
  - PumpSwap Pool account is now 245 bytes (added is_cashback_coin) — the
    listen_programsubscribe dataSize filter was matching nothing.
  - IDL instruction `createV2` was renamed to `create_v2`; the legacy
    `create` instruction added a `creator: pubkey` arg in March 2026.
  - decode_from_blockSubscribe.py decoder now handles bool, i64, u32, u16,
    u8, and the OptionBool defined type (1-byte wire format).

Files touched (all under learning-examples/):
  bonding-curve-progress/get_bonding_curve_status.py  — V4 struct (cashback)
  bonding-curve-progress/poll_bonding_curve_progress.py
  decode_from_blockSubscribe.py
  decode_from_getAccountInfo.py
  decode_from_getTransaction.py
  listen-migrations/compare_migration_listeners.py
  listen-migrations/listen_programsubscribe.py
  listen-new-tokens/compare_listeners.py
  listen-new-tokens/listen_blocksubscribe.py
  listen-new-tokens/listen_geyser.py
  listen-new-tokens/listen_logsubscribe.py
  listen-new-tokens/listen_logsubscribe_abc.py

Verified live against mainnet — listeners decode tokens including
mayhem-mode and cashback-enabled curves correctly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 16:42:11 +02:00
Anton Sauchyk 546b94af6f fix(examples): add bonding_curve_v2 to learning examples (#160)
* 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>
2026-02-27 23:54:18 +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 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 7ae8b560bd feat(pumpswap): update pool account to writable for buy/sell instructions (#146) 2025-11-04 17:06:22 +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
smypmsa ec6d58665d docs(examples): update comments for cu optimization in manual buy script 2025-10-27 22:06:40 +00:00
smypmsa 3f20649d0e fix(examples): clarify cu optimized buy script 2025-10-27 22:01:13 +00:00
Anton 8367611ed7 feat(example): add pump buy script with compute unit optimization (#143) 2025-10-27 00:21:56 +01:00
Anton d64b51da44 fix(examples): mint and buy script (#141)
* fix(examples): remove hardcoded token mints

* feat(core): update pump idls

* feat(examples): add track volume bool to mint script

* feat(examples): add extend acc instr to mint
2025-10-25 15:01:04 +02:00
Anton 25c376dd02 Feat/letsbonk examples (#140)
* feat: update letsbonk idl

* feat: add letsbonk examples
2025-10-22 00:20:30 +02:00
smypmsa 3fb0a9a549 feat(examples): listen and parse wallet txs 2025-09-23 20:27:22 +00: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 eefd15a6b7 fix(examples): module path 2025-08-14 16:56:41 +00:00
smypmsa 0dc7c28499 feat(examples): add bonding curve geyser-buy example 2025-08-14 16:44:19 +00:00
smypmsa 0eb8811d78 chore(examples): remove hardcoded token mints 2025-08-14 10:00:19 +00:00
smypmsa 8ab8932168 docs(claude): add claude code rules 2025-08-11 05:35:25 +00:00
smypmsa 83a7f9e4ad docs(readme): add letsbonk, update commands 2025-08-05 15:18:22 +00:00
smypmsa d2f157e7f0 feat(examples): update pump amm buy instruction 2025-08-01 05:11:31 +00:00
smypmsa 4fd3181612 feat(examples): update bonding curve buy instructions 2025-08-01 05:05:55 +00:00
Ved Patel 40b5e36154 fix(examples): wrapping SOL before pumpswap buy 2025-07-03 17:12:25 -07:00
smypmsa feaedfd91f feat(examples): add mint and buy example 2025-06-29 19:21:40 +00:00
smypmsa 66c6bc37ab fix(examples): compare listeners print width 2025-06-29 19:06:15 +00:00
smypmsa ddbe5970a2 fix(examples): remove redunant imports, comments 2025-06-28 09:52:53 +00:00
Sheng-Yan fb571337c5 fix: retry send_transaction 2025-06-24 10:50:23 +08:00
Sheng-Yan 83c7bb3414 fix: add idempotent_ata_ix 2025-06-23 10:37:28 +08:00
Zhang ShengYan 00216972bf fix:use STRUCT_2 to parse creator 2025-06-08 19:53:30 +08:00
Zhang ShengYan 49504f5106 fix: correct the name of file 2025-06-04 16:55:58 +08:00
smypmsa 06166dd8fc fix(examples): correct formula for bonding curve progress 2025-05-26 14:19:13 +00:00
smypmsa 9495d250b9 fix(pumpswap): set global config writable false 2025-05-15 13:29:31 +00:00
Anton 44e2c83120 fix: remove duplicated function 2025-05-14 17:36:23 +02:00
Anton 957722ba73 Update learning-examples/decode_from_getAccountInfo.py
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-05-14 17:33:17 +02:00
smypmsa f80e06e180 fix: repair pumpswap buy tx 2025-05-14 15:25:04 +00:00
smypmsa e4675c5284 feat: update rest of scripts with creator fee 2025-05-14 07:22:35 +00:00
smypmsa f811632c3c feat: manual buy and sell with creator fee 2025-05-13 07:38:46 +00:00
smypmsa e41a5f4f4f feat(core): add support for creator fee update 2025-05-12 20:07:51 +00:00
smypmsa aa145dc018 feat: add geyser auth type, compare listeners for new tokens 2025-05-06 08:39:13 +00:00
smypmsa 81c2af4af1 feat: add example of programSubscribe listener for migrations, group examples into subfolders 2025-04-21 11:36:09 +00:00
smypmsa b9e29a8b12 feat: add geyser listener script 2025-04-14 15:02:52 +00:00
smypmsa 6e3b1b3b41 feat: add mint address extraction for graduating tokens 2025-04-13 20:23:58 +00:00
smypmsa 18ee63b2b9 feat: add get graduating tokens script 2025-04-09 11:56:44 +00:00
smypmsa 68c8251ccf feat: add track bonding curve progress script 2025-04-02 15:36:58 +00:00
smypmsa c5a0258aa7 fix: use base64 explicitly 2025-04-01 14:57:01 +00:00
Anton 54f3bd4b0e Merge pull request #75 from chainstacklabs/feat/pumpswap-sell-script
Sell tokens on PumpSwap script (learning example)
2025-04-01 08:13:49 +00:00