Skip to content

Shiva953/TraderDraft

Repository files navigation

TraderDraft — Solana KOL Trading Competition Platform

TraderDraft is a Next.js platform where real on-chain trader performance becomes a competitive game. The system scrapes top Solana wallet performers (KOLs), mints an SPL token for each one on Solana using a custom Anchor program, and runs biweekly competitions where users hold those tokens and earn scores proportional to their KOL's real PnL.

Demo

TRADERDRAFT_MAIN.mp4

How It Works — End-to-End

  ┌─────────────────────────────────────────────────────────────────┐
  │                        PLATFORM LIFECYCLE                        │
  └─────────────────────────────────────────────────────────────────┘

  [1] Scrape KOLScan leaderboard (Daily / Weekly / Monthly)
         │
         ▼
  [2] Store KOL wallet addresses, PnL, win-rate in Postgres
         │
         ▼
  [3] For each unique KOL name → mint SPL token via Anchor program
      + create Meteora DAMMv2 liquidity pool (token / SOL pair)
         │
         ▼
  [4] Users buy KOL packs (0.1 SOL) → receive 4 random KOL tokens
      (rarity-weighted: LEGENDARY > EPIC > RARE > COMMON)
         │
         ▼
  [5] Biweekly competition window opens (Mon–Thu or Thu–Sun)
         │
         ▼
  [6] Daily at 14:00 UTC → snapshot on-chain balances,
      calculate each user's daily score from KOL PnL × token share
         │
         ▼
  [7] Competition ends → finalize TP + LP for all participants,
      update global tournament points leaderboard

Token Creation & Meteora DAMMv2 Pools

Each KOL gets a unique SPL token minted via the pnlpackprogram Anchor program and an AMM pool created through Meteora DAMMv2 (cp-amm-sdk).

Token Distribution (per KOL)

  Total Supply: 1,000,000,000 tokens (6 decimals)

  ┌──────────────────────────────────────────────┐
  │  94% → Token Vault PDA  (pack rewards pool)  │
  │   6% → Meteora AMM pool (initial liquidity)  │
  └──────────────────────────────────────────────┘

Pool Creation Flow

  Admin wallet
      │
      ├─[1]─ createMint()               → new SPL mint keypair
      │
      ├─[2]─ createMetadata()           → Metaplex metadata PDA
      │         name = KOL name
      │         symbol = generated ticker (e.g. "ANSEM")
      │
      ├─[3]─ setAuthority()             → transfer mint authority
      │         from: admin wallet
      │         to:   global_pack_pool PDA
      │
      ├─[4]─ initKolVaultAndTransferV2  → Anchor instruction
      │         • mints full supply
      │         • 94% → token_vault PDA
      │         • 6%  → poolTokenAccount (ATA owned by admin)
      │         • transfers SOL from global_pack_pool → admin
      │           (to fund Meteora pool creation)
      │
      └─[5]─ cpAmm.createCustomPool()  → Meteora DAMMv2 pool
                tokenA = KOL token  (6 decimals)
                tokenB = NATIVE_MINT / SOL (9 decimals)
                range  = MIN_SQRT_PRICE → MAX_SQRT_PRICE (full-range)
                fees   = 5% base + 5% partner + up to 1% dynamic

The partner fee (5%) routes to a designated fee wallet on every swap via the referralTokenAccount parameter, giving the protocol a sustainable revenue stream.


Pack System

Users purchase packs via the transferToPackPool instruction (0.1 SOL each). The admin's packReveal instruction then selects 4 KOL tokens weighted by rarity and calls transferFromKolVaultToUser for each, moving tokens from the vault PDAs directly into the user's associated token accounts.

  Rarity tiers (determined by KOL leaderboard rank):

  Rank  1–5    →  LEGENDARY
  Rank  6–15   →  EPIC
  Rank 16–30   →  RARE
  Rank 31+     →  COMMON

Competition Logic

Schedule (production cron)

  Mon 00:00 UTC  → startCompetition   (window 1: Mon–Thu)
  Thu 00:00 UTC  → startCompetition   (window 2: Thu–Sun)

  Daily 14:00 UTC → calculateDailyScores  (snapshot)

  Sun 12:00 UTC  → finalizeCompetition (window 1)
  Wed 12:00 UTC  → finalizeCompetition (window 2)

  Every 5 min    → phaseManager  (auto-transition states)
  Every 6 hrs    → updateDB      (refresh KOL PnL from scraper)

Cron jobs are currently driven by node-cron (Vercel crons require a paid plan).

Daily Score Snapshot (calculateDailyScores)

Every day the system reads actual on-chain balances for all users across all KOL token mints — not just what was purchased during the current competition. Users who hold tokens but haven't explicitly joined are auto-enrolled.

  For each KOL token T with participants holding it:

    totalSupply_T  = Σ (balance of T across all participants)

    dailyScore_T(user) = PnL_T  ×  (userBalance_T / totalSupply_T)

  User's total daily score = Σ dailyScore_T(user)  over all held tokens

One DailyScoreSnapshot row is written per user per day (upserted, keyed on userId + competitionId + snapshotDate).

  Example (2 users, 1 KOL with PnL = +500):

  User A holds 60,000 tokens  →  share = 60%  →  daily score = 300
  User B holds 40,000 tokens  →  share = 40%  →  daily score = 200

Competition Finalization (finalizeCompetition)

After the window ends, window scores are aggregated and two metrics are computed for every participant:

  WindowScore(u)  = Σ dailyScore(u, day)  over all days in window

  TP(u) = TP_POOL  ×  WindowScore(u) / Σ WindowScore(v)
                                         (all participants)

  LP(u) = 100  ×  WindowScore(u) / max(WindowScore)

TP (Tournament Points) are proportional — the pool is shared relative to contribution. LP (Leaderboard Points, 0–100%) reflects performance relative to the top scorer. Both are written to CompetitionEntry and the user's totalTournamentPoints is incremented atomically.

  State machine for a competition:

  ACTIVE ──[end window]──► ACTIVE (expired, pending finalize)
         ──[finalizeCompetition]──► FINALIZED

Tech Stack

Layer Technology
Framework Next.js 15 (App Router)
Database PostgreSQL + Prisma ORM
Blockchain Solana — Web3.js, Anchor, SPL Token
AMM Meteora DAMMv2 (@meteora-ag/cp-amm-sdk)
Auth Privy (wallet + social login)
Scraping Playwright + Cheerio (KOLScan leaderboard)
Package manager Bun

Getting Started

1. Environment Setup

cp .env.example .env

Required variables:

  • DATABASE_URL — PostgreSQL connection string
  • NEXT_PUBLIC_PRIVY_APP_ID — Privy app ID
  • PRIVY_APP_SECRET — Privy app secret
  • ADMIN_KEYPAIR — Solana admin wallet keypair (JSON array)
  • NEXT_PUBLIC_SOLANA_RPC_URL — Solana RPC endpoint

2. Install & Run

bun install
bunx prisma generate
bunx prisma db push
bun run dev

Open http://localhost:3000.

3. Seed Initial Data

After the dev server is running:

  1. POST /api/scrapeAndPushToDB — scrape KOLScan and populate the Trader table
  2. POST /api/createTokensAndPoolImproved — mint SPL tokens + Meteora pools for all KOLs
  3. POST /api/competitions/start — open the first competition window

About

Trade Tokenized KOL tokens on solana and compete in live trading windows to earn tournament points.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors