Non-custodial Solana memecoin terminal + launchpad. Every button is a real transaction signed by the user’s wallet.
| Feature | How |
|—|—|
| Wallet connect | Phantom / Solflare / Backpack via wallet-adapter |
| Board, prices, charts | DexScreener public API + embedded chart |
| New launches + curve trades | pump.fun live stream via PumpPortal websocket |
| Buy / sell (bonding curve) | PumpPortal trade-local → user signs → RPC send |
| Buy / sell (graduated) | Jupiter lite-api quote + swap (fallback PumpPortal auto) |
| Launch a coin | metadata → pump.fun IPFS → PumpPortal create tx (mint keypair + wallet co-sign) |
| Portfolio | on-chain balances (SPL + Token-2022), cost basis + hold clock kept in-browser |
| Protocol preview | vault / flip-fee / desk / redeem math computed live, labeled PREVIEW (not enforced on-chain yet) |
npm install
npm run dev # http://localhost:5173
npm test # protocol unit tests
npm run build # → dist/
Set a fast RPC (Helius/Triton/QuickNode) in Settings — the public endpoint rate-limits.
Static site. Any of:
main; .github/workflows/pages.yml builds and publishes.npm run build, output dist.No platform fee in beta. PumpPortal 0.5% on curve trades, pump.fun 1%, Jupiter LP fees only.
Anchor programs: launch, vault, flip_fee, desk, redeem, copies (see PROTOCOL.md in the demo package / the spec page). Devnet first, then capped mainnet beta, audit before uncapped mainnet.
src/lib/dex.ts DexScreener client
src/lib/pumpportal.ts stream + trade/create tx builders
src/lib/jupiter.ts quote/swap
src/lib/trade.ts buy/sell/launch routing
src/lib/rpc.ts balances, send+confirm
src/lib/protocol.ts BANKER rules (tested)
src/lib/positions.ts local cost-basis ledger
src/components/ Board, CoinPage, Launch, Pages (Portfolio/Settings/About), ui
Default wallet is a browser-side keypair encrypted with a user password (PBKDF2-310k → AES-GCM, localStorage). Deposit from Phantom, trade with no popups, withdraw anytime, export/import key. Phantom/Solflare/Backpack remain available under “Phantom / extension”.
See server/README.md. Desk = non-custodial block bids matched by our server, settled by a two-signer tx. Vault = our bot running the market-maker rules per coin (custodial in beta).
Any coin with a market: 15 SOL (10 → treasury, 5 → chest), one signature, verified on-chain by the server before arming. Owner can deposit tokens (“vault your bag”); anyone can top up the chest. Trims capped 2%/trim, 5%/day, 10% of 1h volume.
Per-vault mode mm (default) or floor. MM counters buys when price is stretched over 30-min VWAP: capture = clamp(10% + stretch×40%, 0, 30%) × mcap tier (×0.5 <$100K, ×1 <$1M, ×0.75 above) × ±20% random, trigger rate 40–70% by buys/min, min buy 0.5 SOL, ≤15% of 1h volume, ≤10% of position/day, ≤5% per capture. Never on dips. Captured SOL → chest → 60% desk bid at −4%, 40% defense in three tranches (−20/−35/−50% from 15-min high). Dev ceiling 5–30%. Everything shows live on the coin page (capture now, stretch, trigger, tier) with a scorecard (captured, redeployed, bought off-chart, floor).
app/src/lib/sim.ts — constant-product pool, scripted + seeded random flow (chop → pump → dump → recover), 1.5% swap fees, the vault’s real rules. npm test in app/ asserts: MM lowers drawdown, does not cap the pump, is profitable, keeps holders better off; 5% chest is cosmetic; <10 tx/hr. The Simulate page runs it in-browser with sliders.
app/src/lib/signal.ts labels every coin RUNNER / HEALTHY / COOLING / CRASHING / BUNDLED / RUG RISK / DEAD from live structure (1h/6h/5m moves, buy:sell, turnover vs mcap, liquidity vs mcap, age, holder concentration, authorities), always with reasons. Tested on synthetic runner / rug / bundle / crash / dead shapes generated by the simulator (test/signal.test.mjs).
Own candlestick chart (lightweight-charts) from GeckoTerminal OHLCV with live ticks from our streams; vault captures (C), dip buys (D), desk fills (OTC), redeems (R), the redeem floor and your TP/SL drawn on it; DexScreener embed as fallback. Sends: Helius priority-fee estimate (High), Jito tip on Jupiter swaps, skip-preflight + 2s rebroadcast until confirmed.