Files
CashumintsAPI/README.md
2025-12-19 23:56:07 -03:00

14 KiB

🌿 Cashumints.space API

A production-ready, decentralized observability, discovery, and reputation API for the Cashu mint ecosystem.

Features

  • Mint Discovery - Track and index Cashu mints across the ecosystem
  • Uptime Monitoring - Continuous probing with full historical data
  • Metadata Tracking - NUT-06 compliant metadata with version history
  • Nostr Reviews - NIP-87 based review ingestion from configurable relays
  • Trust Scores - Transparent, explainable reputation scoring (0-100)
  • Analytics - Pageviews, trending mints, and popularity metrics
  • Admin API - Full mint curation and system management
  • OpenAPI Docs - Interactive Swagger UI documentation

Quick Start

# Clone and install
git clone <repo>
cd cashumints-api
npm install

# Configure
cp env.example .env
openssl rand -hex 32  # Generate admin key, add to .env

# Initialize database
npm run migrate

# Start API server
npm start

# View documentation
open http://localhost:3000/docs

Production Deployment

Prerequisites

  • Node.js 18+
  • Nginx (reverse proxy)
  • systemd (process management)
  • Let's Encrypt (SSL)

Installation

# Create user
sudo useradd -r -s /bin/false cashumints

# Clone to /opt
sudo git clone <repo> /opt/cashumints-api
cd /opt/cashumints-api

# Install dependencies
sudo npm install --production

# Configure
sudo cp env.example .env
sudo openssl rand -hex 32  # Add to .env as ADMIN_API_KEY
sudo nano .env

# Create data directory
sudo mkdir -p data
sudo chown cashumints:cashumints data

# Initialize database
sudo -u cashumints npm run migrate

Systemd Services

# Install service files
sudo cp deploy/cashumints-api.service /etc/systemd/system/
sudo cp deploy/cashumints-workers.service /etc/systemd/system/

# Reload and enable
sudo systemctl daemon-reload
sudo systemctl enable cashumints-api cashumints-workers

# Start services
sudo systemctl start cashumints-api
sudo systemctl start cashumints-workers

# Check status
sudo systemctl status cashumints-api
sudo systemctl status cashumints-workers

# View logs
sudo journalctl -u cashumints-api -f
sudo journalctl -u cashumints-workers -f

Nginx Setup

# Install nginx config
sudo cp deploy/nginx.conf /etc/nginx/sites-available/cashumints-api
sudo ln -s /etc/nginx/sites-available/cashumints-api /etc/nginx/sites-enabled/

# Get SSL certificate
sudo certbot --nginx -d api.cashumints.space

# Test and reload
sudo nginx -t
sudo systemctl reload nginx

API Documentation

Interactive API documentation is available at:

  • Swagger UI: http://localhost:3000/docs
  • OpenAPI JSON: http://localhost:3000/openapi.json

API Endpoints

Base URL: /v1

System

Method Endpoint Description
GET /health Health check
GET /stats System statistics
GET /reviews Global reviews feed (filterable)
GET /analytics/uptime Ecosystem uptime analytics
GET /analytics/versions Mint version distribution
GET /analytics/nuts NUT support analytics

Admin (requires X-Admin-Api-Key header)

Method Endpoint Description
POST /admin/mints Manually add a mint
POST /admin/mints/{id}/urls Add URL to mint
POST /admin/mints/merge Merge two mints
POST /admin/mints/split Undo a merge
POST /admin/mints/{id}/disable Hide from listings
POST /admin/mints/{id}/enable Re-enable mint
POST /admin/mints/{id}/metadata/refresh Force metadata fetch
POST /admin/mints/{id}/trust/recompute Force trust recalc
POST /admin/mints/{id}/status/reset Reset stuck state
POST /admin/mints/{id}/probe Force immediate probe
GET /admin/mints/{id}/visibility Get visibility status
GET /admin/jobs View job queue
GET /admin/system/metrics System health
GET /admin/audit Audit log (filter by mint_id)

Admin endpoints also support /admin/mints/by-url?url= variants for all operations.

Mints

Method Endpoint Description
GET /mints List all mints (paginated, filterable)
GET /mints/trending Get trending mints by popularity
GET /mints/{mint_id} Get mint by ID
GET /mints/by-url?url= Get mint by URL
POST /mints/submit Submit new mint for tracking

Mint Details

All endpoints support both /{mint_id} and /by-url?url= variants:

Endpoint Description
/urls All URLs for mint (clearnet, Tor, mirrors)
/metadata NUT-06 metadata
/metadata/history Metadata change history
/status Lightweight current status
/uptime?window=24h|7d|30d Uptime statistics
/uptime/timeseries?window=&bucket= Timeseries for charting
/incidents Downtime incidents
/trust Trust score with breakdown
/reviews Nostr reviews (NIP-87)
/views Pageview statistics
/features Derived features (NUTs, Bolt11, etc.)

Configuration

Copy env.example to .env and configure:

# Server
PORT=3000
HOST=0.0.0.0
NODE_ENV=production

# Admin (REQUIRED - generate with: openssl rand -hex 32)
ADMIN_API_KEY=your-secure-key-here

# Database (SQLite)
DATABASE_PATH=./data/cashumints.db

# Probing
PROBE_TIMEOUT_MS=10000
PROBE_INTERVAL_ONLINE_MS=300000      # 5 minutes
PROBE_INTERVAL_OFFLINE_MS=900000     # 15 minutes
CONSECUTIVE_FAILURES_OFFLINE=3
ABANDONED_AFTER_DAYS=30

# Nostr Relays (comma-separated)
NOSTR_RELAYS=wss://relay.damus.io,wss://relay.nostr.band,wss://nos.lol

# Trust Score Weights (out of 100)
TRUST_WEIGHT_UPTIME=40
TRUST_WEIGHT_SPEED=25
TRUST_WEIGHT_REVIEWS=20
TRUST_WEIGHT_IDENTITY=10
TRUST_PENALTY_MAX=15

# Rate Limiting
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=100

Architecture

┌─────────────────────────────────────────────────────────────┐
│                   Nginx (Reverse Proxy)                     │
│  • SSL termination  • Rate limiting  • Caching              │
└────────────────────────────┬────────────────────────────────┘
                             │
┌────────────────────────────┴────────────────────────────────┐
│                   HTTP API (Express.js)                     │
│  • REST endpoints  • Swagger UI  • Admin API                │
│  • CORS enabled    • Compression  • Helmet security         │
└────────────────────────────┬────────────────────────────────┘
                             │
┌────────────────────────────┴────────────────────────────────┐
│                    SQLite Database                          │
│  mints │ mint_urls │ probes │ metadata │ reviews │ scores   │
│  incidents │ pageviews │ jobs │ uptime_rollups │ audit_log  │
└────────────────────────────┬────────────────────────────────┘
                             │
┌────────────────────────────┴────────────────────────────────┐
│                    Background Workers                       │
│  Probe │ Metadata │ Nostr │ Rollup │ Trust │ Cleanup        │
└─────────────────────────────────────────────────────────────┘

Trust Score

Trust scores (0-100) are computed from:

Component Max Points Based On
Uptime 40 30-day uptime percentage
Speed 25 Average response time (RTT)
Reviews 20 Nostr review quantity & rating
Identity 10 Metadata completeness
Penalties -15 Offline status, incidents, instability

Trust Levels:

  • Excellent: 85-100
  • High: 70-84
  • Medium: 50-69
  • Low: 25-49
  • Unknown: 0-24

Mint Lifecycle

                    ┌─────────────┐
    Discovery ───▶  │   unknown   │
                    └──────┬──────┘
                           │ successful probe
                    ┌──────▼──────┐
                    │   online    │ ◀──────────┐
                    └──────┬──────┘            │
                           │ slow response     │ recovery
                    ┌──────▼──────┐            │
                    │  degraded   │ ───────────┤
                    └──────┬──────┘            │
                           │ consecutive       │
                           │ failures          │
                    ┌──────▼──────┐            │
                    │   offline   │ ───────────┘
                    └──────┬──────┘
                           │ > 30 days
                    ┌──────▼──────┐
                    │  abandoned  │
                    └─────────────┘

Nostr Integration (NIP-87)

The API ingests these event kinds from configured relays:

Kind Description
38172 Cashu mint announcements (self-published by mints)
38173 Fedimint announcements
38000 Recommendations/reviews (with #k tag referencing 38172)

Reviews are parsed for:

  • Mint URL (from u or d tags, with or without protocol)
  • Rating 1-5 (from rating tag or quality tag like "1/1" recommend / "0/1" not recommend)
  • Content (review text)

Admin API

All admin actions are audited. Never deletes raw data.

# Add a mint manually
curl -X POST http://localhost:3000/v1/admin/mints \
  -H "X-Admin-Api-Key: $ADMIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mint_url": "https://mint.example.com", "notes": "Trusted operator"}'

# Get system metrics
curl http://localhost:3000/v1/admin/system/metrics \
  -H "X-Admin-Api-Key: $ADMIN_API_KEY"

# Force trust recalculation
curl -X POST http://localhost:3000/v1/admin/mints/{mint_id}/trust/recompute \
  -H "X-Admin-Api-Key: $ADMIN_API_KEY"

# View audit log
curl http://localhost:3000/v1/admin/audit \
  -H "X-Admin-Api-Key: $ADMIN_API_KEY"

Project Structure

cashumints-api/
├── src/
│   ├── index.js              # Server entry point
│   ├── config.js             # Configuration
│   ├── db/
│   │   ├── connection.js     # Database connection
│   │   ├── migrate.js        # Migration runner
│   │   ├── schema.sql        # Main schema
│   │   └── schema-admin.sql  # Admin schema
│   ├── docs/
│   │   └── openapi.js        # OpenAPI specification
│   ├── middleware/
│   │   ├── adminAuth.js      # Admin authentication
│   │   ├── errorHandler.js   # Error handling
│   │   └── rateLimit.js      # Rate limiting
│   ├── routes/
│   │   ├── admin.js          # Admin endpoints
│   │   ├── mints.js          # Mint endpoints
│   │   └── system.js         # System endpoints
│   ├── services/
│   │   ├── AdminService.js   # Admin operations
│   │   ├── MintService.js    # Mint CRUD
│   │   ├── ProbeService.js   # HTTP probing
│   │   ├── MetadataService.js # NUT-06 metadata
│   │   ├── UptimeService.js  # Uptime rollups
│   │   ├── TrustService.js   # Trust scoring
│   │   ├── ReviewService.js  # Nostr reviews
│   │   ├── PageviewService.js # Analytics
│   │   └── JobService.js     # Background jobs
│   ├── utils/
│   │   ├── url.js            # URL normalization
│   │   ├── crypto.js         # Hashing
│   │   └── time.js           # Time utilities
│   └── workers/
│       ├── index.js          # Combined runner
│       ├── probe.js          # Mint probing
│       ├── metadata.js       # Metadata fetching
│       ├── nostr.js          # Nostr ingestion
│       ├── rollup.js         # Uptime aggregation
│       └── trust.js          # Trust calculation
├── deploy/
│   ├── cashumints-api.service    # API systemd service
│   ├── cashumints-workers.service # Workers systemd service
│   └── nginx.conf                # Nginx configuration
├── data/                     # SQLite database (auto-created)
├── env.example               # Configuration template
├── package.json              # Dependencies
└── README.md                 # This file

Development

# Install dependencies
npm install

# Run in development mode (auto-reload)
npm run dev

# Run specific worker
npm run worker:probe
npm run worker:metadata
npm run worker:nostr
npm run worker:rollup
npm run worker:trust

Design Principles

  1. History is never erased - All raw data is stored and aggregated. Nothing is overwritten.
  2. Offline ≠ dead - Mints transition through states. Recovery is always possible.
  3. URL ≠ identity - Mint identity is stable. Multiple URLs can point to the same mint.
  4. Trust is derived - Every trust signal is computed from stored data with full breakdown.
  5. Self-hostable - SQLite by default. No Redis or external queues required.
  6. Admin transparency - Every admin action is audited. No hidden mutations.

License

MIT