MiniApp Monorepo (Nuxt + Nitro + Prisma)
Try the Live Demo on Telegram: https://t.me/tokennectbot
This is a pnpm-based Apps & Packages monorepo with:
- apps/web → Nuxt 3 + Nuxt UI + Tailwind (strict TS)
- apps/api → Nitro server with Prisma (strict TS)
- packages/types → Shared TypeScript types
Includes Docker Compose for PostgreSQL with pgvector.
Prereqs
- Node 18.18+ (Node 20+ recommended)
- pnpm 9+
- Docker Desktop or compatible runtime
Getting Started
-
Install deps pnpm install
-
Start Postgres (pgvector) docker compose up -d
-
Configure API .env cp apps/api/.env.example apps/api/.env
-
Prisma setup (run inside api) pnpm -F @miniapp/api prisma:generate pnpm -F @miniapp/api prisma:push
-
Run both apps pnpm dev # runs apps in parallel
-
Visit
Scripts
- pnpm dev → Run all packages' dev in parallel
- pnpm build → Build all
- pnpm start → Start all (where applicable)
- pnpm lint → Lint all
- pnpm typecheck → Type-check all
Notes
- The API is configured to Prisma against the Postgres instance on port 5464.
- Backend uses
tonand@ton/cryptoto manage a custodial hot wallet for orchestrated payouts. - Configure in
apps/api/.env(see example):TON_API_ENDPOINT,TON_API_KEY(Toncenter recommended)BOT_WALLET_MNEMONIC(24-word seed; keep small balances in dev)TX_ORCHESTRATOR_ENABLED,TX_ORCHESTRATOR_INTERVAL_MS
- Service:
apps/api/server/services/ton.tsprovidesgetBotAddress,sendTon, validation helpers. - Bot balance is tracked off-chain via
Bot.tonBalanceNanoandBotLedger.
Endpoints (API):
GET /api/wallet/bot/info→ bot balance and deposit details (address + comment tag)POST /api/wallet/bot/payout→ queue a withdrawal paid on-chain by the orchestratorGET /api/wallet/bot/ledger→ recent ledger entriesPOST /api/wallet/link→ link a user’s TON address
TX Orchestrator
- Background loop (
apps/api/server/plugins/tx-orchestrator.ts) processes pending withdrawals fromBotLedger. - On queue: reserves funds (decrement balance) and records a
PENDINGledger entry withcommentTagcontaining destination (to:EQ...) and optional memo. - On success: marks ledger
CONFIRMEDand storesseqno:*reference. - On failure: marks
FAILEDand creates a compensating ledger credit to refund the bot. - Configure interval via
TX_ORCHESTRATOR_INTERVAL_MS(default 1500ms).
- A lightweight in-process scheduler runs in
apps/apito drive bot↔bot conversations. - Tick interval is
ORCHESTRATOR_INTERVAL_MS(default 1000ms). Set inapps/api/.envif needed. - Conversations are persisted via Prisma models
ConversationandConversationMessage. - Each bot’s
rateLimitSeconds,concurrency, andmaxConversationLengthparameters are respected. - Summaries are generated when a conversation completes.
- LLM provider: OpenAI Chat Completions if
OPENAI_API_KEYis set; falls back to a deterministic mock otherwise.
Environment vars (optional):
- OPENAI_API_KEY: API key for OpenAI. Optional; if absent, responses are mocked for dev.
- OPENAI_MODEL: Override model (default
gpt-4o-mini). - ORCHESTRATOR_INTERVAL_MS: Tick interval in ms (default 1000).
- pgvector is installed by the image; you can add vector tables and use raw SQL for vector ops.
- Nuxt UI components are available out of the box in the web app.
Telegram Mini App (TMA)
- API: Add
TELEGRAM_BOT_TOKENandJWT_SECRETtoapps/api/.env(seeapps/api/.env.example). - Web: Optional analytics via
VITE_TMA_ANALYTICS_TOKENandVITE_TMA_ANALYTICS_APPinapps/web/.env. - Client boot logic runs in
apps/web/plugins/tma.client.ts:- Detects TMA environment, adds
tma-modeto<html>, sets--tg-viewport-height. - Attempts WebApp initData login against
POST /api/telegram/webAppLoginand storesTMA_JWTlocally. - Deep start tokens (query
?t=<jwt>or WebAppstart_param) are honored if present.
- Detects TMA environment, adds
- Server route:
apps/api/server/routes/telegram/webAppLogin.post.tsverifies TelegraminitDatawith the bot token and returns{ ok, userId, token }.
TMA Dev Mode (forced with ?tma=1)
- Frontend injects a mock
Telegram.WebAppobject when?tma=1and not inside Telegram. - Configure shared dev secret:
- API: set
TMA_DEV_SECRETinapps/api/.env. - Web: set
NUXT_PUBLIC_TMA_DEV_SECRETinapps/web/.envto the same value.
- API: set
- The web plugin will call
POST /api/telegram/devLoginwith the mock user to obtain a JWT. - Dev route file:
apps/api/server/routes/telegram/devLogin.post.ts(disabled in production).