diff --git a/scripts/mainnet-test.sh b/scripts/mainnet-test.sh index 921b04c..55022f3 100755 --- a/scripts/mainnet-test.sh +++ b/scripts/mainnet-test.sh @@ -221,10 +221,17 @@ else: GRADUATED_MINT=$(echo "$TRENDING" | python3 -c " import json, sys tokens = json.load(sys.stdin) +# Prefer graduated tokens with higher SOL reserves — pools with extreme +# base/quote ratios can trigger on-chain overflow at buy.rs:400. +best = None for t in tokens: if t.get('complete') and t.get('pump_swap_pool'): - print(t['mint']) - break + if best is None: + best = t + elif t.get('market_cap', 0) > best.get('market_cap', 0): + best = t +if best: + print(best['mint']) else: print('') " 2>/dev/null) @@ -259,14 +266,14 @@ if [[ "$SKIP_TRADING" == true ]]; then else echo "=== Group 5: Bonding Curve Trading ===" if [[ -n "$ACTIVE_MINT" ]]; then - BUY_OUT=$(uv run pumpfun buy "$ACTIVE_MINT" 0.001 --confirm 2>&1) + BUY_OUT=$(uv run pumpfun buy "$ACTIVE_MINT" 0.001 --slippage 50 --confirm 2>&1) BUY_EXIT=$? if [[ $BUY_EXIT -eq 0 ]]; then record "BC Trade" "buy 0.001 --confirm" "PASS" echo " Buy OK. Waiting 5s for RPC state..." sleep 5 - SELL_OUT=$(uv run pumpfun sell "$ACTIVE_MINT" all --confirm 2>&1) + SELL_OUT=$(uv run pumpfun sell "$ACTIVE_MINT" all --slippage 50 --confirm 2>&1) SELL_EXIT=$? if [[ $SELL_EXIT -eq 0 ]]; then record "BC Trade" "sell all --confirm" "PASS" @@ -274,7 +281,7 @@ else # Retry once after delay echo " Sell failed, retrying in 5s..." sleep 5 - SELL_OUT=$(uv run pumpfun sell "$ACTIVE_MINT" all --confirm 2>&1) + SELL_OUT=$(uv run pumpfun sell "$ACTIVE_MINT" all --slippage 50 --confirm 2>&1) SELL_EXIT=$? if [[ $SELL_EXIT -eq 0 ]]; then record "BC Trade" "sell all --confirm" "PASS" "Needed retry (RPC lag)" @@ -297,20 +304,133 @@ else echo "=== Group 6: PumpSwap AMM Trading ===" if [[ -n "$GRADUATED_MINT" ]]; then - AMM_OUT=$(uv run pumpfun buy "$GRADUATED_MINT" 0.001 --force-amm --confirm 2>&1) - AMM_EXIT=$? - if [[ $AMM_EXIT -eq 0 ]]; then - record "PumpSwap" "buy --force-amm --confirm" "PASS" "BUG-1 may be fixed!" - elif echo "$AMM_OUT" | grep -q "6023"; then - record "PumpSwap" "buy --force-amm --confirm" "ISSUE" "Error 6023 — known BUG-1" - else - record "PumpSwap" "buy --force-amm --confirm" "FAIL" "$(echo "$AMM_OUT" | head -1 | cut -c1-60)" + # Build a list of graduated mints to try (some pools have on-chain overflow bugs) + ALL_GRADUATED=$(echo "$TRENDING" | python3 -c " +import json, sys +tokens = json.load(sys.stdin) +for t in tokens: + if t.get('complete') and t.get('pump_swap_pool'): + print(t['mint']) +" 2>/dev/null) + + AMM_BUY_OK=false + AMM_MINT="" + AMM_OVERFLOW_ONLY=true + while IFS= read -r CANDIDATE; do + [[ -z "$CANDIDATE" ]] && continue + AMM_OUT=$(uv run pumpfun buy "$CANDIDATE" 0.001 --slippage 50 --force-amm --confirm 2>&1) + AMM_EXIT=$? + if [[ $AMM_EXIT -eq 0 ]]; then + AMM_BUY_OK=true + AMM_MINT="$CANDIDATE" + break + elif echo "$AMM_OUT" | grep -q "6023"; then + echo " Pool overflow (6023) on ${CANDIDATE:0:12}…, trying next" + continue + else + # Non-overflow failure — record and stop + AMM_OVERFLOW_ONLY=false + record "PumpSwap" "buy --force-amm --confirm" "FAIL" "$(echo "$AMM_OUT" | head -1 | cut -c1-60)" + break + fi + done <<< "$ALL_GRADUATED" + + if [[ "$AMM_BUY_OK" == "true" ]]; then + record "PumpSwap" "buy --force-amm --confirm" "PASS" + echo " PumpSwap buy OK. Waiting 5s for RPC state..." + sleep 5 + + AMM_SELL_OUT=$(uv run pumpfun sell "$AMM_MINT" all --slippage 50 --confirm 2>&1) + AMM_SELL_EXIT=$? + if [[ $AMM_SELL_EXIT -eq 0 ]]; then + record "PumpSwap" "sell all --confirm" "PASS" + else + echo " PumpSwap sell failed, retrying in 5s..." + sleep 5 + AMM_SELL_OUT=$(uv run pumpfun sell "$AMM_MINT" all --slippage 50 --confirm 2>&1) + AMM_SELL_EXIT=$? + if [[ $AMM_SELL_EXIT -eq 0 ]]; then + record "PumpSwap" "sell all --confirm" "PASS" "Needed retry (RPC lag)" + else + record "PumpSwap" "sell all --confirm" "FAIL" "Failed after retry" + fi + fi + elif [[ "$AMM_OVERFLOW_ONLY" == "true" ]]; then + record "PumpSwap" "buy --force-amm --confirm" "ISSUE" "All graduated pools hit error 6023" fi else record "PumpSwap" "buy --force-amm" "ISSUE" "No graduated mint found" fi echo " Done." + # --- Group 6b: Token Launch --- + + echo "=== Group 6b: Token Launch ===" + # Generate a minimal test image + python3 -c "from PIL import Image; Image.new('RGB',(100,100),'blue').save('/tmp/e2e_test_token.png')" 2>/dev/null + LAUNCH_IMG="" + [[ -f /tmp/e2e_test_token.png ]] && LAUNCH_IMG="--image /tmp/e2e_test_token.png" + + LAUNCH_OUT=$(uv run pumpfun --json launch --name "E2E Test $(date +%s)" --ticker "E2ET" --desc "Automated e2e test token" $LAUNCH_IMG 2>&1) + LAUNCH_EXIT=$? + echo "$LAUNCH_OUT" > "$LAST_OUTPUT_FILE" + if [[ $LAUNCH_EXIT -eq 0 ]]; then + LAUNCHED_MINT=$(echo "$LAUNCH_OUT" | python3 -c "import json,sys; print(json.load(sys.stdin).get('mint',''))" 2>/dev/null) + if [[ -n "$LAUNCHED_MINT" ]]; then + record "Launch" "launch" "PASS" + echo " Launched: $LAUNCHED_MINT" + else + record "Launch" "launch" "FAIL" "Invalid --json payload (missing mint)" + LAUNCHED_MINT="" + fi + else + LAUNCH_ERR=$(echo "$LAUNCH_OUT" | grep -m1 "Error:" | cut -c1-60) + [[ -z "$LAUNCH_ERR" ]] && LAUNCH_ERR="exit=$LAUNCH_EXIT" + record "Launch" "launch" "FAIL" "$LAUNCH_ERR" + LAUNCHED_MINT="" + fi + + # Launch + buy + LAUNCH_BUY_OUT=$(uv run pumpfun --json launch --name "E2E Buy Test $(date +%s)" --ticker "E2EB" --desc "Automated e2e launch+buy" $LAUNCH_IMG --buy 0.001 2>&1) + LAUNCH_BUY_EXIT=$? + echo "$LAUNCH_BUY_OUT" > "$LAST_OUTPUT_FILE" + if [[ $LAUNCH_BUY_EXIT -eq 0 ]]; then + LAUNCHED_BUY_MINT=$(echo "$LAUNCH_BUY_OUT" | python3 -c "import json,sys; print(json.load(sys.stdin).get('mint',''))" 2>/dev/null) + if [[ -n "$LAUNCHED_BUY_MINT" ]]; then + record "Launch" "launch --buy 0.001" "PASS" + echo " Launched+bought: $LAUNCHED_BUY_MINT" + else + record "Launch" "launch --buy 0.001" "FAIL" "Invalid --json payload (missing mint)" + LAUNCHED_BUY_MINT="" + fi + + # Sell from the launched token to test full cycle + if [[ -n "$LAUNCHED_BUY_MINT" ]]; then + echo " Waiting 5s for RPC state..." + sleep 5 + LSELL_OUT=$(uv run pumpfun sell "$LAUNCHED_BUY_MINT" all --slippage 50 --confirm 2>&1) + LSELL_EXIT=$? + if [[ $LSELL_EXIT -eq 0 ]]; then + record "Launch" "sell launched token" "PASS" + else + sleep 5 + LSELL_OUT=$(uv run pumpfun sell "$LAUNCHED_BUY_MINT" all --slippage 50 --confirm 2>&1) + LSELL_EXIT=$? + if [[ $LSELL_EXIT -eq 0 ]]; then + record "Launch" "sell launched token" "PASS" "Needed retry" + else + record "Launch" "sell launched token" "FAIL" "Failed after retry" + fi + fi + fi + else + LAUNCH_BUY_ERR=$(echo "$LAUNCH_BUY_OUT" | grep -m1 "Error:" | cut -c1-60) + [[ -z "$LAUNCH_BUY_ERR" ]] && LAUNCH_BUY_ERR="exit=$LAUNCH_BUY_EXIT" + record "Launch" "launch --buy 0.001" "FAIL" "$LAUNCH_BUY_ERR" + fi + rm -f /tmp/e2e_test_token.png + echo " Done." + # --- Group 7: Extras --- echo "=== Group 7: Extras ===" diff --git a/src/pumpfun_cli/protocol/instructions.py b/src/pumpfun_cli/protocol/instructions.py index 35b0606..597e720 100644 --- a/src/pumpfun_cli/protocol/instructions.py +++ b/src/pumpfun_cli/protocol/instructions.py @@ -39,8 +39,9 @@ ) from pumpfun_cli.protocol.idl_parser import IDLParser -# Trailing bytes appended after the two u64 args (track_volume flag). -_TRACK_VOLUME = bytes([1, 1]) +# OptionBool(true) = 1 byte: the IDL defines OptionBool as struct { bool }, +# so it serialises to a single 0x01 byte, NOT 2 bytes (Option). +_TRACK_VOLUME = bytes([1]) def build_buy_instructions( @@ -103,10 +104,7 @@ def build_buy_instructions( discriminators = idl.get_instruction_discriminators() instruction_data = ( - discriminators["buy"] - + struct.pack("