A collaborative pixel canvas NFT governance platform built on Nervos CKB blockchain
SoMo is a pixel canvas where users mint individual pixels as NFTs using the Spore Protocol. Each pixel serves as an access pass to governance tokens, creating a unique blockchain-based social experiment in collective ownership and decision-making.
- 50x50 Pixel Canvas: Interactive "Eternal Land" grid with tiered pricing based on location
- NFT Minting: Each pixel is a unique Spore Protocol DOB/0 NFT with embedded traits
- Governance System: Original minters earn governance points towards a 350M token airdrop
- Multi-Wallet Support: Compatible with JoyID, MetaMask, and UTXOGlobal wallets
- Real-time Updates: WebSocket integration for live canvas synchronization
- Mobile-First Design: Optimized dark-themed UI for all devices
- Referral System: Earn rewards for bringing new participants
- Admin Dashboard: Management tools for cluster operations and monitoring
- React 18 with TypeScript
- Vite for fast development and building
- TailwindCSS + Shadcn/ui for styling
- TanStack React Query for state management
- Wouter for routing
- Node.js with Express
- PostgreSQL database via Drizzle ORM
- WebSocket server for real-time features
- Rate limiting and security middleware
- Nervos CKB (Layer 1 blockchain)
- Spore Protocol for NFT standard
- CCC SDK (@ckb-ccc/core) for blockchain interactions
- DOB/0 encoding for pixel metadata
Before you begin, ensure you have:
- Node.js 18 or higher
- npm or pnpm package manager
- PostgreSQL 14 or higher
- A Nervos CKB wallet (JoyID, MetaMask, or UTXOGlobal)
git clone <your-repo-url>
cd somonpm installdocker run -d \
--name somo-postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=somo_db \
-p 5432:5432 \
postgres:14Ensure PostgreSQL is running and create a database:
createdb somo_dbCreate a .env file in the root directory:
cp .env.example .envEdit .env with your configuration:
# Database Connection
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/somo_db
# Server Configuration
NODE_ENV=development
PORT=5000
# Admin Wallet (replace with your CKB address)
ADMIN_WALLET_ADDRESS=ckt1qrfrwcdnvssswdwpn3s9v8fp87emat306ctjwsm3nmlkjg8qyza2cqgqq...
# Production Frontend URL (for CORS)
# FRONTEND_URL=https://yourdomain.comnpm run db:pushThis will create all necessary tables. The application will automatically initialize the 50x50 pixel canvas on first startup.
npm run devThe application will start on http://localhost:5000
# Build the frontend
npm run build
# Start the server
npm run startnpm run db:pushnpm run db:generatenpm run db:push --force- Connect Wallet: Click "Connect Wallet" and choose your preferred wallet provider
- Mint a Pixel: Select an available pixel on the canvas and mint it as an NFT
- Earn Governance: Original minters receive governance points based on pixel tier and location
- Transfer/Melt: Manage your pixels through the "My Pixels" page
- Admin Access: The wallet address specified in
ADMIN_WALLET_ADDRESShas admin privileges - Dashboard: Access admin features through the hamburger menu
- Cluster Management: Create and manage Spore clusters for pixel minting
- Monitoring: View statistics, user activity, and feedback
somo/
โโโ client/ # Frontend React application
โ โโโ src/
โ โ โโโ components/ # Reusable UI components
โ โ โโโ pages/ # Page components
โ โ โโโ hooks/ # Custom React hooks
โ โ โโโ lib/ # Blockchain and utility functions
โ โ โโโ contexts/ # React contexts (WebSocket, etc.)
โ โโโ index.html
โโโ server/ # Backend Express application
โ โโโ features/ # Feature-based API modules
โ โ โโโ pixels/ # Pixel management
โ โ โโโ users/ # User operations
โ โ โโโ governance/ # Governance points
โ โ โโโ ...
โ โโโ db.ts # Database connection
โ โโโ config.ts # Server configuration
โ โโโ index.ts # Entry point
โโโ shared/ # Shared code between frontend/backend
โ โโโ schema.ts # Database schema (Drizzle)
โ โโโ canvas-utils.ts # Canvas utilities
โ โโโ constants.ts # Shared constants
โโโ package.json
โโโ vite.config.ts
โโโ tailwind.config.ts
โโโ drizzle.config.ts
SoMo implements multiple security layers:
- Rate Limiting: API and operation-specific limits
- CORS Protection: Configured allowed origins
- Input Validation: Zod schema validation on all inputs
- WebSocket Limits: Connection caps per IP
- Database Constraints: Unique constraints and partial indexes
- BigInt Arithmetic: Safe large number calculations
- Admin Authentication: Wallet signature verification
Ensure these are set in your production environment:
NODE_ENV=production
DATABASE_URL=<your-production-database-url>
ADMIN_WALLET_ADDRESS=<your-admin-ckb-address>
FRONTEND_URL=https://yourdomain.com
PORT=5000- Vercel: Frontend deployment (build output:
dist/public) - Railway: Full-stack deployment with PostgreSQL
- Render: Combined frontend + backend with managed database
- DigitalOcean: VPS deployment with Docker
npm run buildnpm run startPixels are priced based on Manhattan distance from center:
| Tier | Distance | Price (CKB) |
|---|---|---|
| S | 0-5 | 5,000 |
| A | 6-10 | 1,500 |
| B | 11-15 | 800 |
| C | 16-20 | 400 |
| D | 21+ | 200 |
Points are calculated based on:
- Pixel tier (higher tier = more points)
- Founder status (original minter multiplier)
- Locked CKB amount
- Territorial control bonuses
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
For questions, issues, or feedback:
- reach out on telegram @telmobit
Built with support from the Nervos ecosystem and the Spore Protocol community.
Made with โค๏ธ for the decentralized future