pumpfun-python 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pumpfun_python-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +16 -0
- pumpfun_python-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +9 -0
- pumpfun_python-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +5 -0
- pumpfun_python-0.1.0/.github/workflows/ci.yml +33 -0
- pumpfun_python-0.1.0/.gitignore +32 -0
- pumpfun_python-0.1.0/CHANGELOG.md +13 -0
- pumpfun_python-0.1.0/CONTRIBUTING.md +32 -0
- pumpfun_python-0.1.0/LICENSE +21 -0
- pumpfun_python-0.1.0/PKG-INFO +208 -0
- pumpfun_python-0.1.0/README.md +176 -0
- pumpfun_python-0.1.0/pumpfun/__init__.py +53 -0
- pumpfun_python-0.1.0/pumpfun/bonding_curve.py +364 -0
- pumpfun_python-0.1.0/pumpfun/constants.py +43 -0
- pumpfun_python-0.1.0/pumpfun/pda.py +65 -0
- pumpfun_python-0.1.0/pumpfun/pumpswap.py +262 -0
- pumpfun_python-0.1.0/pumpfun/py.typed +0 -0
- pumpfun_python-0.1.0/pyproject.toml +68 -0
- pumpfun_python-0.1.0/tests/test_bonding_curve.py +297 -0
- pumpfun_python-0.1.0/tests/test_constants.py +52 -0
- pumpfun_python-0.1.0/tests/test_pda.py +91 -0
- pumpfun_python-0.1.0/tests/test_pumpswap.py +303 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: ${{ matrix.python-version }}
|
|
21
|
+
- run: pip install -e ".[dev]"
|
|
22
|
+
- run: pytest -v
|
|
23
|
+
- run: ruff check .
|
|
24
|
+
|
|
25
|
+
type-check:
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
- uses: actions/setup-python@v5
|
|
30
|
+
with:
|
|
31
|
+
python-version: "3.12"
|
|
32
|
+
- run: pip install -e ".[dev]"
|
|
33
|
+
- run: mypy pumpfun/
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Virtual environments
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
env/
|
|
10
|
+
|
|
11
|
+
# Distribution / packaging
|
|
12
|
+
dist/
|
|
13
|
+
build/
|
|
14
|
+
*.egg-info/
|
|
15
|
+
*.egg
|
|
16
|
+
|
|
17
|
+
# IDE
|
|
18
|
+
.idea/
|
|
19
|
+
.vscode/
|
|
20
|
+
*.swp
|
|
21
|
+
*.swo
|
|
22
|
+
|
|
23
|
+
# OS
|
|
24
|
+
.DS_Store
|
|
25
|
+
Thumbs.db
|
|
26
|
+
|
|
27
|
+
# Testing
|
|
28
|
+
.pytest_cache/
|
|
29
|
+
htmlcov/
|
|
30
|
+
.coverage
|
|
31
|
+
.mypy_cache/
|
|
32
|
+
.ruff_cache/
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 (2025-07-10)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- PumpFun bonding curve v2 buy/sell instruction builders (16/14 accounts)
|
|
7
|
+
- PumpSwap AMM constant-product swap instruction builder (13 accounts)
|
|
8
|
+
- On-chain bonding curve state reader with full field parsing
|
|
9
|
+
- PumpSwap pool state reader (legacy + Pump AMM layouts)
|
|
10
|
+
- Price calculation helpers — `calculate_buy_amount`, `calculate_sell_amount`, `calculate_swap_output`
|
|
11
|
+
- PDA derivation — bonding curve, creator vault, volume accumulators, fee config, ATA
|
|
12
|
+
- All program IDs and discriminators for PumpFun, PumpSwap, and Pump AMM
|
|
13
|
+
- Full type hints with py.typed marker
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Contributing to pumpfun-python
|
|
2
|
+
|
|
3
|
+
## Development Setup
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
git clone https://github.com/JinUltimate1995/pumpfun-python.git
|
|
7
|
+
cd pumpfun-python
|
|
8
|
+
python -m venv .venv
|
|
9
|
+
source .venv/bin/activate
|
|
10
|
+
pip install -e ".[dev]"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Running Tests
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pytest
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Code Quality
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
ruff check .
|
|
23
|
+
mypy pumpfun/
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Pull Requests
|
|
27
|
+
|
|
28
|
+
1. Fork the repo
|
|
29
|
+
2. Create a feature branch
|
|
30
|
+
3. Add tests for new functionality
|
|
31
|
+
4. Ensure all tests pass
|
|
32
|
+
5. Submit a PR
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 JinUltimate1995
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pumpfun-python
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Buy and sell on PumpFun bonding curves + PumpSwap AMM. Directly from Python.
|
|
5
|
+
Project-URL: Homepage, https://github.com/JinUltimate1995/pumpfun-python
|
|
6
|
+
Project-URL: Repository, https://github.com/JinUltimate1995/pumpfun-python
|
|
7
|
+
Project-URL: Issues, https://github.com/JinUltimate1995/pumpfun-python/issues
|
|
8
|
+
Author: JinUltimate1995
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: amm,async,bonding-curve,crypto,defi,dex,pumpfun,pumpswap,python,solana,trading
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Framework :: AsyncIO
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Requires-Dist: httpx>=0.27
|
|
25
|
+
Requires-Dist: solders>=0.21
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# pumpfun-python
|
|
34
|
+
|
|
35
|
+
**Buy and sell on PumpFun bonding curves + PumpSwap AMM. Directly from Python. No Jupiter needed.**
|
|
36
|
+
|
|
37
|
+
[](https://www.python.org/downloads/)
|
|
38
|
+
[](LICENSE)
|
|
39
|
+
[](https://peps.python.org/pep-0561/)
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Why?
|
|
44
|
+
|
|
45
|
+
PumpFun tokens start on a **bonding curve** and graduate to a **PumpSwap AMM pool**. Jupiter doesn't always route through these — and when it does, you're at the mercy of their routing engine. This library builds the raw Solana instructions so you can swap directly.
|
|
46
|
+
|
|
47
|
+
- **Pre-graduation** — buy/sell against the PumpFun bonding curve (v2, 16/14 accounts)
|
|
48
|
+
- **Post-graduation** — swap on PumpSwap AMM pools (constant-product, 13 accounts)
|
|
49
|
+
- **Zero dependencies beyond solders + httpx** — no SDK bloat
|
|
50
|
+
- **Production-tested** — extracted from a live trading system
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install pumpfun-python
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or from source:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install git+https://github.com/JinUltimate1995/pumpfun-python.git
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Quick Start
|
|
69
|
+
|
|
70
|
+
### 💰 Calculate buy/sell amounts (no RPC needed)
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from pumpfun import calculate_buy_amount, calculate_sell_amount
|
|
74
|
+
|
|
75
|
+
# How many tokens for 0.1 SOL?
|
|
76
|
+
tokens = calculate_buy_amount(
|
|
77
|
+
sol_amount_lamports=100_000_000, # 0.1 SOL
|
|
78
|
+
virtual_sol_reserves=30_000_000_000,
|
|
79
|
+
virtual_token_reserves=1_000_000_000_000,
|
|
80
|
+
)
|
|
81
|
+
print(f"Tokens received: {tokens:,}")
|
|
82
|
+
|
|
83
|
+
# How much SOL for selling 1M tokens?
|
|
84
|
+
sol_out = calculate_sell_amount(
|
|
85
|
+
token_amount=1_000_000,
|
|
86
|
+
virtual_sol_reserves=30_000_000_000,
|
|
87
|
+
virtual_token_reserves=1_000_000_000_000,
|
|
88
|
+
)
|
|
89
|
+
print(f"SOL received: {sol_out / 1e9:.6f}")
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 📈 Read bonding curve state
|
|
93
|
+
|
|
94
|
+
> **RPC calls require your own Solana RPC endpoint.** Get a free key from [Helius](https://helius.dev), [QuickNode](https://quicknode.com), or use the public endpoint (rate-limited).
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
import asyncio
|
|
98
|
+
from pumpfun import fetch_bonding_curve_state
|
|
99
|
+
|
|
100
|
+
async def main():
|
|
101
|
+
state = await fetch_bonding_curve_state(
|
|
102
|
+
rpc_url="https://api.mainnet-beta.solana.com",
|
|
103
|
+
token_mint="YourTokenMintAddress",
|
|
104
|
+
)
|
|
105
|
+
print(f"Reserves: {state.virtual_sol_reserves} SOL, {state.virtual_token_reserves} tokens")
|
|
106
|
+
print(f"Complete (graduated): {state.complete}")
|
|
107
|
+
print(f"Creator: {state.creator}")
|
|
108
|
+
|
|
109
|
+
asyncio.run(main())
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 🔨 Build a buy instruction
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from solders.pubkey import Pubkey
|
|
116
|
+
from pumpfun import build_buy_instruction, get_bonding_curve_pda
|
|
117
|
+
|
|
118
|
+
user = Pubkey.from_string("YourWalletAddress")
|
|
119
|
+
token_mint = Pubkey.from_string("TokenMintAddress")
|
|
120
|
+
bonding_curve = get_bonding_curve_pda(token_mint)
|
|
121
|
+
|
|
122
|
+
ix = build_buy_instruction(
|
|
123
|
+
user=user,
|
|
124
|
+
token_mint=token_mint,
|
|
125
|
+
bonding_curve=bonding_curve,
|
|
126
|
+
sol_amount_lamports=100_000_000, # 0.1 SOL max
|
|
127
|
+
min_tokens_out=950_000, # slippage protection
|
|
128
|
+
creator=Pubkey.from_string("CreatorAddress"),
|
|
129
|
+
fee_recipient=Pubkey.from_string("62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV"),
|
|
130
|
+
)
|
|
131
|
+
# Add `ix` to your transaction
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 🏊 PumpSwap AMM swap
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from pumpfun import calculate_swap_output, build_swap_instruction, fetch_pool_state
|
|
138
|
+
|
|
139
|
+
# Read pool state
|
|
140
|
+
pool = await fetch_pool_state(rpc_url, "PoolAddress")
|
|
141
|
+
|
|
142
|
+
# Calculate output
|
|
143
|
+
amount_out, fee = calculate_swap_output(
|
|
144
|
+
amount_in=100_000_000, # 0.1 SOL
|
|
145
|
+
reserve_in=5_000_000_000,
|
|
146
|
+
reserve_out=1_000_000_000_000,
|
|
147
|
+
lp_fee_bps=pool.lp_fee_basis_points,
|
|
148
|
+
protocol_fee_bps=pool.protocol_fee_basis_points,
|
|
149
|
+
)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## API Reference
|
|
155
|
+
|
|
156
|
+
### Bonding Curve (pre-graduation)
|
|
157
|
+
|
|
158
|
+
| Function | Description |
|
|
159
|
+
|---|---|
|
|
160
|
+
| `calculate_buy_amount()` | Tokens received for SOL input (1% fee) |
|
|
161
|
+
| `calculate_sell_amount()` | SOL received for token input (1% fee) |
|
|
162
|
+
| `build_buy_instruction()` | Build PumpFun v2 BUY ix (16 accounts) |
|
|
163
|
+
| `build_sell_instruction()` | Build PumpFun v2 SELL ix (14 accounts) |
|
|
164
|
+
| `fetch_bonding_curve_state()` | Read reserves, creator, completion from chain |
|
|
165
|
+
| `fetch_fee_recipient()` | Read fee recipient from Global account |
|
|
166
|
+
|
|
167
|
+
### PumpSwap AMM (post-graduation)
|
|
168
|
+
|
|
169
|
+
| Function | Description |
|
|
170
|
+
|---|---|
|
|
171
|
+
| `calculate_swap_output()` | Output amount for constant-product swap |
|
|
172
|
+
| `build_swap_instruction()` | Build PumpSwap swap ix (13 accounts) |
|
|
173
|
+
| `fetch_pool_state()` | Read pool vaults, mints, fees from chain |
|
|
174
|
+
|
|
175
|
+
### PDA Helpers
|
|
176
|
+
|
|
177
|
+
| Function | Description |
|
|
178
|
+
|---|---|
|
|
179
|
+
| `get_bonding_curve_pda()` | Derive bonding curve PDA for a mint |
|
|
180
|
+
| `get_associated_token_address()` | Derive ATA (SPL Token or Token-2022) |
|
|
181
|
+
|
|
182
|
+
### Constants
|
|
183
|
+
|
|
184
|
+
All program IDs are exported: `PUMP_FUN_PROGRAM`, `PUMP_SWAP_PROGRAM`, `PUMP_AMM_PROGRAM`, plus system programs, discriminators, and fee accounts.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Account Layout Notes
|
|
189
|
+
|
|
190
|
+
**BUY instruction** uses 16 accounts + 1 remaining account (bonding-curve-v2 PDA).
|
|
191
|
+
|
|
192
|
+
**SELL instruction** uses 14 accounts + 1 remaining — but **creator_vault [8] and token_program [9] are SWAPPED** relative to buy. This is an undocumented PumpFun quirk that causes failed transactions if you copy the buy layout.
|
|
193
|
+
|
|
194
|
+
**Pump AMM pools** (pAMMBay program) can have **reversed base/quote** — base_mint=SOL, quote_mint=TOKEN. The `PoolState.base_is_sol` flag indicates this.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Also by JinUltimate1995
|
|
199
|
+
|
|
200
|
+
- **[jupiter-swap-python](https://github.com/JinUltimate1995/jupiter-swap-python)** — Jupiter swap client for Python. Async. Typed.
|
|
201
|
+
- **[solana-rpc-resilient](https://github.com/JinUltimate1995/solana-rpc-resilient)** — Fault-tolerant Solana RPC with automatic failover.
|
|
202
|
+
- **[dexscreener-python](https://github.com/JinUltimate1995/dexscreener-python)** — DexScreener API client for Python.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## License
|
|
207
|
+
|
|
208
|
+
MIT
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# pumpfun-python
|
|
2
|
+
|
|
3
|
+
**Buy and sell on PumpFun bonding curves + PumpSwap AMM. Directly from Python. No Jupiter needed.**
|
|
4
|
+
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://peps.python.org/pep-0561/)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Why?
|
|
12
|
+
|
|
13
|
+
PumpFun tokens start on a **bonding curve** and graduate to a **PumpSwap AMM pool**. Jupiter doesn't always route through these — and when it does, you're at the mercy of their routing engine. This library builds the raw Solana instructions so you can swap directly.
|
|
14
|
+
|
|
15
|
+
- **Pre-graduation** — buy/sell against the PumpFun bonding curve (v2, 16/14 accounts)
|
|
16
|
+
- **Post-graduation** — swap on PumpSwap AMM pools (constant-product, 13 accounts)
|
|
17
|
+
- **Zero dependencies beyond solders + httpx** — no SDK bloat
|
|
18
|
+
- **Production-tested** — extracted from a live trading system
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install pumpfun-python
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or from source:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install git+https://github.com/JinUltimate1995/pumpfun-python.git
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
### 💰 Calculate buy/sell amounts (no RPC needed)
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from pumpfun import calculate_buy_amount, calculate_sell_amount
|
|
42
|
+
|
|
43
|
+
# How many tokens for 0.1 SOL?
|
|
44
|
+
tokens = calculate_buy_amount(
|
|
45
|
+
sol_amount_lamports=100_000_000, # 0.1 SOL
|
|
46
|
+
virtual_sol_reserves=30_000_000_000,
|
|
47
|
+
virtual_token_reserves=1_000_000_000_000,
|
|
48
|
+
)
|
|
49
|
+
print(f"Tokens received: {tokens:,}")
|
|
50
|
+
|
|
51
|
+
# How much SOL for selling 1M tokens?
|
|
52
|
+
sol_out = calculate_sell_amount(
|
|
53
|
+
token_amount=1_000_000,
|
|
54
|
+
virtual_sol_reserves=30_000_000_000,
|
|
55
|
+
virtual_token_reserves=1_000_000_000_000,
|
|
56
|
+
)
|
|
57
|
+
print(f"SOL received: {sol_out / 1e9:.6f}")
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 📈 Read bonding curve state
|
|
61
|
+
|
|
62
|
+
> **RPC calls require your own Solana RPC endpoint.** Get a free key from [Helius](https://helius.dev), [QuickNode](https://quicknode.com), or use the public endpoint (rate-limited).
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
import asyncio
|
|
66
|
+
from pumpfun import fetch_bonding_curve_state
|
|
67
|
+
|
|
68
|
+
async def main():
|
|
69
|
+
state = await fetch_bonding_curve_state(
|
|
70
|
+
rpc_url="https://api.mainnet-beta.solana.com",
|
|
71
|
+
token_mint="YourTokenMintAddress",
|
|
72
|
+
)
|
|
73
|
+
print(f"Reserves: {state.virtual_sol_reserves} SOL, {state.virtual_token_reserves} tokens")
|
|
74
|
+
print(f"Complete (graduated): {state.complete}")
|
|
75
|
+
print(f"Creator: {state.creator}")
|
|
76
|
+
|
|
77
|
+
asyncio.run(main())
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 🔨 Build a buy instruction
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from solders.pubkey import Pubkey
|
|
84
|
+
from pumpfun import build_buy_instruction, get_bonding_curve_pda
|
|
85
|
+
|
|
86
|
+
user = Pubkey.from_string("YourWalletAddress")
|
|
87
|
+
token_mint = Pubkey.from_string("TokenMintAddress")
|
|
88
|
+
bonding_curve = get_bonding_curve_pda(token_mint)
|
|
89
|
+
|
|
90
|
+
ix = build_buy_instruction(
|
|
91
|
+
user=user,
|
|
92
|
+
token_mint=token_mint,
|
|
93
|
+
bonding_curve=bonding_curve,
|
|
94
|
+
sol_amount_lamports=100_000_000, # 0.1 SOL max
|
|
95
|
+
min_tokens_out=950_000, # slippage protection
|
|
96
|
+
creator=Pubkey.from_string("CreatorAddress"),
|
|
97
|
+
fee_recipient=Pubkey.from_string("62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV"),
|
|
98
|
+
)
|
|
99
|
+
# Add `ix` to your transaction
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 🏊 PumpSwap AMM swap
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from pumpfun import calculate_swap_output, build_swap_instruction, fetch_pool_state
|
|
106
|
+
|
|
107
|
+
# Read pool state
|
|
108
|
+
pool = await fetch_pool_state(rpc_url, "PoolAddress")
|
|
109
|
+
|
|
110
|
+
# Calculate output
|
|
111
|
+
amount_out, fee = calculate_swap_output(
|
|
112
|
+
amount_in=100_000_000, # 0.1 SOL
|
|
113
|
+
reserve_in=5_000_000_000,
|
|
114
|
+
reserve_out=1_000_000_000_000,
|
|
115
|
+
lp_fee_bps=pool.lp_fee_basis_points,
|
|
116
|
+
protocol_fee_bps=pool.protocol_fee_basis_points,
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## API Reference
|
|
123
|
+
|
|
124
|
+
### Bonding Curve (pre-graduation)
|
|
125
|
+
|
|
126
|
+
| Function | Description |
|
|
127
|
+
|---|---|
|
|
128
|
+
| `calculate_buy_amount()` | Tokens received for SOL input (1% fee) |
|
|
129
|
+
| `calculate_sell_amount()` | SOL received for token input (1% fee) |
|
|
130
|
+
| `build_buy_instruction()` | Build PumpFun v2 BUY ix (16 accounts) |
|
|
131
|
+
| `build_sell_instruction()` | Build PumpFun v2 SELL ix (14 accounts) |
|
|
132
|
+
| `fetch_bonding_curve_state()` | Read reserves, creator, completion from chain |
|
|
133
|
+
| `fetch_fee_recipient()` | Read fee recipient from Global account |
|
|
134
|
+
|
|
135
|
+
### PumpSwap AMM (post-graduation)
|
|
136
|
+
|
|
137
|
+
| Function | Description |
|
|
138
|
+
|---|---|
|
|
139
|
+
| `calculate_swap_output()` | Output amount for constant-product swap |
|
|
140
|
+
| `build_swap_instruction()` | Build PumpSwap swap ix (13 accounts) |
|
|
141
|
+
| `fetch_pool_state()` | Read pool vaults, mints, fees from chain |
|
|
142
|
+
|
|
143
|
+
### PDA Helpers
|
|
144
|
+
|
|
145
|
+
| Function | Description |
|
|
146
|
+
|---|---|
|
|
147
|
+
| `get_bonding_curve_pda()` | Derive bonding curve PDA for a mint |
|
|
148
|
+
| `get_associated_token_address()` | Derive ATA (SPL Token or Token-2022) |
|
|
149
|
+
|
|
150
|
+
### Constants
|
|
151
|
+
|
|
152
|
+
All program IDs are exported: `PUMP_FUN_PROGRAM`, `PUMP_SWAP_PROGRAM`, `PUMP_AMM_PROGRAM`, plus system programs, discriminators, and fee accounts.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Account Layout Notes
|
|
157
|
+
|
|
158
|
+
**BUY instruction** uses 16 accounts + 1 remaining account (bonding-curve-v2 PDA).
|
|
159
|
+
|
|
160
|
+
**SELL instruction** uses 14 accounts + 1 remaining — but **creator_vault [8] and token_program [9] are SWAPPED** relative to buy. This is an undocumented PumpFun quirk that causes failed transactions if you copy the buy layout.
|
|
161
|
+
|
|
162
|
+
**Pump AMM pools** (pAMMBay program) can have **reversed base/quote** — base_mint=SOL, quote_mint=TOKEN. The `PoolState.base_is_sol` flag indicates this.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Also by JinUltimate1995
|
|
167
|
+
|
|
168
|
+
- **[jupiter-swap-python](https://github.com/JinUltimate1995/jupiter-swap-python)** — Jupiter swap client for Python. Async. Typed.
|
|
169
|
+
- **[solana-rpc-resilient](https://github.com/JinUltimate1995/solana-rpc-resilient)** — Fault-tolerant Solana RPC with automatic failover.
|
|
170
|
+
- **[dexscreener-python](https://github.com/JinUltimate1995/dexscreener-python)** — DexScreener API client for Python.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## License
|
|
175
|
+
|
|
176
|
+
MIT
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
pumpfun-python — buy and sell on PumpFun bonding curves + PumpSwap AMM.
|
|
3
|
+
Directly from Python. No Jupiter needed.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .bonding_curve import (
|
|
7
|
+
BondingCurveState,
|
|
8
|
+
build_buy_instruction,
|
|
9
|
+
build_sell_instruction,
|
|
10
|
+
calculate_buy_amount,
|
|
11
|
+
calculate_sell_amount,
|
|
12
|
+
fetch_bonding_curve_state,
|
|
13
|
+
)
|
|
14
|
+
from .constants import (
|
|
15
|
+
PUMP_AMM_PROGRAM,
|
|
16
|
+
PUMP_FUN_PROGRAM,
|
|
17
|
+
PUMP_SWAP_PROGRAM,
|
|
18
|
+
)
|
|
19
|
+
from .pda import (
|
|
20
|
+
get_associated_token_address,
|
|
21
|
+
get_bonding_curve_pda,
|
|
22
|
+
)
|
|
23
|
+
from .pumpswap import (
|
|
24
|
+
PoolState,
|
|
25
|
+
build_swap_instruction,
|
|
26
|
+
calculate_swap_output,
|
|
27
|
+
fetch_pool_state,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
__version__ = "0.1.0"
|
|
31
|
+
|
|
32
|
+
__all__ = [
|
|
33
|
+
# Bonding curve (pre-graduation)
|
|
34
|
+
"BondingCurveState",
|
|
35
|
+
"build_buy_instruction",
|
|
36
|
+
"build_sell_instruction",
|
|
37
|
+
"calculate_buy_amount",
|
|
38
|
+
"calculate_sell_amount",
|
|
39
|
+
"fetch_bonding_curve_state",
|
|
40
|
+
# PumpSwap AMM (post-graduation)
|
|
41
|
+
"PoolState",
|
|
42
|
+
"build_swap_instruction",
|
|
43
|
+
"calculate_swap_output",
|
|
44
|
+
"fetch_pool_state",
|
|
45
|
+
# PDA helpers
|
|
46
|
+
"get_associated_token_address",
|
|
47
|
+
"get_bonding_curve_pda",
|
|
48
|
+
# Program IDs
|
|
49
|
+
"PUMP_FUN_PROGRAM",
|
|
50
|
+
"PUMP_SWAP_PROGRAM",
|
|
51
|
+
"PUMP_AMM_PROGRAM",
|
|
52
|
+
"__version__",
|
|
53
|
+
]
|