This repository contains the Three Cauldron (previously "Spooky Games") web platform: a small collection of self-contained, demo-style React games and a lightweight front-end that showcases them. It also includes some development tooling and helper pieces for integrating with Soroban contracts on the Stellar testnet.
The tone of this README is intentionally concise and practical — what you need to run, test, and iterate on the project without any fluff.
public/games/— each game is a small Vite+React app inside its own folder. Games ship adist/build and a simpleindex.htmlfor embedding as demos.src/— the main platform UI (React + Vite) that loads the games manifest and renders the landing page + debug utilities.contracts/— contract source and build artifacts (Rust / Cargo) used for Soroban development. These are large and ignored in the repo index.tests/— Playwright end-to-end tests verifying key pages and game launches.- Utility scripts and flavors: small helpers, a WebSocket server for
piano-flight, and theBuyMTKdebug component.
- Framework: React (Vite)
- Styling: Tailwind CSS
- E2E: Playwright
- Soroban / Stellar:
@stellar/stellar-sdk(Contract, rpc, TransactionBuilder) and@stellar/freighter-apifor Freighter integration - Node: some games and the piano-flight server use small Node scripts (e.g.,
public/games/piano-flight/server.js)
- Node.js (18+ recommended)
- npm or yarn
- A modern browser with Freighter installed for Soroban interactions (if you plan to trigger transactions)
- Install top-level dependencies (the platform itself):
cd c:\stellar-gaming-platform\spooky-games
npm install- Start the Vite dev server for the platform UI (serves the app that lists/embeds games):
npm run dev
# or
npx viteThe platform expects games to be available under public/games/<name>/index.html or a dist build inside each game folder. See the per-game section below for game-specific dev/build steps.
Each game in public/games/<game-name> is a standalone Vite app. Typical workflow inside a game folder:
cd public/games/spooky-poker
npm install
npm run dev # run dev server for that game
npm run build # produce dist/ for embedding in the main siteAfter building, the platform will often link to the game's dist/index.html for demoing.
Playwright is configured to exercise the landing page and games. Run tests from repo root:
npx playwright install
npx playwright testTests run against the dev server, so start npm run dev in a separate shell before running Playwright.
-
The project includes example integration points that call Soroban contracts via
@stellar/stellar-sdkand rely on Freighter for signing (theBuyMTKdebug component and the poker game's transfer flow). -
IMPORTANT: Contract identifiers are hard-coded placeholders in a few files. Example:
public/games/spooky-poker/App.jsx— look forCONTRACT_IDandESCROW_ADDRESSconstants near the top of the file.src/components/BuyMTK.jsx— similarCONTRACT_IDusage.
-
If you plan to interact with real testnet contracts:
- Deploy your contract to Soroban testnet and note the contract id.
- Replace the
CONTRACT_IDconstant in the files above. - Use Freighter in your browser to sign transactions (the code expects Freighter-style sign results; different Freighter versions vary slightly — see code comments and logs if you see XDR/SCVal errors).
For the piano-flight demo there is a small Node WebSocket server at public/games/piano-flight/server.js. To run it locally:
cd public/games/piano-flight
npm install
node server.js
# server listens on ws://localhost:3000 by default (see file for config)Large artifacts (Rust target/, per-game dist/ builds, and node_modules) are excluded from Git via .gitignore. The initial import removed build artifacts from the index so the repository is clean and pushable.
If you see very large files in history and want them purged, I can help with a history rewrite (BFG or git filter-repo) — it rewrites history and requires a force-push.
- Keep game folders self-contained. Use
base: './'in each game'svite.config.jsso builds are portable insidepublic/games/<name>/dist. - When adding a new game:
- Create
public/games/<your-game>as a Vite app. - Ensure
index.htmland built artifacts are relative-path friendly (base: './'). - Optionally update
public/games/games-manifest.jsonif you want the platform to list the demo.
- Create
- A minimal GitHub Actions workflow that installs Node and runs the Playwright smoke tests is a nice next step.
- If you want a clean, smaller repo on GitHub we can remove large committed artifacts from history. I can help do that safely.
If anything in this README is unclear or you want help wiring a contract or CI, open an issue or ping the maintainers. We can add a CONTRIBUTING.md and code owners if you'd like a formal process.
This README is intentionally brief and operational — it focuses on how to run and work with the project. If you want a more narrative README (screenshots, architecture diagrams, or a developer onboarding checklist) tell me what you'd like and I will add it.
A Halloween-themed Web3 gaming platform powered by Stellar blockchain and Soroban smart contracts.
- Halloween Theme: Dark, spooky UI with orange/purple color scheme and animations
- Freighter Wallet Integration: Connect your Stellar wallet securely
- Username NFT System: Claim and manage unique on-chain usernames
- Modular Game System: Easy-to-add HTML games with automatic integration
- Clean Architecture: Modern React with latest Stellar SDK v12
- Production Ready: Built with Vite for optimal performance
We've made it super easy to add HTML-based games to the platform!
- Add your game folder:
public/games/your-game-name/index.html - Register in manifest: Add entry to
public/games/games-manifest.json - Done! Your game appears automatically
# Interactive game addition
node add-game.js
# or
.\add-game.ps1📖 Full Guide: See ADDING-GAMES.md for complete instructions and examples!
# Install dependencies
npm install
# Start development server
npm run dev
# Open browser to http://localhost:5173- Install Freighter Wallet (freighter.app)
- Switch to Testnet in Freighter settings
- Fund account at Stellar Laboratory Friendbot
- Open http://localhost:5174
- Click "Connect Wallet"
- Approve in Freighter popup
- Verify address shows in header (e.g., "GABC...XYZ")
- Click wallet address dropdown
- Click edit icon (pencil)
- Enter username: "SpookyGamer" (3-20 chars)
- Click save (checkmark)
- Approve transaction in Freighter
- Wait for "✅ Username saved successfully!"
- Verify "✓ NFT" badge appears
- Refresh page (F5)
- App auto-reconnects to wallet
- Open account dropdown
- Verify username still displays
- Click edit icon
- Change username to "GhostHunter"
- Save and approve transaction
- Verify username updates
- Click "Disconnect" button
- Verify "Connect Wallet" button returns
- Verify username state clears
Press F12 → Console. Look for:
✅ Wallet connected: GABC...XYZ
ℹ️ Username loaded: SpookyGamer
✅ Username claimed successfully
❌ No red errors should appear
- Orange skull logo with glow
- Gradient buttons (orange→purple)
- Animated floating skulls 💀
- Feature cards hover with glow
- Status messages slide from right
- Responsive layout on mobile
| Category | Technology | Version |
|---|---|---|
| Frontend | React | 19.0.0 |
| Build | Vite | 7.1.12 |
| Blockchain | Stellar SDK | 12.3.0 |
| Wallet | Freighter API | 5.0.0 |
| Icons | Lucide React | Latest |
| Animations | GSAP | Latest |
Our smart contract has a variety of functions to move our tokens and XLMs for game winnings and losses.
We have an in-game currency called MTK. An user starts with a certain amount. They can burn XLMs from their wallet to buy MTKs to play games, like arcade tokens. They win or losr more depending on their game outcomes. MTKs are transferred between users in the games. The user can redeem their MTKs for XLMs anytime.
- After the user has connected a wallet ID to the system using Freighter, they can add a username
- Username tied to Wallet ID through a separate NFT contract system
- Names are unique to each user, wallet-based, stored on chain, acts as an 'alias'
spooky-games/
├── src/
│ ├── App.jsx # Main UI component
│ ├── App.css # Halloween theme
│ ├── stellar-sdk.js # Blockchain integration
│ ├── main.jsx # Entry point
│ └── index.css # Global styles
├── public/ # Static assets
├── package.json # Dependencies
└── vite.config.js # Build config
--orange: #ff6b35 /* Primary accent */
--purple: #6a0dad /* Secondary accent */
--bg-dark: #0a0a0a /* Background */
--bg-card: #1a1a1a /* Cards */
--success: #00ff88 /* Success */
--error: #ff4444 /* Error */| Issue | Solution |
|---|---|
| "Wallet not connected" | Install Freighter, unlock wallet, switch to Testnet |
| Transaction fails | Fund account with 2+ XLM from Friendbot |
| "Loading username..." stuck | Check network, verify RPC URL accessible |
| Build errors | rm -rf node_modules && npm install |
Copy transaction hash from console → Visit:
https://stellar.expert/explorer/testnet/tx/[HASH]
- ✅ Testnet only (no real funds)
- ✅ Freighter manages private keys
- ✅ Review all transactions before signing
- ✅ Official Stellar RPC endpoint
# Production build
npm run build
# Deploy to Vercel
vercel --prod
# Deploy to Netlify
# Drag & drop dist/ folder// ✅ Correct
const tx = new TransactionBuilder(...).build();
const sim = await server.simulateTransaction(tx);
const prepared = assembleTransaction(tx, sim);
// ❌ Wrong (old SDK v11)
const prepared = assembleTransaction(tx, sim).build();- Create component in
src/components/ - Import in
App.jsx - Add styles to
App.css - Test with
npm run dev - Build with
npm run build
- Desktop: Full layout
- Tablet: Optimized grid
- Mobile: Single column
MIT - Free to use for your projects!
🎃 Built with 💀 and ✨ on Stellar 🎃