Skip to main content

Demo Accounts V2 — Spec

Context

Current /demo flow creates a throwaway __demo_user__ with fake wallet and client-side session. No persistence, no real agent hierarchy, no reusable credentials. Deprecate it entirely.

Design

Demo players are real players under a designated Demo Master Agent. They log in with username + password, not Web3Auth. The demo agent is a normal INR master agent with one special privilege: generating username/password credentials for players.

Schema Changes

User model — add credential fields

username    String?  @unique   -- demo player login ID (e.g. "demo_rahul")
password String? -- bcrypt hash, null for Web3 users
authMethod String @default("web3") -- "web3" | "credentials"

Agent model — add demo flag

isDemoAgent  Boolean  @default(false)  -- only ONE agent can have this true

Enforce at DB level: partial unique index on isDemoAgent WHERE isDemoAgent = true.

Components

1. Demo Master Agent (admin setup)

  • Created via existing POST /agents by admin, then flagged with isDemoAgent: true via a one-time admin endpoint or migration seed.
  • INR settlement currency.
  • Normal agent in every way — has credit limit, can be funded, shows in admin panel.
  • The isDemoAgent flag is NOT exposed in any agent creation UI. Admin-only, DB-level.

2. Create Demo Player (agent panel)

Endpoint: POST /agent/demo-players

Auth: Agent must have isDemoAgent = true. All other agents get 403.

Request:

{
"displayName": "Rahul Kumar",
"username": "demo_rahul",
"creditLimit": 100000
}

Validation:

  • Caller's agent must have isDemoAgent: true — hard check, no exceptions.
  • username: 3-30 chars, alphanumeric + underscores only, must start with demo_. Unique.
  • creditLimit: > 0, within agent's available balance.

Behavior:

  1. Generate temporary password (8 chars, alphanumeric).
  2. Create User: role: "player", agentId: <demo agent>, authMethod: "credentials", status: "active".
  3. Set creditLimit and balancePoints = creditLimit (same as normal allocation).
  4. Deduct from demo agent's balance.
  5. Return { username, temporaryPassword, userId }.

The temporary password is shown ONCE. Not stored in plaintext, not recoverable. Agent must note it down or regenerate.

3. Login with Demo ID

Endpoint: POST /auth/demo-login

Request:

{
"username": "demo_rahul",
"password": "abc12345"
}

Behavior:

  1. Find user by username where authMethod = "credentials".
  2. Verify bcrypt hash.
  3. Issue JWT tokens (same as verify-wallet response).
  4. No referral code needed. No wallet needed.

4. Regenerate Password (agent panel)

Endpoint: POST /agent/demo-players/:userId/reset

Auth: Caller's agent must be isDemoAgent: true AND player must belong to this agent.

Behavior:

  1. Generate new temporary password.
  2. Hash and store.
  3. Return { temporaryPassword }.

5. Frontend — Login Flow

strykr-fe sign-in screen (StrykrLoginModal or equivalent):

Add a secondary option: "Login with Demo ID" — a small text link below the main Web3Auth buttons.

Clicking it shows:

  • Username input
  • Password input
  • Submit button

On submit → call POST /auth/demo-login.

  • If success → store tokens, set user, navigate to /sports.

No demoStore. No sessionStorage persistence. No fake balance. The player IS a real player — balancePoints, creditLimit, bets, everything is real and persisted in DB.

6. Frontend — Demo Agent Panel

In the agent panel (/agent), if the logged-in agent has isDemoAgent: true, show an additional tab/section: "Demo Players".

This section shows:

  • List of demo players (username, displayName, balance, status).
  • "Create Demo Player" button → form with displayName, username, creditLimit.
  • "Regenerate Password" action per player.
  • Standard agent actions (allocate/withdraw credit) work as normal.

No other agent sees this section. The isDemoAgent flag controls visibility.

What Gets Deprecated

  • POST /auth/demo endpoint — remove.
  • strykr-fe/src/app/demo/page.tsx — remove.
  • strykr-fe/src/store/demoStore.ts — remove.
  • All isDemo checks scattered across components (Header, BottomNav, ConnectButton, BetSlipCard, BetSlipFooter, etc.) — remove.
  • DemoBanner.tsx — remove.

Demo players are real players. No special UI treatment needed.

Security Constraints

RuleEnforcement
Only demo agent can create credential playersisDemoAgent: true check on every demo-player endpoint
No other agent can set authMethod: "credentials"No endpoint exposes this field except POST /agent/demo-players
isDemoAgent cannot be set via APINot in any update schema. DB-only.
Username must start with demo_Validation regex on create endpoint
Credential login cannot access admin/agent panelsUser role is player, standard RBAC applies
Web3 users cannot have passwordsauthMethod field is immutable after creation

Data Flow

Admin creates Demo Master Agent (INR, isDemoAgent: true)
→ Admin funds Demo Agent with credit
→ Demo Agent creates demo player (username + temp password)
→ Player logs in with "Demo ID" option
→ Player uses platform as normal real player

Migration

  1. Add username, password, authMethod columns to User.
  2. Add isDemoAgent column to Agent.
  3. Backfill: all existing users get authMethod: "web3".
  4. Create demo agent via admin panel, flag in DB.

Out of Scope

  • Self-service demo signup (no public registration).
  • Password reset by player (agent regenerates if needed).
  • Password recovery/forgot password flow.
  • Demo player expiry/auto-cleanup.
  • Rate limiting on demo-login (add later if abused).