fix(learning-examples): repair crashing listeners and decoders, prune obsolete paths, unify naming (#181)

Audited every script in learning-examples/ against mainnet.

Broken — found by running them, all invisible offline:

- listen_geyser.py crashed with IndexError after ~11 coins: it never resolved
  v0 address-lookup-table accounts, which geyser reports in
  meta.loaded_writable_addresses / loaded_readonly_addresses. Resolving them
  removes the crash and brings detections level with the WebSocket listeners,
  35 coins each per 150 s.
- compare_listeners.py logged 13,090,862 error lines / 888 MB in 150 s and never
  printed its own 30-second report: the inner recv() loop caught ConnectionClosed
  in a broad handler that only logged, so every following recv() raised at once
  and the outer reconnect handler was unreachable. Now 12 KB and exit 0. Same
  shape fixed in compare_migration_listeners.py, listen_blocksubscribe.py and
  extract_blocksubscribe_transactions.py; the last two also gained the reconnect
  loop their siblings already had.
- decode_from_gettransaction.py matched instructions on account count instead of
  discriminator, reporting a real 19-account create_v2 as claim_cashback with
  every account under the wrong name. It also walked only top-level
  instructions, and in 40 consecutive pump.fun transactions there was 1
  top-level pump instruction against 8 inner ones.
- decode_from_blocksubscribe.py crashed on every real create_v2: on chain the
  trailing args are variable length, 0001 in one tx and 00 in another, so
  is_cashback_enabled can be absent entirely.
- poll_bonding_curve_progress.py polled a hardcoded dead mint and took no argv.

Obsolete:

- Delete listen_blocksubscribe_old_raydium.py. Seven minutes on mainnet produced
  0 initialize2 events while the wrapper listener caught 3 real migrations.
- Delete the duplicate geyser stubs and protos under listen-new-tokens/. The
  protos were byte-identical to src/geyser/proto and the stubs had drifted; both
  geyser examples now import src.geyser.generated.
- Recapture all four fixtures. The old ones were from Aug 2024 and included a
  49-byte pre-creator bonding curve.

Behind the protocol:

- fetch_price.py, get_bonding_curve_status.py, poll_bonding_curve_progress.py
  and decode_from_getaccountinfo.py never read quote_mint and scaled by a
  hardcoded 1e9. Against a live USDC-paired curve the price was off by 1000x.
- get_pumpswap_pools.py stopped parsing at coin_creator and missed the i128
  virtual_quote_reserves. Live pools carry 17.5845 SOL of them, which
  under-prices by 3.5-23.9% when ignored.

Duplication and naming:

- Merge manual_buy_cu_optimized.py into manual_buy.py --cu-optimized. The
  deleted file's docstring said 512 KB while its code used 16 MB; simulation
  confirms 512 KB and 4 MB both fail MaxLoadedAccountsDataSizeExceeded on
  Token-2022 mints, so 16 MB is the correct value.
- Merge listen_logsubscribe_abc.py into listen_logsubscribe.py. Its ATA
  derivation hardcoded the legacy token program, so every Associated BC it
  printed for a Token2022 coin was an address that does not exist on chain.
  Fixed on merge and cross-checked 59/59 against on-chain accounts.
- Remove 19 dead symbols. BREAKING_FEE_RECIPIENTS is still live in the PumpSwap
  scripts and stays there.
- Normalize naming: kebab-case directories, RPC method names as one lowercase
  token, scripts verb-first. Rules documented in CLAUDE.md.

get_graduating_tokens.py is knowingly left broken: getProgramAccounts over the
whole pump program is now rejected by providers and it needs a
getProgramAccountsV2 rewrite, which belongs in its own PR.

Verified: both offline gates pass, all 41 examples parse, every read-only script
exercised on mainnet against SOL- and USDC-paired coins, no new ruff findings
(427 -> 413). No script that spends real funds was run.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Anton Sauchyk
2026-07-29 15:26:26 +02:00
committed by GitHub
co-authored by Claude Opus 5
parent 5c1fb7eb28
commit a33f4fd035
44 changed files with 3255 additions and 5022 deletions
@@ -1,274 +0,0 @@
{
"transaction": [
"AYqt4iSMLUKIiCn+roUn59P7c0BroL8VCv5X+0515tjH9d5OCez5MIQdftuWcDwEymBNZMWiqy51LDU76WpahAMBAAoTcFi8Lm3PgW7X4XZm7q8+G4Jf4IaSLzptQdkNfSFrd2kW7510gs4rvSfIQ6BD7SbUQJaGC396SVFLuDF387+XgV1pfIfVUZFTFHxe1tb+5NIGBoToM9rJFbh9akpqDSa8XwszrDDJuVPznYGftPUIqlfBd55SSEGIUQWL6ZogaoujB/IYgIAD1tGqXa268xcm661aIHELJcoHVKW8TJPIRaOJkcMpfWvPuYxyTGf253mdFudiJ5NiHvVmi0CTGjvCsU4N5V6fuoY5br/VSM/4ySAR6se3W6qbLZxqhvWhcUHXqo+wYNgpG0xNR12v92LJa9wNrOs2wBLq0S7TqUhBYfprphss/CT2/qy59h94SA3zpgqeFhalg6tebfEaQX2yAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVuD2k2Zaz0TbFWi/F1uqUYnLl/XS/ztlXSu2/W0YsAMGRm/lIRcy/+ytunLDm+e8jOW7xfcSayxDmzpAAAAABt324ddloZPZy+FGzut5rBy0he1fWzeROoz1hX7/AKkG3fbh7nWP3hhCXbzkbM3athr8TYO5DSf+vfko2KGL/Ai2qPUzOEL8dkpbTkkIfplULeP8horDFNap3dmbsYVGOoZeae4PVIDKvPZjV+TcLxjVjUXB6nSJ+zcj2Xk8cqZE+dQlVubfmlZx8g4Yr7VZS6dIqY5CCXXxzYTAYMWwb4yXJY9OJInxuz0QKRSODYMLWhOZ2v8QhASOe9jb6fhZrPE26wH8HE6IPSPItYRKtZo39mrdV8XprDtT4FnTXGT58ypqlPJGff+K9zL4EgTVmKxLEmG7xOccSwzdPrM4LwULAAUCiIoBAAsACQM83OEAAAAAAAkCAAYMAgAAAAAbtwAAAAAAEQYABQAQCQwBAA4PCQwKAgABBQMNDwcQCAQSXgAA4DIpAAAAAAAAAAAAAAAAAMGhI2gAAAAADAkBCgALAQAIDAAABgAEAAIBAQ0ADgEAAxgAZgY9EgHa6+quClnNAQIAAGjN5REAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
"base64"
],
"meta": {
"err": null,
"status": {
"Ok": null
},
"fee": 1500000,
"preBalances": [
2005440908,
0,
4696550893895,
13463471281,
377180764,
0,
57019670,
4441807831495,
2039280,
1,
1141440,
1,
934087680,
1141440,
1141440,
290898417,
1461600,
731913600,
137104014
],
"postBalances": [
1686928628,
0,
4696553593895,
13760771281,
377329414,
2039280,
69019670,
4441810655845,
2039280,
1,
1141440,
1,
934087680,
1141440,
1141440,
290898417,
1461600,
731913600,
137104014
],
"innerInstructions": [
{
"index": 3,
"instructions": [
{
"programIdIndex": 12,
"accounts": [
16
],
"data": "84eT",
"stackHeight": 2
},
{
"programIdIndex": 9,
"accounts": [
0,
5
],
"data": "11119os1e9qSs2u7TsThXqkBSRVFxhmYaFKFZ1waB2X7armDmvK3p5GmLdUxYdg3h7QSrL",
"stackHeight": 2
},
{
"programIdIndex": 12,
"accounts": [
5
],
"data": "P",
"stackHeight": 2
},
{
"programIdIndex": 12,
"accounts": [
5,
16
],
"data": "6UhFp3r3cKbQWwHQYPuDqtb5CAdjXP45vy8Z8DQwgGRSQ",
"stackHeight": 2
}
]
},
{
"index": 4,
"instructions": [
{
"programIdIndex": 9,
"accounts": [
0,
2
],
"data": "3Bxs4eMeB358Cb5h",
"stackHeight": 2
},
{
"programIdIndex": 10,
"accounts": [
15,
7,
16,
3,
8,
5,
0,
9,
12,
4,
18,
10
],
"data": "AJTQ2h9DXrBo1MiibpgfkQHmpSKmNnQgP",
"stackHeight": 2
},
{
"programIdIndex": 12,
"accounts": [
8,
5,
3
],
"data": "3SpdELLWnXkK",
"stackHeight": 3
},
{
"programIdIndex": 9,
"accounts": [
0,
4
],
"data": "3Bxs4VLT5WjmR4oh",
"stackHeight": 3
},
{
"programIdIndex": 9,
"accounts": [
0,
3
],
"data": "3Bxs46HNXQ8jq79R",
"stackHeight": 3
},
{
"programIdIndex": 9,
"accounts": [
0,
7
],
"data": "3Bxs4TJNecvxKcVV",
"stackHeight": 3
},
{
"programIdIndex": 10,
"accounts": [
18
],
"data": "2zjR1PvPvgqdhPdZLxuWCL7GiE5h1bKn4ziAcRd2FBFaC3kf2EYsG31a2aigsk9mgAfieqmo561JLMNk2uSKF65QKzv64GtLAULg9zNrDFfLe7DrBDcgQBwTwRqqLVkWBrksYNBFeyBeSPwcQe5DNEEqwfSowV6pk2t9QuN6JDSpxRegP8ekTV5zwc3ytD2hSo7wu9s4ynRb5ccHwRaoy9Lzm7M66sikRLa74mXuFzdjzGuq454PDDP8eqUSWxt1ddTchsUvqsAnv92vMN2BLu7XZ3UcTv96fz8KrV93qqHSsNwfKdCsY7QMwxbCE7R",
"stackHeight": 3
}
]
}
],
"logMessages": [
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success",
"Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]",
"Program log: Create",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: GetAccountDataSize",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1569 of 93653 compute units",
"Program return: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA pQAAAAAAAAA=",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program log: Initialize the associated token account",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: InitializeImmutableOwner",
"Program log: Please upgrade to SPL Token 2022 for immutable owner support",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1405 of 87066 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: InitializeAccount3",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4188 of 83184 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 21837 of 100550 compute units",
"Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success",
"Program b1oomGGqPKGD6errbyfbVMBuzSC8WtAAYo8MwNafWW1 invoke [1]",
"Program log: Powered by https://telegram.bloombot.app",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P invoke [2]",
"Program log: Instruction: Buy",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
"Program log: Instruction: Transfer",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 49415 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program 11111111111111111111111111111111 invoke [3]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [3]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [3]",
"Program 11111111111111111111111111111111 success",
"Program data: vdt/007mYe5E+dQlVubfmlZx8g4Yr7VZS6dIqY5CCXXxzYTAYMWwbyBwuBEAAAAAT+SenZMEAAABcFi8Lm3PgW7X4XZm7q8+G4Jf4IaSLzptQdkNfSFrd2m6oSNoAAAAALHaOjAKAAAAgP3BigudAgCxLhc0AwAAAIBlrz56ngEA16qPsGDYKRtMTUddr/diyWvcDazrNsAS6tEu06lIQWFfAAAAAAAAAJ4YKwAAAAAAkJajVbvLxqgCZ/z53+NIXoh5GMXQLRXjoGjmO6GR/6UFAAAAAAAAAKpEAgAAAAAA",
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P invoke [3]",
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P consumed 2006 of 33261 compute units",
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P success",
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P consumed 40072 of 70491 compute units",
"Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P success",
"Program b1oomGGqPKGD6errbyfbVMBuzSC8WtAAYo8MwNafWW1 consumed 48895 of 78713 compute units",
"Program b1oomGGqPKGD6errbyfbVMBuzSC8WtAAYo8MwNafWW1 success"
],
"preTokenBalances": [
{
"accountIndex": 8,
"mint": "5eFg3giaX2c3RydHvx1S3yEKpYjBuwtLUsmbAAG9pump",
"uiTokenAmount": {
"uiAmount": 667654902.731215,
"decimals": 6,
"amount": "667654902731215",
"uiAmountString": "667654902.731215"
},
"owner": "7Q1e26aB8kpyamjKPCt5oD73b2Hx7nAEjAMUwfHmZy7G",
"programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
}
],
"postTokenBalances": [
{
"accountIndex": 5,
"mint": "5eFg3giaX2c3RydHvx1S3yEKpYjBuwtLUsmbAAG9pump",
"uiTokenAmount": {
"uiAmount": 5032051.139663,
"decimals": 6,
"amount": "5032051139663",
"uiAmountString": "5032051.139663"
},
"owner": "8ZZ97eWp2k8gfoK2Jk2WQcdofk9hyJpEGDPGiqFryH1S",
"programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
},
{
"accountIndex": 8,
"mint": "5eFg3giaX2c3RydHvx1S3yEKpYjBuwtLUsmbAAG9pump",
"uiTokenAmount": {
"uiAmount": 662622851.591552,
"decimals": 6,
"amount": "662622851591552",
"uiAmountString": "662622851.591552"
},
"owner": "7Q1e26aB8kpyamjKPCt5oD73b2Hx7nAEjAMUwfHmZy7G",
"programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
}
],
"rewards": null,
"loadedAddresses": {
"writable": [],
"readonly": []
},
"computeUnitsConsumed": 71182
},
"version": "legacy"
}