feat: add CoopCredits Solana media rewards ecosystem

Add complete  token system with Plex/Tautulli/Overseer integration:
- Anchor program for SPL token mint/burn/transfer
- Express backend with OAuth, webhooks, Solana integration
- Next.js frontend with dashboard, admin panel, wallet management
- Docker deployment for 172.20.1.0/24 infrastructure
- Production configs with SSL, Nginx, health monitoring

Tautulli webhooks auto-mint  on watch events.
Overseer integration burns  for content requests.
This commit is contained in:
2026-04-14 11:09:50 -04:00
parent f106328f6a
commit e8d9b1fd42
69 changed files with 11382 additions and 0 deletions
+232
View File
@@ -0,0 +1,232 @@
# CoopCredits Infrastructure Documentation
## Network Architecture
```
┌─────────────────────────────────────────────────────────────────────────┐
│ External Access │
│ coop.hobokenchicken.com │
└─────────────────────────────────┬───────────────────────────────────────┘
│ HTTPS (443)
┌─────────────────────────────────────────────────────────────────────────┐
│ CoopCredits Server │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Nginx │ │ Frontend │ │ Backend │ │ PostgreSQL │ │
│ │ (80/443) │──│ (Next.js) │──│ (Express) │──│ (5432) │ │
│ └──────────────┘ └──────────────┘ └──────┬───────┘ └──────────────┘ │
│ │ │
│ ┌──────────────┐ ┌──────────────┐ │ ┌──────────────┐ │
│ │ Certbot │ │ Redis │◀────────┘ │ Anchor CLI │ │
│ │ (SSL) │ │ (6379) │ │ (Optional) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└──────────────────────────────────┬──────────────────────────────────────┘
│ Local Network (172.20.1.0/24)
┌──────────────────────────┼──────────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Plex │ │ Tautulli │ │ Overseer │
│172.20.1.220 │ │172.20.1.255 │ │172.20.1.225 │
│ :32400 │ │ :8181 │ │ :5055 │
└──────────────┘ └──────────────┘ └──────────────┘
```
## Service Details
### Plex Server (172.20.1.220:32400)
- **Purpose**: Content streaming and user authentication
- **Integration**: OAuth authentication for website login
- **Access**: HTTP on local network, may have remote access enabled
### Tautulli (172.20.1.255:8181)
- **Purpose**: Plex analytics and watch event tracking
- **Integration**: Webhook notifications to CoopCredits backend
- **Access**: HTTP on local network
- **API Key**: Required for backend queries
### Overseer (172.20.1.225:5055)
- **Purpose**: Content request management
- **Integration**: API for requesting content, webhooks for status updates
- **Access**: HTTP on local network
- **API Key**: Required for backend integration
### CoopCredits Server
- **Public Access**: coop.hobokenchicken.com (HTTPS)
- **Internal Services**: Only accessible via Nginx reverse proxy
- **Database**: PostgreSQL on localhost only
- **Cache**: Redis on localhost only
## Communication Flow
### 1. User Authentication
```
User → Nginx → Frontend → Backend → Plex OAuth (172.20.1.220:32400)
User authenticated, JWT issued
```
### 2. Watch Event Processing
```
Plex → Tautulli → Webhook → Nginx → Backend → Solana Devnet
Database updated
WebSocket → User notified
```
### 3. Content Request
```
User → Nginx → Frontend → Backend → Overseer API (172.20.1.225:5055)
Request created, $COOP reserved
Webhook on approval → Burn $COOP
```
## Security Considerations
### Network Security
1. **Local Network**: All services communicate over HTTP (trusted network)
2. **External Access**: Only Nginx exposed (ports 80/443)
3. **Internal Services**: Not accessible from external network
### API Security
1. **Tautulli Webhook**: Secret verification recommended
2. **Overseer API**: API key authentication
3. **Plex OAuth**: Standard OAuth 2.0 flow
4. **JWT**: Secure tokens for session management
### Data Security
1. **Wallet Keys**: Encrypted with AES-256-GCM in database
2. **Database**: Not exposed externally
3. **Redis**: Password protected, localhost only
## Firewall Configuration
```bash
# Web traffic
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Internal service access (from Docker containers)
sudo ufw allow from 172.20.0.0/16 to 172.20.1.0/24
# Block external access to internal services
sudo ufw deny 3000/tcp # Frontend
sudo ufw deny 3001/tcp # Backend
sudo ufw deny 5432/tcp # PostgreSQL
sudo ufw deny 6379/tcp # Redis
```
## Docker Network Configuration
### Internal Network (coop-internal)
- Containers can communicate with each other
- Isolated from external network
- Used for: frontend ↔ backend ↔ database
### External Network (coop-external)
- Allows containers to reach local services
- Subnet: 172.20.2.0/24
- Used for: backend → Tautulli/Overseer/Plex
## SSL/TLS Setup
### Let's Encrypt (Recommended)
```bash
# Initial certificate
docker-compose -f docker-compose.prod.yml run --rm certbot certonly \
--webroot -w /var/www/certbot \
-d coop.hobokenchicken.com \
--agree-tos --no-eff-email
# Auto-renewal (configured in docker-compose)
```
### Self-Signed (Testing only)
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout docker/nginx/ssl/key.pem \
-out docker/nginx/ssl/cert.pem \
-subj '/CN=coop.hobokenchicken.com'
```
## Monitoring and Logging
### Log Locations
- Nginx: `docker/nginx/logs/`
- Backend: Docker logs (`docker-compose logs backend`)
- Frontend: Docker logs (`docker-compose logs frontend`)
- Database: Inside container (`/var/log/postgresql/`)
### Health Checks
```bash
# Backend health
curl https://coop.hobokenchicken.com/health
# Database connection
docker-compose exec postgres pg_isready -U coop
# Service status
docker-compose ps
```
## Troubleshooting
### Cannot reach local services
1. Check Docker network: `docker network inspect coop-credits_coop-external`
2. Verify IP connectivity: `docker exec coop-backend ping 172.20.1.255`
3. Check firewall rules: `sudo ufw status`
### Webhook not received
1. Verify Tautulli can reach CoopCredits:
```bash
curl -X POST https://coop.hobokenchicken.com/webhooks/tautulli \
-H "Content-Type: application/json" \
-d '{"test": true}'
```
2. Check Nginx logs: `tail -f docker/nginx/logs/access.log`
3. Check backend logs: `docker-compose logs -f backend`
### CORS errors
1. Verify CORS_ORIGINS in .env includes your domain
2. Check backend is sending correct headers
3. Nginx should pass through CORS headers
## Performance Optimization
### Nginx Tuning
- `worker_processes auto` - Use all CPU cores
- `worker_connections 1024` - High connection limit
- `gzip on` - Compress responses
- `proxy_cache` - Cache static assets
### Database Tuning
- Connection pooling via Prisma
- Redis for session caching
- Indexed queries on user_id, created_at
### Frontend Optimization
- Next.js static generation where possible
- Image optimization
- Code splitting
## Backup and Recovery
### Database Backup
```bash
# Automated backup script
docker-compose exec -T postgres pg_dump -U coop coop_credits > backup_$(date +%Y%m%d).sql
```
### Wallet Recovery
- Private keys are encrypted in database
- Backup keys stored securely (encrypted)
- Recovery requires encryption key from .env
### Configuration Backup
- `.env` file (contains all secrets)
- `docker/nginx/ssl/` certificates
- `docker-compose.prod.yml` service config
+372
View File
@@ -0,0 +1,372 @@
# CoopCredits Setup for 172.20.1.0/24 Infrastructure
This guide covers setting up CoopCredits with your existing Plex/Tautulli/Overseer infrastructure.
## Prerequisites
- Server running Docker and Docker Compose
- Access to 172.20.1.0/24 network
- API keys from Tautulli and Overseer
- Domain name (coop.hobokenchicken.com) pointing to your server
## Network Overview
```
┌─────────────────────────────────────────────────────────────────┐
│ CoopCredits Server │
│ (Your Server IP) │
│ :443 │
└─────────────────────────────────┬───────────────────────────────┘
│ HTTPS
┌─────────────────────────┼──────────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Plex │ │ Tautulli │ │ Overseer │
│172.20.1.220 │ │172.20.1.255 │ │172.20.1.225 │
│ :32400 │ │ :8181 │ │ :5055 │
└──────────────┘ └──────────────┘ └──────────────┘
```
## Quick Start
### 1. Clone Repository
```bash
cd /opt
git clone <repository> coop-credits
cd coop-credits
```
### 2. Run Infrastructure Setup
```bash
./deployment/setup-infrastructure.sh
```
This script will:
- Test connectivity to your services (Plex, Tautulli, Overseer)
- Generate a secure `.env` file
- Check SSL certificate status
- Output configuration instructions
### 3. Configure Environment
Edit the generated `.env` file:
```bash
nano .env
```
Add your API keys:
```env
# Get from Tautulli: Settings > Web Interface > API
TAUTULLI_API_KEY=your-tautulli-api-key
# Get from Overseer: Settings > General > API Key
OVERSEER_API_KEY=your-overseer-api-key
# Get from https://plex.tv/claim or Plex settings
PLEX_CLIENT_ID=your-plex-client-id
PLEX_CLIENT_SECRET=your-plex-client-secret
```
### 4. Setup Solana
```bash
npm run setup:solana
```
This will:
- Install Solana CLI
- Create a devnet wallet
- Request airdrop
- Output the private key for your `.env` file
Copy the `SOLANA_MINT_AUTHORITY_KEYPAIR` into your `.env` file.
### 5. Deploy Solana Program
```bash
cd anchor-program
anchor build
anchor deploy
```
Update `SOLANA_PROGRAM_ID` in `.env` with the deployed program ID.
### 6. Setup SSL Certificates
#### Option A: Let's Encrypt (Recommended)
```bash
# Obtain certificate
docker-compose -f docker-compose.prod.yml run --rm certbot certonly \
--webroot -w /var/www/certbot \
-d coop.hobokenchicken.com \
--agree-tos --no-eff-email
# Update nginx config to use Let's Encrypt paths
# Edit docker/nginx/nginx.prod.conf:
# ssl_certificate /etc/letsencrypt/live/coop.hobokenchicken.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/coop.hobokenchicken.com/privkey.pem;
```
#### Option B: Existing Certificates
```bash
cp /path/to/your/cert.pem docker/nginx/ssl/cert.pem
cp /path/to/your/key.pem docker/nginx/ssl/key.pem
```
#### Option C: Self-Signed (Testing only)
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout docker/nginx/ssl/key.pem \
-out docker/nginx/ssl/cert.pem \
-subj '/CN=coop.hobokenchicken.com'
```
### 7. Deploy
```bash
./deployment/deploy-production.sh
```
### 8. Configure Tautulli Webhook
1. Open Tautulli: http://172.20.1.255:8181
2. Go to **Settings > Notification Agents**
3. Click **Add a new notification agent > Webhook**
**Configuration:**
- Webhook URL: `https://coop.hobokenchicken.com/webhooks/tautulli`
- Webhook Method: `POST`
- Content Type: `application/json`
**JSON Payload:**
```json
{
"action": "watched",
"user_id": "{user_id}",
"username": "{username}",
"rating_key": "{rating_key}",
"session_key": "{session_key}",
"media_type": "{media_type}",
"title": "{title}",
"grandparent_title": "{grandparent_title}",
"started": "{started}",
"stopped": "{stopped}",
"percent_complete": "{percent_complete}",
"is_new": "{is_new}"
}
```
**Triggers:** Enable **Watched**
### 9. Configure Overseer Webhook
1. Open Overseer: http://172.20.1.225:5055
2. Go to **Settings > Notifications**
3. Enable **Webhook**
**Configuration:**
- Webhook URL: `https://coop.hobokenchicken.com/webhooks/overseer`
- Authorization Header: `Bearer your-webhook-secret-from-env`
**JSON Payload:**
```json
{
"request_id": "{{request.id}}",
"status": "{{request.status}}",
"media_type": "{{media.media_type}}",
"title": "{{media.title}}"
}
```
**Events:** Enable **Request Approved** and **Request Declined**
## Verification
### Test Connectivity
```bash
./deployment/health-check.sh
```
### Watch Mode
```bash
./deployment/health-check.sh --watch
```
### Manual Tests
**Test Tautulli webhook:**
```bash
curl -X POST https://coop.hobokenchicken.com/webhooks/tautulli \
-H "Content-Type: application/json" \
-d '{
"action": "watched",
"user_id": "12345",
"username": "testuser",
"rating_key": "1234",
"session_key": "abc123",
"media_type": "movie",
"title": "Test Movie",
"started": "'$(date +%s)'",
"stopped": "'$(($(date +%s) + 3600))'",
"percent_complete": "90"
}'
```
**Test API:**
```bash
curl https://coop.hobokenchicken.com/api/health
```
## Firewall Configuration
If using UFW:
```bash
# Allow web traffic
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Allow backend to reach local network
sudo ufw allow from 172.20.2.0/16 to 172.20.1.0/24
# Deny direct access to internal services
sudo ufw deny 3000/tcp
sudo ufw deny 3001/tcp
sudo ufw deny 5432/tcp
sudo ufw deny 6379/tcp
# Enable firewall
sudo ufw enable
```
## Troubleshooting
### Cannot reach local services
1. Check Docker network:
```bash
docker network inspect coop-credits_coop-external
```
2. Test connectivity from container:
```bash
docker exec coop-backend ping 172.20.1.255
```
3. Verify firewall rules:
```bash
sudo ufw status verbose
```
### Webhooks not working
1. Check Nginx logs:
```bash
tail -f docker/nginx/logs/access.log
```
2. Check backend logs:
```bash
docker-compose -f docker-compose.prod.yml logs -f backend
```
3. Test webhook manually:
```bash
curl -X POST https://coop.hobokenchicken.com/webhooks/tautulli \
-H "Content-Type: application/json" \
-d '{"test": true}'
```
### Database connection issues
1. Check database status:
```bash
docker-compose -f docker-compose.prod.yml ps postgres
```
2. View database logs:
```bash
docker-compose -f docker-compose.prod.yml logs postgres
```
3. Test connection:
```bash
docker-compose -f docker-compose.prod.yml exec postgres pg_isready -U coop
```
### SSL certificate issues
1. Check certificate:
```bash
openssl s_client -connect coop.hobokenchicken.com:443 -servername coop.hobokenchicken.com
```
2. Verify certificate paths in nginx config
3. Check certificate expiry:
```bash
openssl x509 -in docker/nginx/ssl/cert.pem -noout -dates
```
## Maintenance
### Update Application
```bash
cd /opt/coop-credits
git pull
./deployment/deploy-production.sh
```
### Backup Database
```bash
# Automated backup
docker-compose -f docker-compose.prod.yml exec -T postgres pg_dump -U coop coop_credits > backup_$(date +%Y%m%d).sql
```
### View Logs
```bash
# All services
docker-compose -f docker-compose.prod.yml logs -f
# Specific service
docker-compose -f docker-compose.prod.yml logs -f backend
```
### Restart Services
```bash
docker-compose -f docker-compose.prod.yml restart backend
```
## Security Checklist
- [ ] Changed all default passwords in `.env`
- [ ] SSL certificates installed and valid
- [ ] Firewall rules configured
- [ ] Tautulli webhook secret set
- [ ] Overseer webhook secret set
- [ ] JWT secret is random and secure
- [ ] Database not exposed externally
- [ ] Redis password set
- [ ] Encryption key is random and backed up
- [ ] Solana mint authority key backed up securely
## Support
For issues:
1. Check health: `./deployment/health-check.sh`
2. Review logs: `docker-compose -f docker-compose.prod.yml logs`
3. Check documentation in `docs/INFRASTRUCTURE.md`