Open-source web tool for the Quinfall MMORPG auction house. Discord login, live scraper, price history, alerts, and a flip calculator — all driven by a reverse-engineered TCP protocol to the game server.
Live site: https://runevault.gg · Public changelog: #/changelog
RuneVault is a self-hostable companion app for Quinfall. A Go backend keeps long-lived TCP connections to the game server, speaks the game's binary auction protocol, and exposes a React frontend with search, price history, alerts, market movers, and a flip calculator. Users sign in with Discord; an optional premium gate (off by default in the open-source build) is included for self-hosters who want to monetise.
┌─────────────────────────────────────────────────────────────┐
│ Browser (React + Vite) │
└───────────────────────┬─────────────────────────────────────┘
│ HTTPS
┌─────────▼─────────┐
│ Caddy (TLS + reverse proxy)
└─────────┬─────────┘
┌───────────────┴───────────────┐
┌───────▼────────┐ ┌───────▼─────────┐
│ Go backend │ ◄──────► │ Steam-auth │
│ HTTP API + │ │ Node sidecar │
│ game client │ └─────────────────┘
└──────┬─────────┘
│ TCP (TLV-encoded binary protocol)
┌──────▼─────────┐ ┌──────────────────────┐
│ Quinfall game │ │ PostgreSQL 16 │
│ server │ │ users · alerts · │
└────────────────┘ │ listings · chat │
└──────────────────────┘
See docs/ARCHITECTURE.md for the long version.
- 🔎 Auction search — full filters (category, item, price, level, grade, enhancement)
- 🔔 Alerts — Discord webhook + Web Push, up to 25 per user
- 📈 Price history — Recharts-based, 24h free / 30d gated by premium
- 📊 Market movers — top gainers and losers over 6h / 12h / 24h / 3d / 7d
- 💰 Flip calculator — per-enhancement ROI, velocity, confidence
- 🔥 Best deals — live underpriced listings feed
- 💬 Live trade chat — Server-Sent-Events stream of in-game chat
- 🌐 Multi-language — five locales, light + dark themes
- 🪙 Optional premium gate — activation keys (1d / 7d / 14d / 30d / lifetime, stackable). Disabled by default in self-hosted builds.
Full release history: CHANGELOG.md.
Prereqs: Go 1.22+, Node 22+, Docker + Docker Compose.
git clone https://github.com/Velm14/runevault.git
cd runevault
# 1. Configure
cp .env.example .env
# Generate two 64-char hex secrets:
openssl rand -hex 32 # paste into JWT_SECRET
openssl rand -hex 32 # paste into TOKEN_ENCRYPTION_KEY
# Create a Discord app at https://discord.com/developers and fill in
# DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, DISCORD_REDIRECT_URI.
# Add your Steam credentials + a real GAME_TOKEN/HW_FINGERPRINT.
# 2. Build + start everything
docker compose up -d --build backend app-db frontend caddy
# 3. Frontend dev server (hot-reload)
cd frontend
npm install
npm run dev
# → http://localhost:5174
# 4. Sign in via Discord, browse the auction house.Without a Quinfall account? Set SKIP_PUBLIC_CONNECTION=true in .env
to boot the backend without a live game connection. The HTTP API still
serves cached/scraped data from the DB but /api/auction/search will fail.
First Steam login needs a Steam Guard code — see
docs/TROUBLESHOOTING.md.
| Doc | What it covers |
|---|---|
docs/SETUP.md |
Full local development setup |
docs/ARCHITECTURE.md |
Packages, services, data flow |
docs/TROUBLESHOOTING.md |
Common failures and fixes |
docs/DEPLOYMENT.md |
Deploying with Docker Compose |
docs/protocol/ |
Reverse-engineered Quinfall protocol notes |
docs/design/design-system.md |
Fonts, colors, components |
CHANGELOG.md |
Release notes (rendered publicly at #/changelog) |
CONTRIBUTING.md |
Code style, PR flow, release checklist |
SECURITY.md |
Responsible disclosure |
| Layer | Tech |
|---|---|
| Backend | Go 1.22 · net/http · PostgreSQL 16 (lib/pq) · web-push-go |
| Frontend | React 19 · Vite 7 · TypeScript 5 · Tailwind 4 · TanStack Query · Recharts |
| Steam auth sidecar | Node.js 22 · steam-user · steam-session |
| Infra | Docker Compose · Caddy 2 (TLS + reverse proxy) · Umami (analytics) |
| Auth | Discord OAuth · session cookies + JWT |
| Optional | Cloudflare Turnstile · Web Push (VAPID) |
This project is solo-maintained on a best-effort basis. There is no paid support and no SLA — responses to issues and PRs can take hours, days, or longer depending on availability. Please be patient and kind.
| What you need | Where to go |
|---|---|
| Found a bug | Open an Issue using the Bug report template |
| Have a feature idea | Open an Issue using the Feature request template |
| Game protocol broke after a Quinfall patch | Open an Issue using the Protocol break template |
| Have a usage / how-do-I question | Start a Discussion (once enabled) |
| Found a security vulnerability | DO NOT open a public issue. See SECURITY.md |
Before opening anything, please skim .github/SUPPORT.md
for what makes a report actionable and what's out of scope.
PRs welcome from everyone — read CONTRIBUTING.md
first. The fastest path to a merged change is one that:
- Builds (
go build ./...andcd frontend && npm run build). - Updates
CHANGELOG.mdif it's a user-visible change. - Doesn't bake in operator-specific values (use env vars).
- Includes a short test plan in the PR description.
Community standards: CODE_OF_CONDUCT.md. Security
reports: SECURITY.md.
Licensed under the Apache License, Version 2.0 — see LICENSE.
This project interoperates with the Quinfall game server over a binary network protocol that was observed and documented through clean-room reverse engineering of publicly visible client/server traffic. No game source code, art, or insider material is included in this repository. "Quinfall" is a trademark of its publisher; this project is not affiliated, endorsed, or sponsored.
The companion scraper (continuous auction-house polling) is disabled
by default in the open-source build (SCRAPER_ENABLED=false). Enabling
it, or running modified versions of this client, may violate the Quinfall
End User License Agreement. Use at your own risk — see the warranty
disclaimer in LICENSE.
If you are a representative of the Quinfall publisher and have concerns, please open a GitHub issue or email the maintainer.