Early Development Notice This project is in early development and subject to breaking changes. It is intended for personal use only and is not compliant with Riot Games Production API key requirements. Self-hosting requires technical knowledge (Identity-Aware Proxy setup, environment configuration, containerized deployment). The future production-facing path documented in this repo excludes the private-only
gambamechanic entirely.
A self-hosted virtual share market for a private League of Legends friend group.
Users trade shares in League of Legends players using virtual currency. Share prices fluctuate automatically based on real-time Ranked LP changes fetched from the Riot Games API.
A live demo is available at demo-nashordaq.kylehub.dev. No account or API key needed -- just open the link and start trading with simulated data.
Nashordaq started as a personal project for my friend group, and it does what I set out to build. But I'm curious whether others would find it useful too.
The current direction is to explore Nashordaq as a private-league product for friend groups, with a self-hosted product first and a hosted multi-room version only if demand proves out. See the Productization Plan for the market research and sequencing, and the Roadmap for implementation-oriented future work.
If that sounds interesting to you:
- Drop your thoughts in the Discussions tab
- Leave a star if you'd want a hosted version
- Open an Idea for features you'd like to see
I'll keep developing this if there's a community that wants it.
- Live Market -- share prices update automatically from real Riot API data.
- Portfolio Management -- buy and sell orders based on player performance.
- Leaderboards -- global ranking of users by total portfolio net worth.
- Self-Hosted -- single-process deployment, no external database or message broker required.
- Proxy-Ready Auth -- designed to sit behind an Identity-Aware Proxy for zero-friction user management.
- A Linux server (or any host that runs containers)
- A domain name pointed at your server
- Pangolin (or another Identity-Aware Proxy) for authentication
- A Riot Games API key
git clone https://github.com/KyleDerZweite/nashordaq.git
cd nashordaqcp .env.example .envOpen .env in your editor and fill in every value. The sections below explain each one.
- Go to the Riot Developer Portal.
- Sign in with your Riot account.
- Generate a Development API Key (regenerates every 24 hours) or apply for a Personal/Production API Key for persistent access.
- Paste the key into
.env:NASHORDAQ_RIOT_API_KEY=RGAPI-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Nashordaq needs two API base URLs. Set them in .env based on the server your players play on.
| Player Server | RIOT_API_BASE_URL (continent) |
RIOT_API_REGION_URL (platform) |
|---|---|---|
| EU West | https://europe.api.riotgames.com |
https://euw1.api.riotgames.com |
| EU Nordic & East | https://europe.api.riotgames.com |
https://eun1.api.riotgames.com |
| North America | https://americas.api.riotgames.com |
https://na1.api.riotgames.com |
| Korea | https://asia.api.riotgames.com |
https://kr.api.riotgames.com |
Full list: Riot routing values
Set NASHORDAQ_DOMAIN to the public domain you will serve the app on, and NASHORDAQ_CORS_ORIGINS to the full origin URL of your frontend:
NASHORDAQ_DOMAIN=nashordaq.yourdomain.com
NASHORDAQ_CORS_ORIGINS=https://nashordaq.yourdomain.com
Nashordaq does not handle login or passwords. It expects an Identity-Aware Proxy to authenticate users and forward their identity via an HTTP header.
Using Pangolin:
- Install and configure Pangolin on your server following the Pangolin documentation.
- Create a new site/resource in Pangolin pointing to your Nashordaq instance.
- Enable authentication on the resource. Pangolin will handle login (SSO, OIDC, etc.) and inject headers into proxied requests.
- Ensure SSO authentication is enabled on the resource. Pangolin will automatically forward
Remote-User,Remote-Email, andRemote-Nameheaders. See docs/DEPLOYMENT.md for a step-by-step Pangolin setup guide.
For defense-in-depth, enable trusted-proxy enforcement so direct backend requests are rejected unless they originate from your reverse proxy network:
# Primary identity header (recommended: Remote-Email)
NASHORDAQ_REMOTE_EMAIL_HEADER=Remote-Email
NASHORDAQ_REMOTE_NAME_HEADER=Remote-Name
# Legacy fallback identity header (default: Remote-User)
NASHORDAQ_AUTH_HEADER=Remote-User
# Optional admin account list for the operator dashboard. Comma-separate
# multiple email addresses if you want more than one admin.
NASHORDAQ_ADMIN_REMOTE_USERS=admin@yourdomain.com
# Optional hardening (recommended in production)
NASHORDAQ_ENFORCE_TRUSTED_PROXY=true
NASHORDAQ_TRUSTED_PROXY_CIDRS=10.89.0.0/16,127.0.0.1/32,::1/128Set NASHORDAQ_TRUSTED_PROXY_CIDRS to the CIDR(s) used by your proxy/tunnel containers on the Podman network.
For any public-facing, compliance-oriented, or future production-style deployment, also set:
NASHORDAQ_GAMBA_ENABLED=falseNewly tracked players cannot be bought until they receive their first successful market update, so users do not trade against the placeholder startup price.
Riot API timeout behavior is also configurable:
NASHORDAQ_HTTP_TIMEOUT_SECONDS=10
NASHORDAQ_HTTP_CONNECT_TIMEOUT_SECONDS=5When a user visits Nashordaq, Pangolin authenticates them first. The backend identifies users primarily from Remote-Email, with Remote-User retained as a legacy fallback. New users are automatically provisioned with the configured starting balance and then complete a one-time in-app self-onboarding step to link their Riot game_name and tag_line.
No external database or message broker to set up -- Nashordaq uses SQLite (created automatically on first run) and an in-process scheduler.
podman-compose up -dThe SQLite database file is stored at the path configured by NASHORDAQ_DATABASE_URL (default: data/nashordaq.db). Back up this file to preserve all data.
cd backend
uv sync # Install dependencies
uv run uvicorn app.main:app --reload # Start dev server
uv run pytest -v # Run tests
uv run ruff check . # Lint
uv run ruff format . # Formatcd frontend
pnpm install # Install dependencies
pnpm run dev # Start dev server
pnpm run build # Production build
pnpm run lint # Lint (ESLint)
pnpm run format # Format (Prettier)This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See LICENSE.