Repository navigation
Expand file tree
/
Copy pathmain.py
More file actions
229 lines (182 loc) Β· 7.85 KB
/
Copy pathmain.py
File metadata and controls
229 lines (182 loc) Β· 7.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#!/usr/bin/env python3
"""
Pump.fun Trading Bot - Unified Trading Interface
"""
import asyncio
import logging
import sys
from config import Config
from src.pump_fun.unified_pump_fun import UnifiedPumpFun # type: ignore
from src.providers.solana_provider import SolanaProvider
logging.getLogger("httpx").setLevel(logging.WARNING)
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(sys.stdout)
]
)
logger = logging.getLogger(__name__)
BUFFER_FEES_SOL = 0.01
FEE_SOL = 0.0005
DEFAULT_SLIPPAGE = 25
LOSS_PERCENTAGE = 0.1
PERCENTAGE_SELL = 100
MIN_SOL_BALANCE = 0.02
class SimplePumpTester:
"""Simplified pump trading tester using unified interface"""
def __init__(self):
try:
self.config = Config()
self.solana_provider = SolanaProvider.get_instance()
self.trader = UnifiedPumpFun(self.solana_provider)
self.payer_pubkey = self.solana_provider.payer.pubkey()
print(f"Wallet: {self.payer_pubkey}")
except Exception as e:
logger.error(f"Failed to initialize: {e}")
raise
async def check_wallet_balance(self) -> float:
"""Check SOL balance"""
try:
balance_response = self.solana_provider.rpc.get_balance(self.payer_pubkey)
balance = balance_response.value
sol_balance = balance / 1e9
return sol_balance
except Exception as e:
logger.error(f"Failed to check wallet balance: {e}")
return 0.0
async def get_token_info(self, mint_str: str):
"""Get and display token information"""
print(f"\nπ Getting token info for: {mint_str}")
info = await self.trader.get_token_info(mint_str)
if not info["valid"]:
print(f"β Error: {info.get('error', 'Unknown error')}")
return False
print(f" Name: {info.get('name', 'Unknown')}")
print(f" Symbol: {info.get('symbol', 'Unknown')}")
print(f" Trading venue: {'Bonding Curve (pump.fun)' if info['is_on_bonding_curve'] else 'PumpSwap DEX'}")
if info['is_on_bonding_curve']:
print(f" SOL reserves: {info.get('virtual_sol_reserves', 0) / 1e9:.4f}")
print(f" Token reserves: {info.get('virtual_token_reserves', 0) / 1e6:.0f}")
else:
if info.get('pool_available'):
print(f" Pool address: {info['pool_address']}")
print(f" Pool type: {info['pool_type']}")
print(f" SOL liquidity: {info.get('liquidity_sol', 0):.4f}")
else:
print(" β οΈ No pool found - token may not be tradeable")
return True
async def test_buy_sell_cycle(self, mint_str: str, test_sol_amount: float = 0.01):
"""Test complete buy/sell cycle with unified interface"""
print(f"\nπ Starting buy/sell test for {mint_str}")
print(f"Test amount: {test_sol_amount} SOL")
# Check initial balance
initial_sol_balance = await self.check_wallet_balance()
print(f"Initial SOL balance: {initial_sol_balance:.4f}")
if initial_sol_balance < test_sol_amount + BUFFER_FEES_SOL:
print(f"β Insufficient SOL. Need {test_sol_amount + BUFFER_FEES_SOL:.4f}, have {initial_sol_balance:.4f}")
return False
# Get token info
if not await self.get_token_info(mint_str):
return False
# Execute buy
print(f"\nπ° Executing BUY: {test_sol_amount} SOL")
buy_success = await self.trader.buy(
mint_str=mint_str,
sol_amount=test_sol_amount,
slippage=DEFAULT_SLIPPAGE, # Higher slippage for volatile tokens
fee_sol=FEE_SOL # This will be ignored for bonding curve
)
if not buy_success:
print("β Buy failed - trying with higher slippage")
buy_success = await self.trader.buy(
mint_str=mint_str,
sol_amount=test_sol_amount,
slippage=DEFAULT_SLIPPAGE,
fee_sol=FEE_SOL
)
if not buy_success:
print("β Buy failed even with 50% slippage")
return False
print("β
Buy successful!")
print("β³ Waiting 5 seconds before sell...")
await asyncio.sleep(5)
# Execute sell
print(f"\nπΈ Executing SELL: 100%")
sell_success = await self.trader.sell(
mint_str=mint_str,
percentage=PERCENTAGE_SELL,
slippage=DEFAULT_SLIPPAGE,
fee_sol=FEE_SOL
)
if not sell_success:
print("β Sell failed")
return False
print("β
Sell successful!")
# Check final balance
await asyncio.sleep(3)
final_sol_balance = await self.check_wallet_balance()
net_change = final_sol_balance - initial_sol_balance
print(f"\nπ Results:")
print(f" Initial SOL: {initial_sol_balance:.6f}")
print(f" Final SOL: {final_sol_balance:.6f}")
print(f" Net change: {net_change:+.6f} SOL")
if net_change > -test_sol_amount * LOSS_PERCENTAGE: # Lost less than 10% due to fees/slippage
print("β
Test completed successfully!")
else:
print("β οΈ High losses - check slippage settings")
return True
async def run_multiple_tests(self, mints: list, test_amount: float = 0.002):
"""Run tests on multiple tokens"""
print(f"\nπ Running tests on {len(mints)} tokens")
results = []
for i, mint in enumerate(mints, 1):
print(f"\n{'='*60}")
print(f"Test {i}/{len(mints)}: {mint}")
print(f"{'='*60}")
try:
success = await self.test_buy_sell_cycle(mint, test_amount)
results.append((mint, success))
if i < len(mints): # Don't wait after last test
print("\nβ³ Waiting 10 seconds before next test...")
await asyncio.sleep(10)
except Exception as e:
logger.error(f"Test failed for {mint}: {e}")
results.append((mint, False))
# Summary
print(f"\n{'='*60}")
print("π TEST SUMMARY")
print(f"{'='*60}")
successful = sum(1 for _, success in results if success)
print(f"Total tests: {len(results)}")
print(f"Successful: {successful}")
print(f"Failed: {len(results) - successful}")
for mint, success in results:
status = "β
" if success else "β"
print(f" {status} {mint}")
async def close(self):
"""Clean up resources"""
await self.trader.close()
async def main():
print("π Unified Pump.fun Trading Tester")
print("This tool automatically detects token state and uses appropriate trading method")
tester = None
try:
tester = SimplePumpTester()
sol_balance = await tester.check_wallet_balance()
print(f"SOL balance: {sol_balance:.4f}")
if sol_balance < MIN_SOL_BALANCE:
print(f"β Need at least {MIN_SOL_BALANCE:.4f} SOL for testing")
return
# Test tokens (mix of bonding curve and graduated tokens)
test_tokens = [
"GNWQriPD8w1xuvcP8iemExjZCwXonRw6s9KD34s2pump"
]
await tester.run_multiple_tests(test_tokens)
finally:
if tester:
await tester.close()
print("\nπ Resources cleaned up")
if __name__ == "__main__":
asyncio.run(main())