A Bitcoin-powered AI chat API that uses Cashu ecash tokens for payments and publishes model configurations via Nostr relays. Users can interact with various AI models by paying with Bitcoin through Cashu tokens, with automatic refunds for unused credits.
- Pay-per-use AI Chat: Interactive chat with multiple AI models (OpenAI, Anthropic, etc.)
- Bitcoin Payments: Seamless payments using Cashu ecash tokens
- Automatic Refunds: Unused credits are automatically refunded as Cashu tokens
- Model Discovery: Real-time model configurations published via Nostr
- Multi-Provider Support: Supports OpenRouter for access to various AI providers
- Observability: Built-in OpenTelemetry tracing with Uptrace integration
- Persistent Wallet: SQLite-backed Cashu wallet with transaction history
- CashuWalletManager: Handles Cashu token validation, wallet operations, and refunds
- ModelConfigService: Subscribes to Nostr for real-time model pricing and availability
- NDKService: Manages Nostr connections for publishing and subscribing to events
- AIProvider: Interfaces with OpenRouter for AI model access
- Client estimates cost and deposits Cashu tokens via
X-Cashuheader - Server validates tokens and processes the chat request
- Actual usage is calculated and excess funds are refunded as new Cashu tokens
- All transactions are recorded in the local SQLite database
- Node.js 22.14.0 or higher
- Docker (optional, for containerized deployment)
- OpenRouter API key
- Nostr private keys for admin and publisher operations
- Bitcoin/Cashu mint access
- Clone and install dependencies:
git clone <repository-url>
cd cypherflow-api
npm install- Configure environment variables:
cp .env.example .env
# Edit .env with your configurationRequired environment variables:
# OpenRouter API configuration
OPENROUTER_API_KEY=your_openrouter_api_key
# Nostr keys (hex format, 64 characters each)
NOSTR_ADMIN_PRIVATE_KEY=your_admin_private_key_hex
NOSTR_PUBLISHER_PRIVATE_KEY=your_publisher_private_key_hex
# Nostr relay URLs (comma-separated)
NOSTR_RELAYS=wss://relay1.com,wss://relay2.com
# Optional: OpenTelemetry tracing
OTEL_ENABLED=true
UPTRACE_DSN=your_uptrace_dsn# Start development server with hot reload
npm run dev
# Run linting
npm run lint
# Format code
npm run format# Build the application
npm run build
# Start production server
npm start# Build Docker image
docker build -t cypherflow-ai .
# Run container
docker run -d \
-p 3000:3000 \
-v cypherflow-data:/app/data \
--env-file .env \
cypherflow-ai# Development
npm run check-balance:dev
# Production
npm run check-balance# Development
npx tsx src/scripts/withdrawl.ts 1000 # Withdraw 1000 sats
# Production
npm run withdrawl 1000# Publish OpenRouter model details to Nostr
npm run model-details:dev # Development
npm run model-details # Production# Publish current BTC price to Nostr
npm run btc-price:dev # Development
npm run btc-price # ProductionGET /healthReturns service status:
{
"status": "ok",
"ndkReady": true,
"modelsLoaded": true,
"walletReady": true,
"telemetryEnabled": true
}POST /api/chatHeaders:
X-Cashu: Cashu token for paymentContent-Type: application/json
Request body:
{
"modelId": "gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "Hello, how are you?"
}
]
}Response: Streaming chat completion with payment metadata in the final message annotation.
The application uses SQLite with two main tables:
CREATE TABLE proofs (
id TEXT PRIMARY KEY,
amount INTEGER NOT NULL,
secret TEXT NOT NULL,
C TEXT NOT NULL,
keyset_id TEXT NOT NULL,
spent BOOLEAN DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE transactions (
id TEXT PRIMARY KEY,
type TEXT NOT NULL,
amount INTEGER NOT NULL,
model_id TEXT,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);The service publishes two types of events to Nostr:
- d-tag:
cypherflow-ai-models-config - Content: JSON with model pricing and capabilities
- Purpose: Real-time model discovery for clients
- d-tag:
cypherflow-ai-bitcoin-price-feed - Content: Current BTC/USD price
- Purpose: Price reference for cost calculations
Edit AUTHORIZED_MODEL_IDS in src/scripts/publishOpenRouterLLMDetails.ts to control which models are available:
const AUTHORIZED_MODEL_IDS = [
"openai/gpt-4o-mini",
"anthropic/claude-3.5-sonnet",
// Add more model IDs
];Set AI_MODELS_PROFIT_MARGIN in your environment:
2.0= 100% markup (default)1.5= 50% markup1.2= 20% markup
Configure mints in src/services/cashuWalletManager.ts:
private mints = [
"https://mint.cypherflow.ai",
"https://mint.example.com"
];Enable distributed tracing with Uptrace:
OTEL_ENABLED=true
UPTRACE_DSN=https://your-token@api.uptrace.dev/project-idAll requests are logged with:
- HTTP method and URL
- Payment validation status
- Token usage and costs
- Refund calculations
Monitor service health via the /health endpoint for:
- NDK connection status
- Model configuration readiness
- Wallet service availability
- Telemetry status
- Private Key Management: Store Nostr private keys securely
- API Key Security: Protect OpenRouter API keys
- Token Validation: All Cashu tokens are cryptographically verified
- Error Handling: Sensitive information is not exposed in error messages
The API returns structured error responses:
{
"error": "Insufficient deposit. Required: 150 sats, received: 100 sats",
"status": "payment_required"
}Common error codes:
400: Bad Request (invalid model, malformed request)402: Payment Required (insufficient or invalid deposit)503: Service Unavailable (services not ready)
- Fork the repository
- Create a feature branch
- Follow the existing code style (use
npm run lintandnpm run format) - Add tests for new functionality
- Submit a pull request
MIT License - see LICENSE file for details.
For issues and questions:
- Check the health endpoint for service status
- Review application logs for error details
- Verify environment configuration
- Check Nostr relay connectivity
- Validate Cashu mint accessibility
Note: This service handles real Bitcoin transactions. Always test thoroughly in development environments before deploying to production.