Core service for Quadratic Funding donations platform built with NestJS, Prisma, and GraphQL.
- ✅ NestJS modular architecture
- ✅ Prisma ORM with PostgreSQL
- ✅ GraphQL API with Apollo Server
- ✅ Multi-wallet support per user
- ✅ Semantic search with pg_trgm
- ✅ Redis caching and rate limiting
- ✅ AdminJS dashboard
- ✅ Multi-chain EVM support
- ✅ Integration with Blockchain verification service
- ✅ JWT authentication via SIWE
- ✅ Automated donation verification cronjobs
- ✅ Runtime configuration system with Discord bot integration
- Node.js >= 18.x
- Docker and Docker Compose
- pnpm
cd giveth-v6-core
pnpm install# Start PostgreSQL, Redis, and admin tools
docker-compose up -d
# Wait for services to be healthy
docker-compose ps# Generate Prisma client
npm run prisma:generate
# Run migrations
npm run prisma:migrate
# Seed database
npm run prisma:seedCopy .env.example to .env and update the values:
cp .env.example .envKey variables to configure:
DATABASE_URL: PostgreSQL connection stringJWT_SECRET: Secret for JWT tokensBLOCKCHAIN_INTEGRATION_SERVICE_URL: URL for blockchain verification serviceSIWE_AUTH_SERVICE_URL: URL for SIWE authentication serviceNOTIFICATION_CENTER_URL: URL for notification serviceNOTIFICATION_CENTER_USERNAME/NOTIFICATION_CENTER_PASSWORD: basic auth for notification centerPINATA_API_KEY/PINATA_SECRET_KEY: credentials for Pinata uploadsPINATA_GATEWAY: gateway base URL (defaults tohttps://gateway.pinata.cloud)
npm run start:devThe service will be available at:
- API: http://localhost:3000
- GraphQL Playground: http://localhost:3000/graphql
- Admin Dashboard: http://localhost:3000/admin
- Health Check: http://localhost:3000/health
- pgAdmin: http://localhost:5050 (admin@giveth.io / admin)
- Redis Commander: http://localhost:8081
When running docker-compose up -d, the following services are started:
- PostgreSQL:
localhost:5432 - Redis:
localhost:6379 - pgAdmin: http://localhost:5050 (admin@giveth.io / admin)
- Redis Commander: http://localhost:8081
# Development
npm run start:dev # Start with hot reload
npm run start:debug # Start in debug mode
# Build
npm run build # Build for production
npm run start:prod # Run production build
# Database
npm run prisma:generate # Generate Prisma client
npm run prisma:migrate # Run migrations
npm run prisma:studio # Open Prisma Studio
npm run prisma:seed # Seed database
# Code Quality
npm run lint # Run ESLint
npm run format # Format with Prettier
# Testing
npm run test # Run unit tests
npm run test:watch # Run tests in watch mode
npm run test:cov # Run tests with coverage
npm run test:e2e # Run e2e testssrc/
├── modules/ # Domain modules
│ ├── user/ # User management
│ ├── project/ # Project management
│ ├── donation/ # Donation handling
│ ├── qf-round/ # QF round management
│ ├── category/ # Categories
│ └── token/ # Token management
├── common/ # Shared utilities
│ ├── decorators/ # Custom decorators
│ ├── guards/ # Auth guards
│ ├── filters/ # Exception filters
│ ├── pipes/ # Validation pipes
│ └── interceptors/ # Interceptors
├── config/ # Configuration
├── database/ # Prisma and migrations
├── integrations/ # External service clients
└── cronjobs/ # Scheduled tasks
- ORM: Prisma with PostgreSQL
- Read/Write Separation: Automatic routing to read replicas
- Semantic Search: pg_trgm extension for fuzzy text search
- Connection Pooling: Built-in Prisma connection pooling
- Method: Sign-In with Ethereum (SIWE)
- Integration: SiweAuthMicroservice
- Tokens: JWT with configurable expiration
- Multi-wallet: Each user can have multiple wallet addresses
- Layer: Redis
- Strategy: GraphQL query result caching with TTL (projects, donations, users, categories, tokens, QF rounds)
- TTL: 1–60 minutes depending on query type (e.g.
projects3m,categories60m) - Opt-out:
@SkipCache()decorator on resolvers that handle personalized data - Invalidation: Event-based cache invalidation plus TTL fallback
- Blockchain Integration Service: Transaction verification
- SIWE Auth Microservice: Authentication and JWT generation
- Notification Center: Email and push notifications
- Matching Service: QF matching calculations (Python, to be implemented)
To add a new EVM-compatible chain, simply add it to src/config/chains.config.ts:
export const CHAINS: Record<number, ChainConfig> = {
// ... existing chains
// Your new chain
12345: {
id: 12345,
name: 'Your Chain',
nativeCurrency: {
name: 'Token',
symbol: 'TKN',
decimals: 18,
},
rpcUrls: [process.env.YOUR_CHAIN_RPC_URL || 'https://rpc.yourchain.com'],
blockExplorerUrls: ['https://explorer.yourchain.com'],
isTestnet: false,
isActive: true,
},
};This project includes a runtime configuration system that allows you to change operational parameters without code changes or redeployment.
- Store configs in database with caching
- Discord bot for managing configs
- AdminJS interface for viewing/editing
- Type-safe parsing (string, number, boolean, JSON)
- Audit trail (who/when updated)
Add to your .env:
DISCORD_BOT_ENABLED=true
DISCORD_BOT_TOKEN=your_bot_token_here
DISCORD_ALLOWED_ROLE_IDS=admin_role_id_1,admin_role_id_2
DISCORD_ALLOWED_USER_IDS=user_id_1,user_id_2!config help # Show help
!config list core # List all configs for a service
!config get blockchain-integration timeout-seconds # Get a config value
!config set blockchain-integration timeout-seconds 45 # Set a config value
!config delete core test-key # Delete a config
!config refresh blockchain-integration # Refresh cacheFor full documentation, see docs/RUNTIME_CONFIG.md.
This project uses a database-based authentication system for the AdminJS panel, allowing multiple admin users with secure password storage.
# Generate password hash
pnpm admin:generate-password --interactive
# Add admin via Discord
!admin add admin@giveth.io $2b$10$your_hash_here
# Or during seed (for local development)
# Add to .env:
ADMIN_EMAIL=admin@localhost
ADMIN_PASSWORD=DevPassword123!
pnpm prisma:seed!admin help # Show help
!admin list # List all admin users
!admin add admin@giveth.io $2b$10$hash... # Add/update admin user
!admin delete admin@giveth.io # Delete admin userFor full documentation, see:
- Admin Authentication Guide - Complete documentation
- Admin Quick Start - Quick setup guide
- Frontend creates pending donation via GraphQL mutation
- User completes transaction on blockchain
- Frontend calls verify donation mutation with tx hash
- Core service verifies with Blockchain Integration Service
- Donation status updated to "verified"
- Cronjob periodically checks and verifies pending donations
- Admin creates QF round via AdminJS
- Projects are assigned to the round
- Donations during round period are tracked
- Matching calculations provided by Matching Service
- Admin exports results at round end
# Run all tests
npm test
# Run specific test suite
npm test -- user.service.spec.ts
# Run with coverage
npm run test:cov
# E2E tests
npm run test:e2enpm run build
npm run start:prod# Build image
docker build -t qf-donations-core .
# Run container
docker run -p 3000:3000 --env-file .env qf-donations-core- Create feature branch
- Make changes
- Run tests and linting
- Submit pull request
ISC
For issues and questions, please open an issue on GitHub or contact the Giveth team.