Files
pump-game-ops/tools

Инструменты проверки игрового контура

Скрипты для живой приёмки механик ставок (не заменяют npm test в репозитории релейера, а проверяют боевой стенд).

exploit-decisive.cjs — решающая проверка окна закрытия

Проверяет главное: цена закрытия берётся из истории на момент экспирации, а не в момент клика.

Как запускать (внутри пода шлюза — там есть node_modules и доступ к RPC):

P=$(kubectl -n game get pod -l app.kubernetes.io/instance=testfront-gateway -o jsonpath='{.items[0].metadata.name}')
kubectl -n game cp tools/exploit-decisive.cjs "$P:/app/data/probe/exploit-decisive.cjs" -c gateway
kubectl -n game exec "$P" -c gateway -- sh -c "cd /app && node /app/data/probe/exploit-decisive.cjs 300"

Питфоллы (каждый пойман вживую)

  • Нельзя просто сравнивать exitPrice с текущей ценой. Цена часто стоит на месте, и сравнение вырождается в «совпало» — ложный успех. Скрипт ждёт, пока цена на экспирации и текущая разойдутся, и только тогда закрывает. Первый прогон без этого дал ложное «совпало» дважды.
  • Копировать только в /app/data/, не в /app (Permission denied, под не root).
  • Запускать с cd /app, иначе Cannot find module '@solana/web3.js' (из /tmp//app/data без cwd node_modules не виден).
  • Ставка при exit == entry остаётся open — это ожидаемо (равные цены, отдельная задача), а не сбой проверки.

Читает bet_time / expire_time прямо из аккаунта Bet (сырые байты) — off-chain данными не верим. Раскладка аккаунта (Anchor, после 8-байтового дискриминатора): amount u64 @8, bet_time i64 @16, expire_time i64 @24, entry_price u64 @32, exit_price u64 @40, side u64 @48, status u64 @56, bettor Pubkey @64.

price-history-probe.cjs — разбор истории цены

Смотрит, что реально накопилось в binance-market (Postgres 192.168.76.182:5434, БД binance_market) вокруг конкретной ставки: сделки в окне, цена на входе, цена на экспирации, и что было бы при «ждать выгодной цены».

node tools/price-history-probe.cjs <programId> <betId>

⚠️ Символ в БД — в нижнем регистре (solusdt, не SOLUSDT). Запрос с верхним регистром вернёт пусто, и это легко принять за «данных нет».