A Telegram Mini App game on the TON blockchain. Earn $CUBE (a DB-only soft currency) through daily claims, referrals, and TON donations; rank a queue to mint a generative pixel-art NFT that gates game entry; then play an ancient-world ARPG/4X loop โ castles, heroes, expeditions, PvP arena & raids, and weekly tournaments โ with an optional real-money (USDT) rail via xRocket.
- ๐ฎ Mini App game โ Vue 3 frontend served straight inside Telegram, with TonConnect wallet integration.
- ๐ช DB-only $CUBE โ earned via daily streaks (premium multipliers), referrals, and TON donations;
User.votes+ theBalanceledger are canonical (no on-chain jetton). - ๐จ NFT-gated entry โ Stability AI + ChatGPT generate a pixel-art cNFT through a player-facing webview mint with an escalating eligibility floor; a binary admin Approve/Return deploys it on-chain. Owning it unlocks the game.
- ๐ฐ Ancient-worlds economy โ castles & resource production, hero recruitment / dungeons / quests, weekly boss, async-snapshot PvP (arena + castle raids on an ELO ladder), and a congestion-based expedition loop.
- ๐ฐ Monetization rails โ xRocket USDT wallet (deposits/withdrawals/transfers, reconciled), Telegram Stars Season Pass, Adsgram rewarded ads, and a weekly tournament with a rewards-pool payout.
- ๐งช Heavily tested backend โ 749 tests on the Node.js built-in test runner.
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ
โ Telegram Bot โ โ Fastify Server โ โ Vue 3 App โ
โ (Grammy) โโโโโโถโ (API + Static) โโโโโโโ (Vite, TMA) โ
โ src/bot/ โ โ src/server.ts โ โ src/frontend/ โ
โโโโโโโโโโฌโโโโโโโโโ โโโโโโโโโโฌโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ
โ โ
โ โโโโโโโโโโดโโโโโโโโโโ
โโโโโโโโโโโโโโโถโ MongoDB โ
โ (Typegoose) โ
โโโโโโโโโโฌโโโโโโโโโโ
โ
โโโโโโโโโโดโโโโโโโโโโ
โ TON Blockchain โ
โ (subscription) โ
โโโโโโโโโโโโโโโโโโโโ
See ARCHITECTURE.md for the full system overview and runtime flows.
| Layer | Stack |
|---|---|
| Bot | Grammy + plugins (auto-retry, hydrate, parse-mode, i18n) |
| HTTP API | Fastify + @fastify/middie, @fastify/static |
| Frontend | Vue 3 + Vite + Pinia + TonConnect |
| Database | MongoDB via Typegoose (Mongoose decorators) |
| Blockchain | @ton/ton for donations, wallet binding (ton_proof), NFT minting |
| Money rail | xRocket USDT (micro-USDT ledger) + Telegram Stars (Season Pass) |
| AI | Stability AI (images) + OpenAI (NFT descriptions) |
| Storage | Pinata IPFS for NFT metadata + artwork |
| Quality | @antfu/eslint-config, Prettier, tsc, Husky |
Prerequisites: Node 18+, MongoDB, a Telegram bot token, optional TON wallet for production.
# 1. Configure
cp .env.example .env
# edit .env โ BOT_TOKEN, MONGO_URL, etc.
# 2. Install (root + frontend each have their own package.json)
npm install
npm --prefix src/frontend install
# 3. Run in watch mode โ serves the full app (API + bot + frontend HMR) at http://localhost:3000
npm run dev
# Optional: standalone frontend-only Vite server (port 5173, no /api)
npm --prefix src/frontend run dev| Command | Purpose |
|---|---|
npm run dev |
Backend watch mode (tsx). |
npm run build:all |
Compile backend (tsc) + frontend (vite build). |
npm run lint |
Lint with @antfu/eslint-config. |
npm run format |
Prettier write across .ts/.js/.vue/.json/.css/.scss/.md. |
npm run typecheck |
tsc --noEmit strict. |
npm run test:backend |
Backend unit/integration suite (Node test runner). |
npm run test:coverage |
Coverage report via Node's --experimental-test-coverage. |
npm run start |
One-shot build + run (production-like). |
The backend uses Node.js's built-in test runner (node --test) โ no Jest/Vitest. Handlers are written with dependency injection so tests can swap in mocks without spinning up Mongo, TON, or the bot. See src/backend/auth-handler.test.ts for the canonical pattern.
npm run test:backend # 749 tests across 113 files (Node test runner)
npm run test:coverage # full per-file coverage reportAreas at or near full coverage: every backend route handler, all callback-data packers, every keyboard, every middleware, plus most pure helpers (points, markdown, text, time, votes, leaderboard-rows, โฆ). Files that still have gaps are mostly Typegoose model classes and config bootstrap โ code that only meaningfully executes against a real database or environment. Run npm run test:coverage for the latest per-file numbers.
src/
main.ts # entrypoint โ MongoDB โ bot โ server โ subscription โ workers
server.ts # Fastify, registers /api/* handlers
config.ts # znv + Zod, lazy proxy (throws on read when NODE_ENV=test)
subscription-core.ts # TON transaction watcher (donations โ votes)
subscription.ts # composer wiring for the watcher
bot/
index.ts # middleware chain (ORDER MATTERS) + feature registration
context.ts # Grammy Context + SessionData types
features/*.ts # commands: start, help, line, stats, whales, season-pass,
# unhandled, removed-commands, admin/{queue,
# collection,parameters,transaction,user}
filters/is-admin.ts # auth filter for admin-only commands
backend/ # Fastify handlers (DI-split): auth, mint, claim, castle, hero,
# dungeon, quest, boss, pvp, expedition, tournament, wallet, โฆ
# plus settlement + NFT-mint background runners
common/
models/ # Typegoose: User, Balance, CNFT, Castle, Hero, Match, Wallet*, โฆ
helpers/ # ton, ipfs, generation, files, mint-floor, combat, production, โฆ
frontend/ # Vue 3 + Vite (separate package.json)
src/routes.ts # route table; non-minted users are locked to /mint
locales/ # Fluent (.ftl) translations
docs/ # design & research docs, coverage badge, economy model
The dice game (
/dice), NFT-mint command (/mint), and story game (/play) were removed;removed-commands.tscatches those slash commands and points users to the Mini App. The on-chain $CUBE jetton bridge and the CUBEโSATOSHI exchange were also removed in the DB-only pivot โ see CLAUDE.md.
- ARCHITECTURE.md โ system shape, startup flow, runtime flows, security model
- AGENTS.md โ orientation for AI coding agents working on this repo
- CODEX.md โ quick reference for ChatGPT Codex / Cursor-style tools
- CLAUDE.md โ compact context for Claude Code
- docs/FUTURE_DEVELOPMENT.md โ prioritized improvements and feature ideas
- Fork and create a branch.
- Run the full gate before opening a PR:
npm run lint && npm run typecheck && npm run test:backend && npm --prefix src/frontend run build
- Follow the existing DI handler pattern for any new route or bot command โ it makes the handler testable without booting infrastructure.
MIT โ see package.json.