# Deployment Guide

## Prerequisites

1. **Database**: PostgreSQL 14+ with TimescaleDB extension
2. **Node.js**: Version 20 or higher
3. **Docker**: (Optional) For containerized deployment
4. **RPC Access**: Access to RPC endpoints for ChainID 138 and 651940

## Database Setup

1. Ensure PostgreSQL is running with TimescaleDB extension enabled:
```sql
CREATE EXTENSION IF NOT EXISTS timescaledb;
```

2. Run the migration from the explorer database:
```bash
# The migration file is located at:
# ~/projects/explorer-monorepo/backend/database/migrations/0011_token_aggregation_schema.up.sql
```

3. Verify tables were created:
```sql
\dt token_market_data
\dt liquidity_pools
\dt token_ohlcv
```

## Environment Configuration

1. Copy the example environment file:
```bash
cp .env.example .env
```

2. Configure required variables:
```bash
# Required
CHAIN_138_RPC_URL=http://192.168.11.221:8545
CHAIN_651940_RPC_URL=https://mainnet-rpc.alltra.global
DATABASE_URL=postgresql://user:password@localhost:5432/explorer_db

# Optional (for external API enrichment)
COINGECKO_API_KEY=your_key_here
COINMARKETCAP_API_KEY=your_key_here
DEXSCREENER_API_KEY=your_key_here
```

For explorer/LAN deployments, `CHAIN_138_RPC_URL` should point to the public Chain 138 RPC node directly at `http://192.168.11.221:8545`. Use `https://rpc-http-pub.d-bis.org` for external-only consumers. Do not point explorer/read services at the operator core RPC `http://192.168.11.211:8545`.

## Local Deployment

### Using npm

1. Install dependencies:
```bash
npm install
```

2. Build the project:
```bash
npm run build
```

3. Start the service:
```bash
npm start
```

### Using Docker

1. Build the image:
```bash
docker build -t token-aggregation-service .
```

2. Run the container:
```bash
docker run -d \
  --name token-aggregation \
  -p 3000:3000 \
  --env-file .env \
  token-aggregation-service
```

### Using Docker Compose

1. Start all services:
```bash
docker-compose up -d
```

2. View logs:
```bash
docker-compose logs -f token-aggregation
```

## Production Deployment

### Kubernetes

1. Create a ConfigMap for environment variables:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: token-aggregation-config
data:
  CHAIN_138_RPC_URL: "http://192.168.11.221:8545"
  CHAIN_651940_RPC_URL: "https://mainnet-rpc.alltra.global"
  INDEXING_INTERVAL: "5000"
  ENABLE_INDEXER: "true"
  LOG_LEVEL: "info"
```

Set `ENABLE_INDEXER` to `"false"` for public read-only explorer deployments that should serve API traffic without running the in-process multi-chain indexer.

2. Create a Secret for sensitive data:
```yaml
apiVersion: v1
kind: Secret
metadata:
  name: token-aggregation-secrets
type: Opaque
stringData:
  DATABASE_URL: "postgresql://..."
  COINGECKO_API_KEY: "..."
  COINMARKETCAP_API_KEY: "..."
```

3. Deploy the service:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: token-aggregation
spec:
  replicas: 2
  selector:
    matchLabels:
      app: token-aggregation
  template:
    metadata:
      labels:
        app: token-aggregation
    spec:
      containers:
      - name: token-aggregation
        image: token-aggregation-service:latest
        ports:
        - containerPort: 3000
        envFrom:
        - configMapRef:
            name: token-aggregation-config
        - secretRef:
            name: token-aggregation-secrets
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 10
          periodSeconds: 5
```

## DEX Factory Configuration

For ChainID 138, configure DODO PoolManager address:

```bash
CHAIN_138_DODO_POOL_MANAGER=0x...
CHAIN_138_UNISWAP_V2_FACTORY=0x0C30F6e67Ab3667fCc2f5CEA8e274ef1FB920279
CHAIN_138_UNISWAP_V2_ROUTER=0x3019A7fDc76ba7F64F18d78e66842760037ee638
CHAIN_138_UNISWAP_V2_START_BLOCK=4041370
CHAIN_138_SUSHISWAP_FACTORY=0x2871207ff0d56089D70c0134d33f1291B6Fce0BE
CHAIN_138_SUSHISWAP_ROUTER=0xB37b93D38559f53b62ab020A14919f2630a1aE34
CHAIN_138_SUSHISWAP_START_BLOCK=4041495
```

For ChainID 651940, configure DEX factories as they are discovered:

```bash
CHAIN_651940_UNISWAP_V2_FACTORY=0x...
CHAIN_651940_UNISWAP_V2_ROUTER=0x...
CHAIN_651940_UNISWAP_V2_START_BLOCK=0
CHAIN_651940_UNISWAP_V3_FACTORY=0x...
CHAIN_651940_UNISWAP_V3_ROUTER=0x...
CHAIN_651940_UNISWAP_V3_START_BLOCK=0
CHAIN_651940_HYDX_FACTORY=0x...
CHAIN_651940_HYDX_ROUTER=0x...
CHAIN_651940_HYDX_START_BLOCK=0
```

The canonical ALL Mainnet non-DODO inventory is also tracked in the parent repo at `config/allmainnet-non-dodo-protocol-surface.json`.

## Monitoring

### Health Checks

The service exposes a health check endpoint:
```bash
curl http://localhost:3000/health
```

### Logs

View service logs:
```bash
# Docker
docker logs -f token-aggregation

# Kubernetes
kubectl logs -f deployment/token-aggregation
```

### Metrics

Monitor the following:
- Database connection pool usage
- Indexing progress (tokens indexed, pools discovered)
- API request rates
- External API call success rates

## Troubleshooting

### Database Connection Issues

1. Verify database is accessible:
```bash
psql $DATABASE_URL -c "SELECT 1"
```

2. Check connection pool settings in `.env`

### RPC Connection Issues

1. Test RPC endpoints:
```bash
curl -X POST $CHAIN_138_RPC_URL \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
```

2. Verify RPC URLs in `.env`

### Indexing Not Working

1. Check logs for errors
2. Verify DEX factory addresses are configured
3. Ensure RPC endpoints have required APIs enabled (ETH, NET, etc.)

## Scaling

### Horizontal Scaling

The service is stateless and can be scaled horizontally:
- Multiple instances can run simultaneously
- Each instance will index independently
- Database handles concurrent writes

### Vertical Scaling

For high-volume chains:
- Increase `INDEXING_INTERVAL` for less frequent updates
- Increase database connection pool size
- Use read replicas for database queries

## Backup and Recovery

### Database Backups

Regular backups of the following tables:
- `token_market_data`
- `liquidity_pools`
- `token_ohlcv`
- `swap_events`

### Recovery

1. Restore database from backup
2. Restart indexing service
3. Service will backfill missing data automatically
