Profitmaker v3 -- Open Source Crypto Trading Terminal

June 17, 2026 · View on GitHub

Profitmaker Story

Profitmaker v3 -- Open Source Crypto Trading Terminal

License Discord

Modular, widget-based trading terminal with support for 100+ crypto exchanges via CCXT. All user state is managed through a REST API backed by PostgreSQL -- every dashboard, widget, group, and setting is persisted per-user.

Launch Terminal | Docs | Discord | Telegram

The hosted terminal runs at terminal.marketmaker.cc (single sign-on via auth.marketmaker.cc). Self-host it anywhere with the steps below.


API-First Architecture

Profitmaker is an API-managed project. All functionality is exposed through a REST/WebSocket API on the backend, backed by PostgreSQL for persistent storage. This design enables:

  • LLM Integration -- AI agents (Claude Code, etc.) can manage the entire platform via API: register users, create dashboards, arrange widgets, place orders, manage exchange accounts
  • Headless Mode -- run the backend without the browser UI for automated trading, data collection, or bot integration
  • Multi-Client -- the same API serves the React frontend, CLI tools, mobile apps, or third-party integrations
  • Per-User Persistence -- every user gets their own dashboards, widgets, groups, exchange accounts, and settings stored in PostgreSQL
# Register a user and get a session token
curl -s -X POST http://localhost:3001/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"trader@example.com","password":"secret123","name":"Trader"}'

# Use the token to create a dashboard
curl -s -X POST http://localhost:3001/api/dashboards \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"title":"My Dashboard"}'

See docs/server-api.md for the full API reference, and docs/remote-control.md for driving a live terminal from the backend — REST mutations stream to open browsers in real time, and UI verbs (switch tab, focus widget, read UI state) are executable over an API. Run bun scripts/control-demo.ts to see it end to end.

AI agents drive the terminal over MCP, and humans/scripts over a profitmaker CLI — both on one shared command registry (31 tools). See docs/mcp.md and docs/cli.md.


Tech Stack

LayerTechnology
UI FrameworkReact 18, TypeScript
BuildVite 5 + SWC
Componentsshadcn/ui (Radix UI + Tailwind CSS)
StateZustand 5 + Immer, synced to API
Data FetchingTanStack React Query
ChartsNight Vision (OHLCV candlestick) + Recharts (pie, bar)
Exchange APICCXT 4.4 (100+ exchanges, REST + WebSocket)
BackendBun + Elysia (HTTP API) + Socket.IO (WebSocket streaming)
DatabasePostgreSQL via Drizzle ORM
AuthLocal sessions (bcrypt) or ecosystem SSO via auth.marketmaker.cc (RS256 JWT, verified through public JWKS)
Exchange keysSSO/central accounts: kept server-side in the auth.marketmaker.cc vault (AES-256-GCM) — the browser never holds secrets. Self-host: passed inline per request, held in memory for the call (not persisted)
TestingVitest + JSDOM
MonorepoBun workspaces (4 packages)

Features

Widget System

  • Drag & drop positioning with snap-to-grid alignment
  • Resize from all 8 directions (edges + corners)
  • Maximize, minimize, collapse -- collapsed widgets dock to bottom bar
  • Multiple dashboards with tab navigation, create/duplicate/rename/delete
  • Right-click context menu to add new widgets
  • Per-widget settings stored per-user in database
  • Editable titles -- double-click any widget header

Trading Widgets

WidgetDescription
ChartOHLCV candlestick (Night Vision), 13 timeframes, infinite scroll
Order BookReal-time bid/ask depth, spread display
TradesLive trade feed with filtering, aggregated mode
Order FormMarket, limit, stop-loss, take-profit, trailing stop, iceberg; live ticker + real balance
PortfolioCross-account allocation — total value, per-asset breakdown, allocation donut (USD-valued)
User BalancesDetailed balances across all accounts with pie-chart breakdown
User Trading DataMy trades, open orders, positions (futures)
Transaction HistoryDeposits / withdrawals / transfers / fees from the exchange ledger
DealsDeal tracking with entry/exit analysis, built from real trade history

All widgets render live data — the demo/placeholder ("not ready") widgets were replaced with real exchange data wired through the data-provider layer.

Data Provider System

  • CCXT Server -- all market data + trading run through the Elysia backend (CORS-free, WebSocket via CCXT Pro); the browser has no CCXT
  • Pluggable server registry -- the built-in ccxt provider plus module-supplied providers (incl. native napi bindings); priority-based resolution, providerId override
  • Automatic fallback -- WebSocket to REST when an exchange lacks Pro support
  • Subscription deduplication -- one connection per data stream, shared across widgets
  • Authenticated calls -- balances, trades, orders, positions and the ledger resolve per account via { accountId } (central accounts) or inline credentials; the server attaches the keys before calling CCXT
  • KuCoin Broker Pro (hosted only) -- KuCoin trades routed through the hosted terminal are attributed to the MarketMaker broker for rebate; self-host installs are unaffected (no-op unless broker env vars are set)

Security & Accounts

  • Authentication -- local register/login (bcrypt, 30-day sessions in PostgreSQL), or ecosystem single sign-on via auth.marketmaker.cc (RS256 JWT verified through the public JWKS — no shared secret in this repo).
  • Central accounts (SSO mode) -- exchange API keys live server-side in the auth.marketmaker.cc vault (AES-256-GCM). The terminal sends only { accountId, want: 'read' | 'trade' } + the user's JWT; the backend fetches decrypted keys server-to-server. The browser never holds secrets.
  • Multiple simultaneous logins -- hold several ecosystem identities at once and quick-switch the active one.
  • Per-account access levels -- accounts can be shared read-only; trade operations on a read-grant are rejected server-side (403).
  • Self-host mode -- without SSO, exchange keys are passed inline per request and held in memory for the call only (never persisted). Legacy browser-stored keys are migrated into the vault and purged; a persistent encrypted self-host store is on the roadmap.
  • Dual server auth -- API_TOKEN for server-to-server + the user's JWT/session for browser calls (every /api/* requires a bearer token).

Quick Start

Prerequisites

Environment Variables

VariableDefaultDescription
DATABASE_URL--PostgreSQL connection string (required)
PORT3001API server port
API_TOKENyour-secret-tokenServer-to-server auth token

Install & Run

# Clone
git clone https://github.com/suenot/profitmaker.git
cd profitmaker

# Install dependencies
bun install

# Set up database
export DATABASE_URL="postgresql://user:password@localhost:5432/profitmaker"
cd packages/server && bun db:push && cd ../..

# Start the API server (port 3001)
bun server:dev

# Start the frontend (port 8080)
bun dev

Open http://localhost:8080 -- register an account to get a default dashboard with 6 widgets.

Scripts

CommandDescription
bun devStart Vite dev server (port 8080)
bun run buildProduction build
bun serverStart Elysia API server (port 3001)
bun server:devStart API server with auto-reload
bun testRun tests (Vitest)
bun lintESLint check
bun db:pushPush schema to PostgreSQL (in packages/server)
bun db:generateGenerate migration files
bun db:studioOpen Drizzle Studio (database GUI)

Architecture

Monorepo Structure

profitmaker/
├── packages/
│   ├── client/             # @profitmaker/client -- React frontend
│   │   └── src/
│   │       ├── components/   # Widgets, UI, AuthPage, AuthGate
│   │       ├── store/        # Zustand stores (synced to API)
│   │       ├── services/     # API client, apiSync, storeSync
│   │       └── hooks/        # Custom React hooks
│   ├── server/             # @profitmaker/server -- Elysia API
│   │   └── src/
│   │       ├── db/schema/    # Drizzle ORM (9 tables)
│   │       ├── routes/       # auth, dashboards, widgets, groups,
│   │       │                 # accounts, settings, providers,
│   │       │                 # exchange, websocket, proxy, health
│   │       ├── services/     # auth, ccxtCache, wsSubscriptions,
│   │       │                 # defaultDashboard
│   │       └── middleware/    # requireUser (session validation)
│   ├── types/              # @profitmaker/types -- shared types (incl. provider contracts)
│   └── sdk/                # @profitmaker/module-sdk -- module SDK
├── package.json            # Bun workspace root
└── vite.config.ts          # Frontend build config

Database Schema

users
├── sessions              (auth tokens, 30-day expiry)
├── dashboards
│   └── widgets           (position, config, per-dashboard)
├── groups                (instrument linking)
├── exchange_accounts     (schema reserved; SSO keys live in the auth.marketmaker.cc vault)
├── data_providers        (ccxt-server provider configs)
├── user_settings         (key-value: theme, activeDashboardId, etc.)
└── widget_settings       (per-widget, per-user configs)

Data Flow

Browser                          Server                      Database
  │                                │                            │
  ├── Login ──────────────────────>│── Verify password ────────>│
  │<── Token + user ──────────────│<── Session created ────────│
  │                                │                            │
  ├── Load state ─────────────────>│── Query dashboards, ──────>│
  │<── Dashboards, widgets, ──────│<── widgets, groups, ───────│
  │    groups, settings            │    settings, providers     │
  │                                │                            │
  ├── Drag widget ─── Zustand ───>│── PUT /api/widgets/:id ──>│
  │    (local state)  (debounced)  │    (position update)       │
  │                                │                            │
  ├── Subscribe data ─────────────>│── CCXT/Socket.IO ────────>│ Exchange
  │<── Real-time stream ──────────│<── Market data ────────────│ API

API Endpoints

GroupEndpointsDescription
AuthPOST /api/auth/register, login, logout GET /api/auth/meUser authentication
DashboardsGET, POST, PUT, DELETE /api/dashboardsCRUD per-user dashboards
WidgetsGET, POST, PUT, DELETE /api/widgets PUT /api/widgets/batchCRUD + batch position update
GroupsGET, POST, PUT, DELETE /api/groupsInstrument linking groups
AccountsGET, POST, PUT, DELETE /api/accountsExchange API accounts
SettingsGET, PUT, DELETE /api/settings/:key PUT /api/settings (bulk)Per-user key-value settings
ProvidersGET, POST, PUT, DELETE /api/providersData provider configs
ExchangePOST /api/exchange/fetch* POST /api/exchange/watch*CCXT market data
ProxyPOST /api/proxy/requestCORS bypass proxy
HealthGET /healthServer health (no auth)

Socket.IO (port 3002): subscribe, unsubscribe, data, error

Supported Exchanges

100+ exchanges via CCXT including: Binance, Bybit, OKX, Coinbase, Kraken, Bitfinex, Gate.io, KuCoin, MEXC, Huobi, Bitget, and many more.

  • profitmaker.cc -- open source crypto terminal + modular server for custom metrics
  • marketmaker.cc -- commercial trading platform with profitmaker integration

Team

StarMapper

StarMapper

Star History

Star History Chart

License

MIT License with Commons Clause.

Allowed: use for any purpose, modify, distribute, create products built with Profitmaker.

Not allowed: sell Profitmaker itself, offer it as a hosted service, create competing products based on it.

See LICENSE for full text. For commercial licensing -- Telegram or email.


MarketMaker.cc

MarketMaker.cc -- commercial trading platform with AI-powered analytics, automated bots, and Profitmaker integration.