Skip to content

Commit 93af7bf

Browse files
smypmsaclaude
andcommitted
feat: buy, sell and info for Raydium LaunchLab coins
A mint with no pump.fun curve is looked up on LaunchLab, under any launchpad's platform config and any quote asset, with Token-2022 transfer fees counted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent a5ad67a commit 93af7bf

17 files changed

Lines changed: 7848 additions & 77 deletions

File tree

‎CLAUDE.md‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ src/pumpfun_cli/
5252
├── crypto.py # AES-256-GCM wallet encryption (scrypt KDF)
5353
├── output.py # render() + error() — TTY-aware output
5454
├── commands/ # Thin CLI layer (config, info, launch, tokens, trade, tx_status, wallet)
55-
├── core/ # Business logic (config, info, launch, pumpswap, tokens, trade, tx_status, validate, wallet)
56-
└── protocol/ # Solana primitives (address, client, contracts, curve, idl_parser, instructions, pumpswap, quote)
55+
├── core/ # Business logic (config, info, launch, launchlab, pumpswap, tokens, trade, tx_status, validate, wallet)
56+
└── protocol/ # Solana primitives (address, client, contracts, curve, idl_parser, instructions, launchlab, pumpswap, quote)
5757
5858
tests/
5959
├── test_commands/ # CLI smoke tests
@@ -68,7 +68,7 @@ tests/
6868

6969
**Error handling:** `error()` raises `SystemExit` — code after it is unreachable. Core functions return `dict` with `"error"` key for expected failures (graduated tokens, not found, slippage exceeded, insufficient_balance). Catch `ValueError` for wrong wallet password in every command that decrypts. Buy/sell functions perform pre-trade balance validation — SOL for fees and rent, the quote asset for the spend, token balance for sells with specific amounts.
7070

71-
**Auto-routing:** When `buy_token` / `sell_token` returns `{"error": "graduated"}`, the command layer in `commands/trade.py` automatically retries via `buy_pumpswap` / `sell_pumpswap` (PumpSwap AMM). Never suppress or swallow the `"graduated"` error in core — the routing decision belongs in the command layer.
71+
**Auto-routing:** `_route` in `commands/trade.py` picks the venue from the errors core returns: `{"error": "graduated"}` from `buy_token` / `sell_token` retries on PumpSwap, `{"error": "not_found"}` retries on LaunchLab (`buy_launchlab` / `sell_launchlab`). Never suppress or swallow those errors in core — the routing decision belongs in the command layer. `info` falls back to LaunchLab the same way in `core/info.py`.
7272

7373
**Imports:** stdlib → third-party → local. Example:
7474
```python
@@ -133,6 +133,13 @@ lists; these are the ones this CLI depends on.
133133
- `migrate_v2` also carries accounts the IDL omits: after its 27, the new pool's
134134
boost vault authority (`["boost_vault", pool]` on PumpSwap) and that
135135
authority's quote token account. Without them PumpSwap reverts with 6027.
136+
- LaunchLab (`protocol/launchlab.py`) pools are keyed by base and quote mint.
137+
The SOL pool is derived; any other quote is found by `getProgramAccounts`
138+
on the base mint (PoolState offset 205). Swaps are the IDL's 15 accounts plus
139+
the system program and the platform and creator fee vaults
140+
(`[platform_config, quote]`, `[creator, quote]`). The curve fee is
141+
GlobalConfig's trade fee plus PlatformConfig's fee and creator fee, read
142+
live; a Token-2022 coin's transfer fee comes off what arrives.
136143
- `send_tx` sends v0 and falls back to v1 when the transaction exceeds 1232
137144
bytes (a cashback-pool buy, a launch with a buy). v1 carries the compute budget
138145
in its header.

‎README.md‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ pump.fun no longer accepts anonymous metadata uploads, so `launch` takes the
7373
URI of a metadata JSON you host (`name`, `symbol`, `description`, `image`).
7474
Without `--uri` it still tries the upload and says so when it is refused.
7575

76+
`buy`, `sell` and `info` also work on coins launched on Raydium LaunchLab, the
77+
program behind letsbonk.fun, StonkFun and other launchpads: a mint with no
78+
pump.fun bonding curve is looked up there, and the output says `"venue":
79+
"launchlab"` and which launchpad (`platform`). A LaunchLab coin priced in
80+
anything but SOL is found with `getProgramAccounts`, so it needs an RPC that
81+
serves it. Token-2022 transfer fees are taken into account in the amounts.
82+
7683
Amounts are in the coin's quote asset. Most pump.fun coins are priced in SOL,
7784
but a coin can be priced in USDC or another admitted mint; `buy`, `sell` and
7885
`info` read it from the coin and label their output with it. Buying such a coin
@@ -106,7 +113,7 @@ Token discovery (zero config; price and progress added when an RPC is set):
106113
pumpfun tokens search <query> Search by name or ticker
107114
108115
Token info (requires RPC):
109-
pumpfun info <mint> Price, bonding progress, reserves
116+
pumpfun info <mint> Price, bonding progress, reserves (pump.fun or LaunchLab)
110117
111118
Trading (requires RPC + wallet):
112119
pumpfun buy <mint> <amount> [--slippage N] [--force-amm] [--dry-run] [--confirm]
@@ -157,9 +164,9 @@ Global options:
157164
| `tokens recommended` | `frontend-api-v3.pump.fun/coins/recommendations` | HTTPS |
158165
| `tokens search` | `frontend-api-v3.pump.fun/coins/search-unrestricted` | HTTPS |
159166
| `tokens *` with an RPC set | + Solana RPC (`getMultipleAccounts` for the bonding curves) | JSON-RPC |
160-
| `info` | Solana RPC (`getAccountInfo` for bonding curve PDA) | JSON-RPC |
161-
| `buy` | Solana RPC (`getAccountInfo`, `getLatestBlockhash`, `sendTransaction`) | JSON-RPC |
162-
| `sell` | Solana RPC (`getAccountInfo`, `getTokenAccountBalance`, `getLatestBlockhash`, `sendTransaction`) | JSON-RPC |
167+
| `info` | Solana RPC (`getAccountInfo` for bonding curve PDA; LaunchLab: `getMultipleAccounts`, `getProgramAccounts`) | JSON-RPC |
168+
| `buy` | Solana RPC (`getAccountInfo`, `getLatestBlockhash`, `sendTransaction`; LaunchLab adds `getMultipleAccounts`, `getProgramAccounts`) | JSON-RPC |
169+
| `sell` | Solana RPC (`getAccountInfo`, `getTokenAccountBalance`, `getLatestBlockhash`, `sendTransaction`; LaunchLab as `buy`) | JSON-RPC |
163170
| `launch` | Solana RPC (`sendTransaction`); `pump.fun/api/ipfs` only without `--uri` | JSON-RPC (+ HTTPS) |
164171
| `tx-status` | Solana RPC (`getTransaction`) | JSON-RPC |
165172
| `migrate` | Solana RPC (`sendTransaction`) | JSON-RPC |

0 commit comments

Comments
 (0)