JBALLIN Rewards
A wager leaderboard and merch store for Kick streamer JBALLIN. Affiliate data is pulled by a protected job, so the API key never reaches the browser and usernames are masked on the server.
- Client
- JBALLIN · Kick streamer
- Partner
- Rainbet
- Year
- 2026
- Role
- Design & development
- Code
- Code · GitHub ↗
- Next.js 16
- TypeScript
- Tailwind v4
- MySQL
- Rainbet API
- Shopify
- GitHub Actions

01Overview
JBALLIN's viewers sign up on Rainbet with his code and compete for a monthly prize pool. He also sells merch.
The brief was to match the best sites in the niche and beat them on two points: a leaderboard rendered on the server, and a search box so viewers can find their own rank.
02What I built
Leaderboard
Server-rendered ranking with self-lookup search and previous months.
Store
Products synced from Shopify, category sidebar and an auto-rotating banner.
Prediction
Viewer predictions for stream events.
Stream tools
Bonus hunt board, tournament board and a giveaway wheel for live use.
Referral & instructions
Clear pages explaining the code, the rules and how to join.
Share previews
Open Graph images generated with the live podium.
03Album · 6 screens
Click any screen to open it. Leaderboard and store screens use sample data; player names are hidden.
04Problems I solved
01Keep the API key secret
The problem
The affiliate API takes its key as a URL parameter. Any request from the browser would leak it.
The fix
Only a protected scheduled job ever calls the API. The site reads from its own database, never from the casino.
02Privacy for players
The problem
Full usernames must never be public.
The fix
Names are masked on the server before any data leaves it, not hidden with CSS.
03Money without rounding errors
The problem
Wager amounts arrive as high-precision decimal strings.
The fix
They're parsed with decimal-safe code and stored as DECIMAL in MySQL. No floating point for money.
04Results that can't change
The problem
A bad sync shouldn't wipe a leaderboard or rewrite who won.
The fix
Rows are never deleted on a failed sync, and a closed month's final results are frozen.
Next case study
RAVONEVERSLEEPS →
Booking new projects
Got a streamor a store?Let's build it.
Tell me what you have in mind. You'll get a plan and a timeline before anything starts.
