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 /agentsby admin, then flagged withisDemoAgent: truevia 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
isDemoAgentflag 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 withdemo_. Unique.creditLimit: > 0, within agent's available balance.
Behavior:
- Generate temporary password (8 chars, alphanumeric).
- Create User:
role: "player",agentId: <demo agent>,authMethod: "credentials",status: "active". - Set
creditLimitandbalancePoints= creditLimit (same as normal allocation). - Deduct from demo agent's balance.
- 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:
- Find user by
usernamewhereauthMethod = "credentials". - Verify bcrypt hash.
- Issue JWT tokens (same as
verify-walletresponse). - 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:
- Generate new temporary password.
- Hash and store.
- 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/demoendpoint — remove.strykr-fe/src/app/demo/page.tsx— remove.strykr-fe/src/store/demoStore.ts— remove.- All
isDemochecks 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
| Rule | Enforcement |
|---|---|
| Only demo agent can create credential players | isDemoAgent: 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 API | Not in any update schema. DB-only. |
Username must start with demo_ | Validation regex on create endpoint |
| Credential login cannot access admin/agent panels | User role is player, standard RBAC applies |
| Web3 users cannot have passwords | authMethod 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
- Add
username,password,authMethodcolumns to User. - Add
isDemoAgentcolumn to Agent. - Backfill: all existing users get
authMethod: "web3". - 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).