Last synced: 2026-03-02
The Superteam Academy admin panel provides tools for syncing Sanity CMS content to the on-chain program.
The admin panel is available at /{locale}/admin (e.g., /en/admin).
Authentication: The panel is protected by a shared secret. On the login page, enter the value of ADMIN_SECRET from your environment variables.
| Variable | Description |
|---|---|
ADMIN_SECRET |
Admin password (min 32 chars, random). Set in .env.local. |
PROGRAM_AUTHORITY_SECRET |
Base58 private key of the keypair that is authority on the on-chain Config PDA. |
BACKEND_SIGNER_SECRET |
Base58 private key of the backend signer registered in Config.backend_signer. Used to sign on-chain transactions from API routes. |
SANITY_ADMIN_TOKEN |
Sanity write token from sanity.io/manage. Required to sync onChainStatus back to Sanity after deploying a course. |
Course content lives in Sanity CMS. On-chain course state lives in the Solana program. The admin panel bridges these two.
A course must be in onChainStatus.status == "synced" before it appears to learners.
- Create the course in Sanity Studio (
/studio) with all modules, lessons, and metadata. - Open the admin panel at
/en/admin. - Select "Deploy Course" and choose the course from the Sanity course list.
- The admin panel will:
- Call
create_courseon-chain (viaPROGRAM_AUTHORITY_SECRET) - Create a Metaplex Core collection for the course track (via
deployCourseTrackCollection) - Update
onChainStatusin Sanity to{ status: "synced", ... }(viaSANITY_ADMIN_TOKEN)
- Call
- The course is now visible in the learner-facing platform.
- Open the admin panel at
/en/admin. - Select "Deploy Achievement".
- The admin panel calls
create_achievement_typeon-chain and creates the Metaplex Core collection.
Courses can be toggled on/off without deleting the on-chain PDA:
- Deactivate:
POST /api/admin/courses/deactivate— sets the on-chain Course PDAis_active = false - Reactivate:
POST /api/admin/courses/reactivate— setsis_active = true
Both routes require ADMIN_SECRET in the Authorization header.
GET /api/admin/status returns:
- Whether the on-chain program is live (Config PDA exists)
- Whether the local
PROGRAM_AUTHORITY_SECRETmatches the on-chainConfig.authority
POST /api/admin/resync re-reads on-chain state and backfills Supabase mirror tables. Use this to recover from Supabase write failures or sync drift.
- "Unauthorized": Check that
ADMIN_SECRETis set and matches the value used at login. - "Transaction failed": Verify
PROGRAM_AUTHORITY_SECRETis the correct authority keypair and has SOL for fees. - "Sanity update failed": Verify
SANITY_ADMIN_TOKENhas write access to the dataset. - Course not appearing to learners: Check
onChainStatus.statusin Sanity Studio — it must be"synced".
ADMIN_SECRETshould be at least 32 random characters. Never commit it to version control.PROGRAM_AUTHORITY_SECRETandBACKEND_SIGNER_SECRETmust never be exposed to the browser — all admin API routes useimport "server-only".- The admin panel is for internal use only. Do not expose it publicly without additional authentication.