# PullChain > Pull blocks. Master crypto. Own your knowledge. PullChain is a production gamified Web3 education app on Base Mainnet. Players pull blocks from a Jenga tower, study topic cards, answer quizzes, and mint soulbound ERC-721 certificates. - Live: https://pullchain.fun - Contract: https://basescan.org/address/0x5b9e85bbee0ba7abc3f69833bf97ea8799e0e3b3 - Chain: Base Mainnet (8453) - Builder: Mojeeb Titilayo (@MojeebMotion), founder of BlindspotLab - Contract audit: not formally audited unless separate evidence is published ## Game thresholds Source of truth: lib/game-config.ts - Easy learning: 36 blocks, certificate at 16 pulls - Medium learning: 36 blocks, certificate at 24 pulls - Hard learning: 36 blocks, certificate at 36 pulls - Elite slang: 18 blocks, clear at 18 pulls (leaderboard only; no NFT) Shared rules: - 4 MCQ questions per block - Pass threshold for progress/streak: >= 3 correct - Lose a life only on 0/4 - Stability damage by correct count: 22, 14, 8, 3, 0 - Last block in row: +5 stability damage - 3 lives, start stability 100 Elite is separate from Easy learning progress (session.mode = elite). Elite access requires a minted Easy certificate (DB and/or on-chain hasCertificate). ## Auth and integrity - Privy bearer tokens verified server-side - /api/auth/sync does not trust browser-supplied identity fields - Session/progress/certificate/leaderboard mutations are ownership-scoped - Quiz answers re-scored server-side from word bank + selected option text - Lives, stability, score, completion/failure computed on server - Progress is derived from learning-mode quiz attempts only - Certificate mint recording verifies Base tx receipt, sender, contract, CertificateMinted event, difficulty, token id - Duplicate user+difficulty certs and duplicate tx hashes rejected ## Sessions and resume - Each session stores seed + ordered topic_ids - Topic order and quiz option shuffle use seeded Fisher-Yates - POST /api/session resumes the active session for user+difficulty+mode unless restart=true - restart=true ends the prior active session and creates a new one - Resume restores topic order, words_seen, score, lives, stability, attempts ## API surface - POST /api/auth/sync - PATCH /api/profile/username - POST /api/session - GET /api/session/active - GET /api/session/[id] - POST /api/session/[id]/attempt - GET /api/progress (POST disabled) - GET /api/certificate/eligibility?difficulty= - GET|POST /api/certificate/mint - GET|POST /api/leaderboard - GET /api/nft/[tokenId] - GET /api/nft/image/[tokenId] - POST /api/quiz/submit (410 — use session attempt) ## Contract boundary (PullChainCert) - Soulbound ERC-721: transfers and approvals revert - One certificate per wallet per difficulty (Easy/Medium/Hard) - Invalid difficulty reverts - tokenIdOf / getCertificate / hasCertificate for lookups - tokenURI = metadata base URI + tokenId + .json - mint(uint8 difficultyLevel, uint256 score) is open on-chain; app enforces eligibility when recording mints - Do not redeploy or upgrade from app changes ## Word banks - easy/medium/hard: ~500 topics each for learning modes - slang: ~150 terms for elite mode only ## Stack Next.js App Router, TypeScript, Privy, wagmi/viem, Prisma/Postgres, Zod, Resend (optional), Vitest, Vercel ## Builder bio Full-stack Web3 and AI Product Engineer. Founder of BlindspotLab. Designs and ships production applications across smart contracts, embedded wallets, authentication, backend systems and user-facing products.