A production-ready microservice for managing Impact Tokens in the TreeTracker ecosystem with Hyperledger Fabric blockchain integration.
- Token Issuance: Automatically issue Impact Tokens when tree captures are verified
- Token Lifecycle Management: Handle token states (basic β mature β traded β redeemed)
- Blockchain Integration: Full Hyperledger Fabric integration for immutable token records
- Wallet Management: Track user token balances and ownership
- Analytics & Reporting: Comprehensive metrics and impact statistics
- RESTful API: Clean, well-documented API endpoints
- Authentication: JWT-based authentication integrated with auth service
- Database: PostgreSQL with optimized schema and triggers
- Caching: Redis for performance optimization
- Production Ready: Docker, Kubernetes, health checks, logging, monitoring
- Node.js 20.x or higher
- PostgreSQL 15+
- Redis 7+
- Docker & Docker Compose (for containerized deployment)
- Kubernetes cluster (for production deployment)
- Access to existing TreeTracker services:
- Auth Service (Port 30001)
- Capture Service (Port 30002)
- Hyperledger Fabric Network
cd /root/greenstand-token
npm installcp .env.example .env
# Edit .env with your configurationKey environment variables:
DB_HOST,DB_PORT,DB_NAME,DB_USER,DB_PASSWORD- PostgreSQL connectionREDIS_HOST,REDIS_PORT- Redis connectionJWT_SECRET- Must match auth service JWT secretAUTH_SERVICE_URL- Auth service endpointCAPTURE_SERVICE_URL- Capture service endpointFABRIC_*- Hyperledger Fabric configuration
# Run migrations
npm run migrate
# Or manually with psql
psql -U postgres -d treetracker_tokens -f src/database/schema.sqlnpm run devThe service will start on http://localhost:3004
npm run build
npm start# Start all services (PostgreSQL, Redis, Token Service)
docker-compose up -d
# View logs
docker-compose logs -f token-service
# Stop services
docker-compose downdocker build -t treetracker-token-service:latest .# Create namespace
kubectl create namespace treetracker
# Apply deployment
kubectl apply -f k8s/deployment.yaml# Edit secrets in k8s/deployment.yaml before applying
# Or use kubectl to create secret
kubectl create secret generic token-service-secret \
--from-literal=DB_PASSWORD=your-password \
--from-literal=JWT_SECRET=your-jwt-secret \
-n treetracker# Check pods
kubectl get pods -n treetracker -l app=treetracker-token-service
# Check logs
kubectl logs -f deployment/treetracker-token-service -n treetracker
# Check service
kubectl get svc -n treetracker treetracker-token-serviceProduction: https://tokens.treetracker.example.com/api
Development: http://localhost:3004/api
All API endpoints require JWT authentication:
Authorization: Bearer <access_token>Get Tokens (Paginated)
GET /api/tokens?page=1&limit=10&state=basicResponse:
{
"success": true,
"data": [
{
"id": "uuid",
"captureId": "capture-001",
"planterId": "user-001",
"treeSpecies": "Mango",
"state": "basic",
"status": "active",
"value": 1.0,
"ecologicalValue": {
"carbonOffset": 15.0,
"waterRetention": 100,
"biodiversityScore": 5.0
},
"issuedDate": "2025-10-24T02:00:00Z",
"blockchainTxId": "tx-12345"
}
],
"pagination": {
"total": 45,
"page": 1,
"pageSize": 10,
"hasMore": true
}
}Get Token by ID
GET /api/tokens/:idIssue New Token
POST /api/tokens
Content-Type: application/json
{
"captureId": "capture-001",
"planterId": "user-001",
"treeSpecies": "Mango",
"carbonOffset": 15.0,
"waterRetention": 100,
"biodiversityScore": 5.0
}Mature Token
POST /api/tokens/:id/matureTransfer Token
POST /api/tokens/transfer
Content-Type: application/json
{
"tokenId": "token-uuid",
"toUserId": "recipient-user-id",
"metadata": {
"reason": "carbon offset purchase"
}
}Get Wallet Balance
GET /api/tokens/wallets/:userId/balanceGet Token Metrics
GET /api/analytics/metricsResponse:
{
"success": true,
"data": {
"totalTokens": 1250,
"totalValue": 1875.50,
"totalCarbonOffset": 18750.0,
"totalWaterRetention": 125000,
"tokensByState": {
"basic": 800,
"mature": 350,
"traded": 80,
"redeemed": 20
},
"averageTokenValue": 1.5,
"issuanceRate": {
"daily": 25,
"weekly": 150,
"monthly": 600
}
}
}Get Impact Statistics
GET /api/analytics/impactGet Dashboard Data
GET /api/analytics/dashboardβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TreeTracker Web App β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Token Microservice (Port 3004) β
β ββββββββββββββ ββββββββββββββ ββββββββββββββ β
β β Token β β Analytics β β Validation β β
β β Service β β Service β β Service β β
β ββββββββββββββ ββββββββββββββ ββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
βΌ βΌ βΌ
ββββββββββββ ββββββββββββ ββββββββββββ
βPostgreSQLβ β Redis β β Fabric β
β β β Cache β β Network β
ββββββββββββ ββββββββββββ ββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β External Services Integration β
β ββββββββββββββββββ ββββββββββββββββββ β
β β Auth Service β βCapture Service β β
β β (Port 30001) β β (Port 30002) β β
β ββββββββββββββββββ ββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The service uses PostgreSQL with the following main tables:
- tokens - Core token data
- transactions - Token transaction history
- wallets - User wallet aggregates
- token_ownership - Current ownership tracking
- token_history - Audit trail
- analytics_cache - Performance optimization
See src/database/schema.sql for complete schema with triggers and views.
- Authentication: JWT tokens validated against auth service
- Authorization: Role-based access control
- Input Validation: All inputs validated with Joi
- Rate Limiting: Configurable request rate limits
- CORS: Configurable allowed origins
- Helmet: Security headers
- SQL Injection: Parameterized queries
- Secrets: Environment variables, never committed
Structured logging with Winston:
- Console: Development mode
- Files:
logs/combined.log,logs/error.log - Format: JSON with timestamps
- Levels: error, warn, info, debug
# Run tests
npm test
# Watch mode
npm run test:watch
# Coverage
npm run test:coveragetreetracker-token-service/
βββ src/
β βββ config/ # Configuration files
β β βββ database.ts # Database connection
β βββ database/ # Database schema and migrations
β β βββ schema.sql
β β βββ migrate.ts
β βββ middleware/ # Express middleware
β β βββ auth.ts # Authentication
β βββ routes/ # API routes
β β βββ tokenRoutes.ts
β β βββ analyticsRoutes.ts
β βββ services/ # Business logic
β β βββ TokenService.ts
β β βββ FabricService.ts
β β βββ AnalyticsService.ts
β βββ types/ # TypeScript types
β β βββ index.ts
β βββ utils/ # Utilities
β β βββ logger.ts
β βββ server.ts # Express server
βββ k8s/ # Kubernetes manifests
βββ .env.example
βββ Dockerfile
βββ docker-compose.yml
βββ package.json
βββ tsconfig.json
# Lint
npm run lint
# Format
npm run formatWhen a tree capture is verified in the capture service:
- Capture service calls
POST /api/tokenswith capture details - Token service issues new Impact Token
- Token recorded in database and blockchain
- Wallet balance updated automatically
- JWT tokens from auth service are validated
- User context extracted from JWT payload
- Roles checked for authorization
Update treetracker-web/lib/api.ts:
// Replace mock endpoint
const TOKEN_SERVICE_URL = process.env.NEXT_PUBLIC_TOKEN_API_URL || 'http://localhost:3004/api';
async getImpactTokens(userId: string, page = 1, limit = 10) {
const response = await this.axiosInstance.get(
`${TOKEN_SERVICE_URL}/tokens?page=${page}&limit=${limit}&planterId=${userId}`
);
return response.data;
}# Test connection
psql -h localhost -U postgres -d treetracker_tokens
# Check logs
tail -f logs/error.log# Verify wallet exists
ls -la wallet/
# Check connection profile
cat connection-profile.json
# Service will continue without Fabric if not configuredCheck logs for:
- Database constraint violations
- Duplicate capture IDs
- Missing required fields
- Fabric transaction errors (non-blocking)
curl http://localhost:3004/healthcurl http://localhost:9090/metrics# Resource usage
kubectl top pods -n treetracker -l app=treetracker-token-service
# Logs
kubectl logs -f deployment/treetracker-token-service -n treetracker --tail=100- 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
MIT License - See LICENSE file for details
For issues and questions:
- Create an issue in the repository
- Contact the TreeTracker team
- Check existing documentation
- Core token management
- Blockchain integration
- Analytics and reporting
- Docker and Kubernetes deployment
- Token marketplace features
- Advanced fraud detection
- Machine learning for token valuation
- Mobile SDK for direct integration
- GraphQL API
- Real-time notifications via WebSocket
Built with π³ for sustainable reforestation
TreeTracker Impact Token Service - Tokenizing environmental impact for a greener future