Skip to content
fphxgalleryPublic

About

A full-featured Solana trading terminal powered by Jupiter

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

⚡ SupaSOL

A full-featured Solana trading terminal powered by Jupiter, Meteora, and Flash Trade. Swap tokens, earn yield, trade perpetual futures, place limit orders, run DCA strategies, provide liquidity, browse trending tokens, and send tokens via invite codes — all from a single self-hosted app.

SupaSOL Dashboard Jupiter Meteora Flash Trade Release License


Features

Feature Description
Swap Best-route token swaps via Jupiter Ultra v2 (DEX + RFQ) with wallet token selector
Trending Jupiter organic score leaderboard — bot-filtered token rankings with 5m/1h/6h/24h intervals, price, change, volume, and one-click buy
Lend / Earn Deposit & withdraw into Jupiter lending products — markets and positions unified in one view, deposited amount shown per market card
Perps Long/short perpetual futures on crypto and equities via Flash Trade — live preview, SL/TP orders, and collateral management
Limit Orders Place and cancel trigger-based limit orders
DCA Set up recurring dollar-cost-averaging purchases
Liquidity Provide liquidity to Meteora DLMM pools — Spot, Curve, and Bid-Ask strategies
Portfolio Token balances + Jupiter DeFi positions across all platforms
Send Send tokens via claimable invite codes (clawback supported)
History App transactions + live on-chain signature history via Solana RPC
Price Charts Live OHLCV charts (1H / 4H / 1D / 1W / 1M) via Pyth Network
Token Search Global search bar — find any Solana token, click to swap
Auto Trader Automated meme coin sniper — configurable entry/exit rules, trailing stop, take profit, max hold time, rebuy cooldown, organic score filter, candidate sorting by score, and live P&L chart
Logs Unified troubleshooting view — backend stdout/stderr, frontend console + window errors, outbound network/RPC calls (Jupiter / OpenAI / Solana / Telegram), and AI Decisions tail — with search, level/source filter, per-tab clear, and Copy/Download export
Settings RPC endpoint, cluster, slippage tolerance, priority fee

Tech Stack

Frontend

  • React 18 + Vite + TypeScript
  • Tailwind CSS v4 — dark theme UI
  • Zustand — wallet, settings, and UI state
  • TanStack Query — server state + caching
  • lightweight-charts — TradingView-style price charts
  • @solana/web3.js + @solana/spl-token — on-chain interactions
  • @meteora-ag/dlmm + @coral-xyz/anchor — Meteora DLMM liquidity SDK

Backend

  • Express.js + TypeScript — Jupiter, Meteora & Flash Trade API proxy
  • express-rate-limit — 200 req / 10s global limit
  • CORS — configurable frontend origin whitelist

Project Structure

SupaSOL/
├── frontend/                  # React + Vite SPA
│   ├── src/
│   │   ├── pages/             # 12 route pages
│   │   ├── components/        # UI, charts, layout, liquidity, wallet modals
│   │   ├── hooks/             # Custom React hooks
│   │   ├── api/               # Jupiter, Meteora & Flash Trade client functions
│   │   ├── store/             # Zustand stores
│   │   └── config/            # Constants & token mints
│   ├── Dockerfile             # Multi-stage: Node builder → nginx
│   └── nginx.conf             # SPA routing + asset caching
│
├── backend/                   # Express API proxy
│   ├── src/
│   │   ├── routes/            # Route modules (swap, lend, trigger, dlmm, perps, tokens…)
│   │   └── lib/               # Jupiter client + trigger JWT auth
│   └── Dockerfile             # Multi-stage: Node builder → slim runtime
│
├── docker-compose.yml         # Frontend + backend services
├── install.sh                 # Bare-metal Ubuntu deployment script
└── .env.example               # Environment variable template

Quick Start

Prerequisites

  • Node.js 20+
  • npm 10+
  • A Jupiter API key — get one at portal.jup.ag
  • A Helius API key (recommended) — get one at helius.dev for reliable RPC

1. Clone & install

git clone https://github.com/fphxgallery/SupaSOL.git
cd SupaSOL
npm install

2. Configure environment

cp .env.example .env

Edit .env:

JUPITER_API_KEY=your_key_here
VITE_API_BASE=http://localhost:4000
VITE_RPC_URL=https://mainnet.helius-rpc.com/?api-key=your_helius_key
VITE_CLUSTER=mainnet-beta
FRONTEND_ORIGIN=http://localhost:5173
PORT=4000

3. Run in development

npm run dev

Docker Deployment

Using Docker Compose

cp .env.example .env
# Edit .env with your JUPITER_API_KEY and production URLs

docker compose up --build -d

The frontend container waits for the backend health check before starting.

Build args (frontend)

Arg Default Description
VITE_API_BASE http://localhost:4000 Backend API URL
VITE_RPC_URL https://api.mainnet-beta.solana.com Solana RPC endpoint
VITE_CLUSTER mainnet-beta Solana cluster

Bare-Metal (Ubuntu)

For VPS/dedicated server deployment with systemd + nginx:

chmod +x install.sh
./install.sh

This script will:

  1. Install Node.js 20 and nginx (if not present)
  2. Build the frontend and copy to /var/www/supasol
  3. Configure nginx with SPA routing and /api/ proxy
  4. Create and enable a supasol-backend systemd service

After install:

  • Frontend: http://your-server-ip
  • Backend health: http://your-server-ip/api/health
  • Logs: sudo journalctl -u supasol-backend -f

Environment Variables

Variable Required Default Description
JUPITER_API_KEY ✅ — Jupiter API key from portal.jup.ag
PORT — 4000 Backend server port
NODE_ENV — development development or production
FRONTEND_ORIGIN — http://localhost:5173 CORS allowed origin
VITE_API_BASE ✅ — Backend URL (used at build time)
VITE_RPC_URL — mainnet-beta RPC Solana RPC endpoint (Helius recommended)
VITE_CLUSTER — mainnet-beta Solana cluster name

Wallet

SupaSOL includes a built-in non-custodial wallet:

  • Create — generates a new keypair with a 24-word seed phrase. The backup screen locks until you confirm you've saved the phrase.
  • Import — paste an existing mnemonic or base58 private key

⚠️ Your private key is stored only in your browser's localStorage. Never share your seed phrase. This app does not transmit private keys to any server.


API Routes

All backend routes proxy to Jupiter, Meteora, or Flash Trade with your API key injected server-side.

Path Description
GET /health Health check
GET /api/swap/* Quote + execute token swaps
GET /api/lend/* Lending positions, deposit, withdraw
GET /api/trigger/* Limit orders (create, cancel, list)
GET /api/recurring/* DCA orders
GET /api/tokens/* Token search, metadata, trending rankings
GET /api/price/* Live prices
GET /api/portfolio/* Portfolio positions
POST /api/send/* Craft send / clawback invite
GET /api/dlmm/pairs Meteora DLMM pool list
GET /api/dlmm/pair/:address Meteora pool metadata
GET /api/perps/pool-data Flash Trade markets + custody stats
GET /api/perps/prices Flash Trade mark prices (live)
GET /api/perps/positions/:wallet Open perp positions with PnL
GET /api/perps/orders/:wallet Open SL/TP trigger orders
POST /api/perps/open Build open position transaction
POST /api/perps/close Build close position transaction
POST /api/perps/add-collateral Build add collateral transaction
POST /api/perps/remove-collateral Build remove collateral transaction
POST /api/perps/trigger Build stop loss / take profit transaction
POST /api/perps/cancel-trigger Cancel SL/TP order

Scripts

npm run dev        # Start frontend + backend in watch mode
npm run build      # Build both frontend and backend
npm run start      # Start production build

Changelog

v1.14.2

  • Loss-streak circuit breaker — new "Risk Controls" card on Auto Trader. After N consecutive losses (default 3), entries freeze for a cooldown (default 30m), or earlier if 5m net-buyer breadth ≥ 6h breadth (regime no longer weakening). Open positions still managed normally; only new buys pause. Tunable via lossStreakBreakerEnabled / lossStreakThreshold / lossStreakCooldownMinutes (engine.ts, BotPage.tsx)
  • Per-exit-reason avg pnl — bot performance snapshot now tracks avg pnl per top exit reason, surfacing which exit type is bleeding vs cutting. AI prompt block now reads top exits: trailing stop (n=6, avg -8.2%), AI sell @80% (n=4, avg -3.1%). AI Decisions panel shows the figures with green/red color. Tells you when to retune the trail or AI gate (marketSentiment.ts, AiDecisionsPanel.tsx)

v1.14.1

  • Net-buyer breadth divergence (5m vs 6h) — old 6h net-buyer breadth was structurally pegged near 100% because the sample is pre-filtered to high-organic-score trending tokens (selection bias = leaders are by definition being accumulated). Now also computes 5m breadth over the same cohort and surfaces the delta (5m − 6h). Negative delta = leaders losing short-term flow → exhaustion / rotation tell. Sentiment chip score replaces centered-6h with clipped-divergence term (±30pp). System prompt explicitly tells the AI to read the delta, not the level. Backwards-compatible: 5m field optional; old persisted decision logs render fine (marketSentiment.ts, aiAdvisor.ts, MarketSentimentChip.tsx, AiDecisionsPanel.tsx)
  • Multi-origin CORS — FRONTEND_ORIGIN now accepts a comma-separated list; default covers both http://localhost:5173 (vite dev) and http://localhost:3000 (docker nginx) so dev + docker work without env-flipping (backend/src/config.ts, .env.example)

v1.14.0

  • Dependency hygiene — drop unused @solana/wallet-adapter-* — @solana/wallet-adapter-base/react/react-ui/wallets were declared in frontend/package.json but never imported (app uses its own zustand walletStore + raw Keypair). Removing them eliminates the entire particle / torus / walletconnect / reown transitive chain.
  • Result — 640 packages removed; node_modules 810M → 186M (-77%); npm audit 56 vulns (8 critical, 5 high) → 17 (0 critical, 4 high); frontend build 5.26s → 2.00s; rollup PURE-comment warnings gone. Dead wallet entry also removed from vite.config.ts manualChunks.

v1.13.4

  • Market sentiment — token age floor raised 6h → 48h — macro sample now drawn from tokens established for at least 2 days, further insulating the regime signal from new-launch volatility (marketSentiment.ts)

v1.13.3

  • Market sentiment — 6h token age filter — computeMarketSentiment now also requires createdAt known and ≥ 6h, on top of mcap ≥ $200k and organicScore ≥ 70. Stops brand-new launches from skewing the macro 6h/24h price-change avg and 6h net-buyer breadth. Constraint surfaced in the prompt header line so AI sees the cap (marketSentiment.ts)

v1.13.2

  • Fix Jupiter price 400s when no open positions — Auto Trader was calling usePrice(['']) as a placeholder, producing GET /price/v3?ids= (empty ids) every 10s and returning HTTP 400. Now passes [] directly; fetchPrices already short-circuits to {} (BotPage.tsx)

v1.13.1

  • Market sentiment chip in Auto Trader header — single composite glance (0.4·avg6h + 0.3·avg24h + 0.3·breadth, clipped) labeled Bullish / Neutral / Bearish at ±0.15 thresholds. Tooltip exposes raw avg 6h/24h price change, 6h net-buyer breadth, and sample size. New GET /api/bot/market-sentiment endpoint, polled every 30s while bot runs (MarketSentimentChip.tsx, routes/bot.ts, useMarketSentiment.ts)
  • AI Decisions — copy-as-JSON per row — small JSON button copies the full AiDecisionLogEntry (inputs + outcome + sentiment + perf snapshots) to clipboard for prompt debugging. Confirms with ✓ (AiDecisionsPanel.tsx)
  • AI Decisions — Δ vs prev (same mint) — expanded panel now shows changed fields (action, outcome, conf, composite, pnl, reason) between current decision and the previous one for the same mint, so you can see what the AI changed its mind on. Header shows Δ{n} count

v1.13.0

  • Market sentiment context for AI — new marketSentiment.ts computes a per-tick macro snapshot from the trending list (top 25 by organicScore, filtered to mcap ≥ $200k & organicScore ≥ 70). Tracks avg 6h + 24h price change, 6h net-buyer breadth %, avg organicScore, day-of-week (UTC) and weekend flag. 15min TTL.
  • Bot recent performance context for AI — same module derives last-20-closed stats: win/loss split, win-rate, avg pnl, avg held minutes, consecutive same-sign streak from newest, top exit reasons.
  • Both blocks injected into entry + exit prompts — system prompt updated to treat them as advisory (broad-red regime → tighter entries; losing streak → bias skip on borderline). Will not hard-veto on macro alone.
  • AI Decisions log captures snapshots — AiDecisionLogEntry gains marketSentiment and botPerformance fields, written by recordDecisionLog (aiAdvisor.ts).
  • AI Decisions panel — expandable rows — rows with context show ▸/▾ indicator; click to reveal market regime + bot performance snapshot the AI saw at decision time (AiDecisionsPanel.tsx)

v1.12.2

  • Logs tab — Copy + Download — every log tab (Backend / Frontend / Network) gains export buttons that emit the currently filtered rows as ISO-timestamped plaintext, ready to paste into a bug report or save as .log (LogsPage.tsx)
  • AI Decisions search + Action filter — new search box matches mint, symbol, reason, and action; new Action filter chips (buy / sell / hold / skip) sit alongside the existing Kind and Outcome filters (AiDecisionsPanel.tsx)

v1.12.1

  • AI Decisions panel relocated — moved from the Auto Trader page into the Logs tab as a 4th sub-tab, consolidating all troubleshooting surfaces in one place (LogsPage.tsx, BotPage.tsx)

v1.12.0

  • Logs tab — new /logs route with three sub-tabs (Backend / Frontend / Network) for end-to-end troubleshooting without tailing journalctl or opening DevTools
  • Backend log ring — logRing.ts keeps last 2000 entries; logger.ts emit() patched to push every leveled log into the ring (stdout/stderr writes unchanged)
  • Network log ring + global fetch interceptor — networkRing.ts monkey-patches globalThis.fetch once at boot; captures method, URL, status, duration, error for all outbound calls. Auto-classifies source (Jupiter / OpenAI / Solana / Telegram / Other). Redacts api_key, token, secret query params. Last 1000 entries.
  • Frontend log capture — captureFrontendLogs.ts wraps console.{log,info,warn,error} and hooks window.error + unhandledrejection; entries land in frontendLogStore.ts (Zustand, in-memory, last 1000). Real console output preserved.
  • API surface — GET|DELETE /api/logs/backend, GET|DELETE /api/logs/network (routes/logs.ts); polled every 3s by LogsPage.tsx with text search + level/source filter + clear button per tab

v1.11.3

  • AI-unavailable sell threshold raised 3 → 5 — aiUnavailableStreak must hit 5 consecutive failed AI exit calls before force-sell (AI unavailable x5). Combined with the 90s per-mint AI call floor, this gives ~7.5 minutes of AI-provider downtime tolerance before a position is dumped on transient errors. Streak still resets on any successful AI response. (engine.ts)

v1.11.2

  • Auto Trader responsive layout — outer grid now grid-cols-1 xl:grid-cols-[minmax(0,1fr)_560px]. Below the xl breakpoint (1280px) the right column stacks under the left so Active Positions table no longer gets squeezed on mid-size screens. At ≥1280px, side-by-side with right column fixed at 560px (down from 640px). (BotPage.tsx)

v1.11.1

v1.11.0

  • Auto Trader layout reflow — settings cards (Entry, Exit, AI Advisor) moved to a fixed 640px right column on the bot page; PnL History now sits on the same row as Entry, with Active Positions + Activity Log side-by-side under PnL on the left. AI Decisions Panel stays full-width below. Right column no longer stretches on wide displays. (BotPage.tsx)
  • Centered, width-capped page containers — Lend/Earn, Transaction History, Trending Tokens, and DLMM pages now cap content at 1080–1200px and center horizontally so cards/tables stay readable on ultrawide monitors instead of stretching edge-to-edge. (LendPage.tsx, HistoryPage.tsx, TrendingPage.tsx, LiquidityPage.tsx)

v1.10.9

  • Sell on 3rd consecutive AI-unavailable — exit engine now tracks aiUnavailableStreak per position; when AI exit gate is open and the API call fails 3 times in a row, force-sell with reason AI unavailable x3. Streak resets on any successful AI call. Previously a stuck-unavailable position would only exit at max-hold cap. Fields: types.ts, increment/reset in engine.ts, hydrate default in state.ts
  • Sidebar branding — replaced ⚡ glyph with the official Solana mark (inline SVG, green→purple gradient) in both desktop and mobile sidebar headers (Sidebar.tsx)

v1.10.8

  • Per-mint AI call floor (90s) — fixes log spam where 4 SELL@70% calls fired in 1 minute on the same blocked-by-gate position
  • Root cause: exit cache key in aiAdvisor.ts includes dhLen (decisionHistory length); each fresh call records a snapshot, so the next key always misses → every poll = new OpenAI call
  • Fix: lastCallByMint map with MIN_CALL_INTERVAL_MS = 90_000. On cache miss, if last fresh call for this mint was <90s ago, return last decision as cached: true — engine skips logging cached decisions and gate math (effectiveMinConf) decays locally without burning OpenAI calls
  • Cleared via resetAdvisorState() on bot stop, alongside existing cache/rejections/history

v1.10.7

  • Structured backend logger — new logger.ts with leveled output (debug|info|warn|error), ISO timestamps, scoped prefixes, LOG_LEVEL env gate (defaults to info in prod, debug otherwise); errors/warnings route to stderr
  • All 17 console.* call sites in backend prod paths swapped to scoped loggers: index.ts, config.ts, routes/perps.ts, routes/price.ts, routes/vault.ts, bot/state.ts, lib/notifier.ts
  • Noisy [trigger] tx hex dump demoted/removed; tx bytes kept at debug level
  • notifier.ts notify() fire-and-forget hardened — delegates to explicit async deliver() with void marker; all errors captured internally, no unhandled rejection path

v1.10.6

  • Fix HTTP 400 on Run Bot in Background after v1.10.4 — Zustand persist merge in botStore.ts was preserving legacy takeProfitPct/tieredTpEnabled keys from localStorage; backend validateConfig rejects unknown fields
  • Config hydration now whitelists to DEFAULT_CONFIG keys, so removed fields are dropped on load
  • apiFetch in client.ts also reads body.error (not just err/message), matching backend's error shape

v1.10.5

  • Fix [object Object] error in Run Bot in Background modal — apiFetch in client.ts now throws a real ApiError extends Error instead of a plain object literal
  • Consumers using err instanceof Error ? err.message : String(err) (UnlockBotModal, useTradingBot, AddLiquidityModal) now get the actual backend message (e.g. "Wrong password") instead of the Object.prototype.toString fallback
  • withRetry still reads .retryable — unchanged

v1.10.4

  • Exit card consolidated, tiered TP always-on — merged Exit + Tiered Take-Profit into one card; removed non-tiered takeProfitPct and tieredTpEnabled from config
  • Backend types.ts, validateConfig.ts, engine.ts, aiAdvisor.ts drop both fields; tiered sell path runs unconditionally; AI exit context no longer carries takeProfitPct
  • Frontend botStore.ts, useTradingBot.ts, BotPage.tsx same strip; single Exit card lays trailing/maxhold/rebuy above T1/T2 with AI-gated + AfterT1 controls below
  • Zustand persist will drop the legacy keys on next load; no migration needed

v1.10.3

  • Min token age filter — new minTokenAgeHours config (default 0 = off) skips tokens younger than X hours during entry evaluation
  • Backend engine.ts + frontend useTradingBot.ts entry loops drop candidates where (now - createdAt) < minTokenAgeHours
  • Uses Jupiter top-level createdAt from tokens/v2/toptrending response; exposed as TrendingToken.createdAt (ms epoch)
  • UI: "Min token age" input on BotPage under Min org buyers

v1.10.2

  • Max-hold AI-gated — new maxHoldAiGated toggle (default on). When AI Advisor enabled, hitting the max-hold cap triggers an AI consult instead of force-selling; strong hold verdicts let winners run past the cap
  • engine.ts defers the max-hold exit reason when gated and opens the AI exit gate even outside loss/gain zones
  • Prompt hint added to exit context: cap-reached positions lean SELL unless 5m+1h signals clearly bullish
  • Exit cache key includes cap bucket so cap-hit calls don't reuse a pre-cap cached decision
  • Safety net: if AI unavailable while gated, cap is honored and position force-sells
  • UI: new checkbox under Max Hold with conditional explainer

v1.10.1

  • AI decision history depth 10 → 20 — aiAdvisor.ts MAX_DECISION_SNAPSHOTS bumped so exit prompt sees a longer HOLD-streak window on slow bleeders
  • Doubles per-call token footprint of the decision-history block on positions with >10 prior snapshots; trade-off for better streak detection

v1.10.0

  • Notis coverage fix — tiered take-profit sells (T1/T2) and close-all sells now fire Telegram notifications
  • doTierSell() in engine.ts routes through notify('bot.exit', …) on success and bot.error on failure
  • closeAllPositions() same treatment
  • Previously only the full trailing-stop / take-profit / max-hold exit path notified, so partial tier exits were silent on Telegram

v1.9.16

  • Notis tab — Telegram notifications — new /notis page with BotFather-driven setup flow
  • Backend notifier.ts: persistent config at notis.json, token masking, per-event toggles (entry / exit / veto / start / stop / error), sendMessage via Telegram Bot API, getUpdates chat discovery
  • Routes notis.ts: GET|PUT /api/notis/config, POST /api/notis/telegram/chats, POST /api/notis/telegram/test (rate-limited)
  • Engine hooks in engine.ts fire notify() on buy / sell / AI veto / bot start / stop / errors — fire-and-forget, never blocks trade logic
  • Frontend NotisPage.tsx: collapsible BotFather guide, token save, fetch-chats button, chat picker, event checkboxes, send-test button, last-send status
  • Disabled by default; stored token is never round-tripped to the frontend (masked as ****last4)

v1.9.15

  • AI Decisions viewer on Auto Trader page — ring-buffered log (200 cap) of AI entry/exit calls with score, confidence, outcome, reason
  • Backend ring log in aiAdvisor.ts; routes GET|DELETE /api/bot/ai-decisions
  • Frontend AiDecisionsPanel polls every 5s, filterable by kind + outcome; Background mode only, in-memory

v1.9.14

  • AI exit prompt guards — fixes spurious SELL verdicts that cited fabricated "prior losses" on first exit evaluation
  • Hallucination guard: system prompt forbids citing prior trades, HOLDs, or losses unless a history block is actually present in the user message; exit prompt now explicitly says "No prior AI calls…" / "No prior bot trades…" when absent so model cannot invent history
  • Score-sign guard: if blended composite score ≥ 0 (neutral/bullish), SELL requires confidence ≥75 AND the reason MUST explicitly cite a specific metric contradicting the positive composite — otherwise default HOLD
  • Grounding rule: narrated reasons must match cited numbers (e.g. claim of "negative 1h" requires 1h price/holder change to actually be negative)
  • Dynamic composite-sign hint appended to exit user prompt per call — model sees which regime applies before responding

v1.9.13

  • AI exit memory + weighted composite score — fixes loop where losing positions got stuck on repeated HOLD@65%
  • Per-position decision history (last 10 snapshots) now injected into exit prompt: prior action, confidence, pnl, composite score, age — AI sees its own HOLD-streak and can break out
  • Weighted composite signal score [-1,+1] across 5m/1h in aiAdvisor.ts: holderChange/numNetBuyers 1.2, priceChange/organic buy-sell ratio 1.0, liquidityChange 0.8, volumeChange 0.5, total vol ratio 0.4, trade-count ratio 0.3; blended 40% 5m / 60% 1h
  • System prompt adds HOLD-streak failure-mode rubric — MUST bias SELL when composite trends negative across prior HOLDs with deteriorating pnl; score ≤ -0.3 on 1h = confirmed reversal
  • Dynamic sell gate: effectiveMinConf = max(25, aiMinConfidence − min(20, heldMin/10) − min(15, |lossPct|)) — a -10%, 100-min position drops sell gate from 60 to 25, letting moderate-confidence SELL calls fire
  • Cache TTL decay: 2 consecutive HOLDs → cache shrinks to 5 min, 3+ → 2 min (was fixed at aiCacheMinutes, typically 10)
  • Cache key now includes composite score bucket → cache auto-invalidates when signals shift, not just pnl
  • Exit log line now shows [gate=X, score=±Y] for visibility into why SELL did/didn't fire

v1.9.12

  • Codebase sanity pass — hardened Docker deployment + fixed AI exit gate edge case
  • docker-compose.yml now passes through OPENAI_API_KEY and SOLANA_RPC_URL (were silently dropped, disabling AI and falling back to rate-limited public RPC in container)
  • Persistent state: new BOT_STATE_DIR env (default cwd, Docker: /data) honored by state.ts, vault.ts, bot.ts — named volume bot-state prevents bot-state.json + vault.json wipe on container restart
  • VITE_API_BASE no longer hardcoded in compose; overridable via env
  • AI exit loss-side gate decoupled from tier completion (engine.ts:245) — losing trades that never hit T1/T2 can now trigger aiExitLossPct instead of being silently skipped when tieredTpEnabled
  • Local browser bot now logs a one-time warning when aiEnabled is on — AI advisor is backend-only, prevents silent no-AI runs

v1.9.11

  • tsc -b build fix: narrowed tier union type after guard to satisfy strict TS in doTierSell call

v1.9.10

  • 2-tier scale-out take-profit — sell fraction at T1, second fraction at T2, let remainder ride on trail
  • Config: tieredTpEnabled, tp1Pct/tp1SellPct, tp2Pct/tp2SellPct, afterT1Mode (tighten trail vs breakeven floor), tightTrailPct
  • Position state extends with tokenAmountRemaining, tiersHit, breakevenFloor
  • Closed positions gain tier field (1/2) for partial exits; full close keeps existing semantics
  • Available in both backend vault bot and browser local bot

v1.9.9

  • HOLD-specific confidence rubric in system prompt — scores how certain the hold call is, not bullishness
  • Prevents HOLD decisions from inheriting buy/sell confidence semantics

v1.9.8

  • Removed prompt-side instruction that forced hold when confidence <50 — was redundant with exit HOLD default and risked converting real low-conf sell signals to hold
  • Confidence gating now handled purely by aiMinConfidence threshold in engine (single source of truth)

v1.9.7

  • AI confidence now explicitly defined as action certainty, not price prediction — fixes semantic ambiguity where model rated "likelihood of dump" instead of "certainty skip is correct"
  • Hard floor added: 2+ bearish signals + skip/sell decision → confidence MUST be 80+
  • Low-confidence band (<50) now instructs model to pick hold instead of acting with weak conviction

v1.9.6

  • AI advisor system prompt gains explicit confidence calibration rubric — 90-100 for multi-signal alignment, 80-89 for 2 strong signals, 70-79 for single signal, etc.
  • Explicit instruction to avoid clustering around 70-80% when reason cites multiple confirming timeframes/signals
  • Fixes observed miscalibration where strong multi-timeframe veto reasons ("negative holder change and declining volume across multiple timeframes") rendered at only 75% confidence

v1.9.5

  • Codebase sanity pass: hardened .env load in backend/src/config.ts to be __dirname-relative (no longer brittle to process.cwd())
  • Warn log emitted at startup when OPENAI_API_KEY is missing — AI exit advisor silently no-ops before
  • docker-compose.yml FRONTEND_ORIGIN now overridable via env (${FRONTEND_ORIGIN:-http://localhost:3000}) for hybrid docker-backend + dev-frontend setups
  • .env.example documents optional OPENAI_API_KEY

v1.9.4

  • AI exit prompt rewritten to bias toward HOLD as default, countering observed sell-happy behavior
  • System prompt gains exit-specific guidance: ignore single-candle 5m noise, require sustained reversal across 5m AND 1h, small green P&L is not a sell signal
  • Exit context now includes trailingStopPct, takeProfitPct, and drawdownFromPeak — AI can see the guardrails that already exist
  • User message reframes: "Default action is HOLD unless clear reversal" / "Recommend SELL only on clear sustained reversal"

v1.9.3

  • AI exit decisions now gated by P&L bands — AI only consulted when pnlPct <= -aiExitLossPct or pnlPct >= aiExitGainPct
  • Middle band (small green/red) handled by trailing stop + max-hold only, preventing premature exits on minor wobble
  • Two new config knobs: aiExitLossPct (default 10%) and aiExitGainPct (default 30%), surfaced in AI Advisor card
  • Fixes issue where AI sold positions at +1% "good exit point" despite 100% TP target — AI was unaware of user strategy

v1.9.2

  • AI Advisor gains per-mint rejection memory — last 3 AI skip/veto/no-confirm decisions on the same mint injected into entry prompts
  • Each rejection line: action, confidence, reason quote, age (e.g. skip @80% — "sell-dominated volume" (3m ago))
  • System prompt updated: if flagged concerns persist in current stats, keep skipping; if conditions materially improved, fresh look OK
  • In-memory only (cleared on bot stop), capped at 3 per mint; cache key includes rejection count

v1.9.1

  • AI Advisor now has per-mint trade memory — last 5 closed trades on the same mint injected into both entry and exit prompts
  • Each history line: PnL%, hold duration, exit reason, age (e.g. +45.2% (held 12m, exit=take profit +45%, 2h ago))
  • System prompt updated: model factors prior bot outcomes when judging repeat signals
  • Cache key includes history length so new closes invalidate stale decisions
  • No behavior change on first trade of a mint; token overhead ~200/call max

v1.8.1

  • AI Advisor system prompt retuned for memecoin context — removed "conservative/skeptical/ignore hype" framing that caused AI to veto nearly every trending token
  • New prompt treats memecoins as momentum plays, weighs signals on balance, and only skips on clear red flags (dumping liquidity, sell-dominated volume, collapsing holders)

v1.8.0

  • AI Advisor prompts now feed full Jupiter market context to the model
  • Entry prompt: all 13 stat fields (priceChange, holderChange, liquidityChange, volumeChange, buy/sell volume, organic volumes, num buys/sells/traders/organic buyers/net buyers) across 5m/1h/6h/24h intervals
  • Exit prompt: fetches live token stats via /tokens/v2/search before each AI call and includes 5m + 1h intervals alongside entry/current/peak price, PnL, and hold time
  • Field names match Jupiter API exactly (no abbreviations) for self-documenting prompts
  • Added fetchTokenStats(mint) helper in jupiterApi.ts; exported IntervalStats interface

v1.7.13

  • Entry loop now tracks mints the AI rejected (veto or no-confirm) and silently skips re-evaluating them for aiCacheMinutes
  • Eliminates repeated skip logs for the same trending tokens and saves redundant OpenAI calls
  • Rejection list cleared when bot stops

v1.7.12

  • AI Advisor toggle label now always reads "Enabled" (checkbox state indicates on/off) — previous "Disabled" label was misleading
  • Activity log no longer spams cached AI decisions — exit-loop advisor only logs on fresh calls (not cache hits), cutting log volume dramatically for held positions

v1.7.11

  • Backend now loads .env from repo root instead of backend/.env
  • Single source of truth for env vars across the monorepo (matches existing .env convention used by this project)
  • No migration needed if you already keep .env at the repo root

v1.7.10

  • Fix: AI Advisor numeric fields (min confidence, max calls/hr, cache TTL) appeared blank for users upgrading from ≤1.7.8
  • Root cause: Zustand persist shallow-merged old storage over fresh defaults, wiping fields that didn't exist in prior versions
  • Fix: custom merge deep-merges persisted config over DEFAULT_CONFIG, so any new field added later shows its default instead of undefined

v1.7.9

  • Auto Trader: optional AI advisor via OpenAI API (opt-in, OPENAI_API_KEY env var)
  • Three modes: Veto (AI can block buys it disapproves), Confirm (AI must explicitly approve buys), Advisory (log-only, no action)
  • Entry gate: runs after Jupiter filters, before swap — decision + confidence + reason logged to Activity Log
  • Exit signals: AI can trigger early sell when no rule-based exit fires. Rule-based stops (trailing, take profit, max hold) always override — AI never blocks safety exits
  • Cost control: per-token decision cache (configurable TTL) + hourly rate cap; model selection between gpt-4o-mini (cheap) and gpt-4o
  • New UI card in Bot page for all AI config; defaults disabled so existing deploys unchanged

v1.7.8

  • Backend security hardening pass
  • Brute-force guard on POST /api/bot/unlock — 5 failed attempts per 15 min per IP (successful unlocks skip the limit)
  • Global error handler now logs full stack + X-Request-Id per request; clients get the requestId in the error body for traceability
  • New validateBotConfigPatch() — strict field-level validation on PATCH /api/bot/config and the config payload of /unlock. Blocks negative buyAmountSol, out-of-range slippageBps, unknown fields, NaN, wrong types, and mcapMin > mcapMax

v1.7.7

  • Auto Trader: clear stale Active Positions that aren't in the wallet anymore (sold externally, failed exits, etc.)
  • Per-row × button on each active position — removes from state without selling
  • "Prune Ghosts" button scans wallet via getParsedTokenAccountsByOwner and auto-removes positions with 0 on-chain balance
  • Works with background bot (uses vault pubkey, no unlock required to prune)

v1.7.6

  • Portfolio → Token Holdings: SOL row now uses the official Solana icon via TokenLogo, matching the style of SPL token rows (was a purple ◎ glyph)

v1.7.5

  • Backend hardening pass from codebase sanity check
  • Path param validation added to proxy routes — base58 regex for wallet/mint/pool addresses (dlmm, tokens/icon, portfolio), whitelist for Jupiter token category/interval, safe charset for trigger orderId
  • Atomic writes (tmp+rename) for bot-state.json and vault.json — prevents corruption on crash mid-write
  • Icon cache now LRU-bounded at 5000 entries to prevent unbounded memory growth
  • Backend RPC URL moved from frontend-scoped VITE_RPC_URL to dedicated SOLANA_RPC_URL env var
  • Spot chart bars flattened; auto-fill toggle now renders proportional distribution (from v1.7.4)

v1.7.3

  • Lend / Earn page redesigned — Available Markets and My Positions merged into a single unified view
  • Deposited amount and USD value now shown bottom-left of each market card inline
  • Total deposited and position count moved to compact inline header strip
  • Deposit/Withdraw mode toggle moved inline with input to reduce vertical space
  • 2-column grid on large screens eliminates wasted whitespace

v1.7.2

  • Auto Trader: rebuyCooldownMinutes added as an independent config field (default: 60m)
  • Cooldown is now separate from max hold time — both can be tuned independently
  • UI input added to Exit card; set to 0 to disable cooldown entirely

v1.7.1

  • Auto Trader: trending token candidates sorted by organic score (desc) before buying — best signals get position slots first when capacity is limited
  • Auto Trader: rebuy cooldown blocks re-entering a token that was just stopped out within the cooldown window

v1.7.0

  • DLMM pool browser overhauled with smarter filtering and scanning
    • TVL filter replaced with min/max range text inputs (supports 25k, 1m etc.) — defaults to $25K min
    • Bin step filter added — filters pools with step ≥ value, defaults to 100
    • Scan button — filters and sort are committed on click, not on every keystroke
    • Sort buttons (Fee/TVL, Volume, TVL) trigger a fresh server fetch on click
    • APR sort removed — replaced by Fee/TVL (fee_tvl_ratio_24h:desc) which is the correct metric
    • Fixed Meteora API TVL filter: now uses filter_by=tvl>VALUE (was sending unsupported min_tvl)
    • "Other…" wallet button renamed to "Import"

v1.6.9

  • DLMM token icons now load correctly — icon lookups proxied through backend to fix CORS errors
  • Backend caches token icons 24h in-memory, eliminating repeat Jupiter API calls and 429s
  • Auto Trader runs as a background systemd process — continues trading without browser open
  • update.sh skips backend rebuild when no backend files changed (faster redeployment)

v1.6.5

  • Auto Trader entry fields: suffixes/units now displayed inside input fields; all fields uniform width
  • Activity Log card height capped to match other dashboard cards

v1.6.0

  • Auto Trader: price change filter replaced with a min/max Price Chg Range (was single min value)
  • HTTPS support added to bare-metal install — self-signed TLS cert generated automatically
  • install.sh now auto-detects and sets FRONTEND_ORIGIN to the server IP
  • Fixed relative API base path in production builds

v1.5.0

  • Auto Trader — automated meme coin sniper bot
    • Configurable entry rules: signal interval, poll rate, buy amount, max positions, min organic score, price change range, price impact, mcap range, slippage, and skip filters (suspicious, mintable, freezable)
    • Configurable exit rules: trailing stop %, take profit %, max hold time
    • Live Activity Log with buy/sell events and Solana Explorer links
    • Cumulative P&L chart with per-trade history
    • Encrypted private key vault — key never leaves the browser unencrypted
    • Close empty token accounts utility

v1.4.3

  • Portfolio tab: token detail panel with quick-sell on row click
  • Portfolio tab: 24h price change column on token holdings
  • Close empty token accounts button (reclaim rent)
  • Fixed stale chart on token switch

v1.4.2

  • Trending tab: organic buyers column, interval filters, and one-click quick buy buttons
  • DLMM tab redesigned with Trending-style layout

v1.3.0

  • Trending tab — Jupiter organic score token leaderboard
    • 5m / 1h / 6h / 24h interval selector with per-interval price change and volume
    • Rank, logo, name/symbol, price, % change, volume, organic score, and audit warnings per row
    • Click any row to expand a full TokenInfoPanel with price, liquidity, market cap, and safety audit
    • Buy button navigates directly to Swap with the token pre-selected
    • 30s auto-refresh; data pulled directly from Jupiter toptrending API (no extra price calls)

v1.2.10

  • Perps SL/TP fixes
    • Fixed error 6039 "Exponent Mismatch" for equity trigger orders (SPY etc.) — Flash Trade API hard-codes exponent -6 but equity oracles use -5; now patches transaction instruction bytes post-build
    • SL/TP orders now visible on position cards — added /orders/owner/:wallet endpoint and merged trigger data into position display
    • Switched RPC to Helius for reliable blockhash fetching (avoids public endpoint 403s)

v1.2.9

  • Meteora DLMM Add Liquidity modal redesigned to match Meteora UI
  • Fixed error 6040 "Invalid position width" — removed ±1 bin padding that exceeded 70-bin limit; default range targets ~30 bins using bin-step math

v1.2.8

  • Swap page wallet token selector — "You Pay" token dropdown shows your wallet balances at the top
  • Dashboard price card shows BTC, SOL, and SPY via Flash Trade API; clicking a ticker switches the chart

v1.2.7

  • Swap page redesigned to single centered column with Jupiter-style TokenInfoPanel for output token (price, liquidity, market cap, audit flags)
  • Wallet balance displayed for all tokens in "You Pay" field (not just SOL)

v1.2.0

  • Perps tab — perpetual futures trading via Flash Trade
    • Long/short on SOL, BTC, ETH, JitoSOL, JUP, BONK, WIF, PYTH, JTO, RAY, plus equities (SPY, NVDA, TSLA, AAPL, AMD, AMZN) and commodities (XAU, XAG)
    • 1×–10× leverage with presets and slider
    • Live entry price + liquidation price preview
    • Stop Loss / Take Profit orders with on-chain validation
    • Add / Remove collateral to adjust leverage
    • TradingView-style price chart above the trade form via Pyth Network OHLCV
    • Live mark prices polled every 5s; positions refreshed every 15s

v1.1.0

  • Meteora DLMM Liquidity — full integration with the Meteora DLMM SDK
    • View all active positions across every pool with live APR, bin range, and claimable fees
    • Claim swap fees and LM rewards per position or all at once
    • Remove 100% of liquidity and close a position in one action
    • Pool browser with search, sorted by Fee/TVL, Volume, or APR
    • Add liquidity with Spot, Curve, and Bid-Ask strategy selection

v1.0.1

  • Token search icons, SOL price display, real token logos via Jupiter CDN
  • Mobile layout: slide-over sidebar with hamburger, auto-close on navigation
  • Wallet backup flow, swap transaction feedback, on-chain history

v1.0.0

  • Initial release

License

MIT — use freely, build on top, ship your own terminal.


Built with ⚡ on Solana · Powered by Jupiter, Meteora & Flash Trade

About

A full-featured Solana trading terminal powered by Jupiter

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages