Architecture Overview¶
This document describes the high-level architecture of Routstr Core, helping contributors understand how the system works.
System Overview¶
Routstr Core is a FastAPI-based reverse proxy that adds Bitcoin micropayments to OpenAI-compatible APIs and can optionally announce providers via Nostr.
graph TB
subgraph "External Services"
Client[API Client]
Mint[Cashu Mint]
Provider[AI Provider]
Nostr[Nostr Relays]
end
subgraph "Routstr Core"
API[FastAPI Server]
Auth[Auth Module]
Payment[Payment Module]
Proxy[Proxy Module]
DB[(SQLModel DB)]
API --> Auth
Auth --> Payment
Auth --> DB
Payment --> Proxy
Proxy --> Provider
Payment --> Mint
API --> Nostr
end
Client --> API
Core Components¶
FastAPI Application¶
The main application is initialized in routstr/core/main.py:
- Lifespan Management: Runs migrations, initializes DB, refreshes pricing/models, starts background tasks
- Middleware: CORS and request logging
- Routers: Admin, pricing/models, balance/wallet, providers discovery, proxy
- Background Tasks: Price refresh, model map refresh, payouts, node announcements, provider discovery refresh
Authentication System¶
Located in routstr/auth.py, handles:
- API Key Validation: SHA-256 hashed key lookup and persistence
- Balance Checking: Ensures sufficient funds before requests
- Token Redemption: Converts Cashu tokens to balance
Payment Processing¶
The routstr/payment/ module manages:
- Cost Calculation: Token-based or fixed pricing
- Model Pricing: Derived from upstream providers and DB overrides
- Currency Conversion: BTC/USD price refresh and conversion
- Fee Application: Provider fee applied to upstream model pricing
Request Proxying¶
routstr/proxy.py handles:
- Request Forwarding: Forwards requests to selected upstream providers
- Response Streaming: Streaming and non-streaming paths
- Usage Tracking: Adjusts costs after upstream responses
- Error Handling: Maps upstream errors to consistent responses
Database Layer¶
Using SQLModel in routstr/core/db.py:
# Core tables
ApiKey:
- hashed_key: Primary key (SHA-256 of key or Cashu token)
- balance: Current balance (msats)
- reserved_balance: Reserved balance (msats)
- refund_address: Optional LNURL for refunds
- key_expiry_time: Optional refund expiry timestamp
- total_spent: Total spent (msats)
- total_requests: Request count
- refund_mint_url: Mint URL for refunds
- refund_currency: Refund currency
UpstreamProviderRow:
- id: Primary key
- provider_type: openai/anthropic/azure/openrouter/etc.
- base_url: Provider API base URL
- api_key: Provider API key
- api_version: Optional API version
- enabled: Provider enabled flag
- provider_fee: Provider fee multiplier
ModelRow:
- id: Model ID
- upstream_provider_id: Provider foreign key
- name: Model name
- architecture: JSON
- pricing: JSON
- sats_pricing: JSON
- per_request_limits: JSON
- top_provider: JSON
- canonical_slug: Canonical model slug
- alias_ids: Model aliases
- enabled: Model enabled flag
LightningInvoice:
- id: Primary key
- bolt11: Invoice
- amount_sats: Amount in sats
- payment_hash: Payment hash
- status: pending/paid/expired/cancelled
- api_key_hash: Optional associated API key
- purpose: create/topup
- created_at: Unix timestamp
- expires_at: Unix timestamp
- paid_at: Unix timestamp
Request Flow¶
Standard API Request¶
sequenceDiagram
participant C as Client
participant R as Routstr
participant D as Database
participant P as AI Provider
C->>R: API Request + Key
R->>D: Validate Key
D-->>R: Key Info + Balance
R->>R: Reserve Max Cost
R->>P: Forward Request
P-->>R: AI Response
R->>D: Finalize Cost (adjust by usage)
R-->>C: Return Response
Payment Flow¶
sequenceDiagram
participant C as Client
participant R as Routstr
participant W as Wallet Module
participant M as Cashu Mint
participant D as Database
C->>R: Request + Cashu Token
R->>W: Redeem Token
W->>M: Verify with Mint
M-->>W: Token Valid
W-->>R: Token Amount
R->>D: Create/Update Key + Balance
R-->>C: Continue Request
Key Design Decisions¶
1. Async Architecture¶
The system is async end-to-end, with background tasks for pricing refresh, provider discovery, model map refresh, and payouts.
2. Modular Design¶
Components are loosely coupled:
- Routers: Separate files for different endpoints
- Dependencies: Injected via FastAPI's DI system
- Models: Shared data structures
- Services: Business logic separated from routes
3. Error Handling¶
Exceptions are handled by FastAPI exception handlers to return consistent JSON responses with a request ID.
4. Database Migrations¶
Alembic migrations are run on startup, and tables are created for any models not tracked by migrations.
Security Architecture¶
API Key Security¶
- Storage: SHA-256 hashed keys
- Generation: Cryptographically secure random (when creating new keys)
- Validation: Hash lookup in DB
- Expiry: Optional refund flow via
key_expiry_timeandrefund_address
Payment Security¶
- Token Validation: Cashu token redemption via mint
- Balance Protection: Atomic updates and reserved balance tracking
- Audit Trail: Structured logging of payments and adjustments
Network Security¶
- CORS: Configurable origins
- Input Validation: Pydantic models
Performance Considerations¶
Caching Strategy¶
Model and provider selections are cached in process memory and refreshed on a schedule.
Database Optimization¶
- Async I/O: Non-blocking queries
- Atomic Updates: Balance reservation and finalization updates
Streaming Responses¶
Streaming responses are forwarded from upstream providers with usage tracking hooks.
Extension Points¶
Adding New Endpoints¶
- Create router module
- Define Pydantic models
- Implement business logic
- Register with main app
- Add tests
Custom Pricing Models¶
- Extend
ModelPriceclass - Implement calculation logic
- Add to pricing registry
- Update configuration
Payment Methods¶
- Create payment handler
- Implement validation
- Add to payment router
- Update balance logic
Testing Strategy¶
Unit Tests¶
- Mock external dependencies
- Test business logic in isolation
Integration Tests¶
- Test component interactions
- Use test database
- Mock external services
- Verify end-to-end flows
Performance Tests¶
- Response time benchmarks (as needed)
Monitoring and Observability¶
Structured Logging¶
logger.info("api_request", extra={
"request_id": request_id,
"api_key": api_key_id,
"endpoint": endpoint,
"model": model,
"tokens": token_count,
"cost_sats": cost,
"duration_ms": duration
})
Metrics Collection¶
Structured logs are emitted for requests, pricing, and payment events.
Health Checks¶
Use /v1/info for basic service metadata and configuration visibility.
Deployment Architecture¶
Container Structure¶
See core/Dockerfile for the current container build configuration.
Environment Configuration¶
- Development: Local SQLite, debug logging
- Testing: In-memory database, mock services
- Production: Persistent storage, structured logs
Scaling Considerations¶
- Horizontal: Multiple instances behind a load balancer
- Vertical: Async handles high concurrency
- Database: Configure
DATABASE_URLfor external databases
Future Architecture¶
Planned Improvements¶
- WebSocket Support: Real-time balance updates
- Plugin System: Extensible pricing/auth
- Multi-Region: Geographic distribution
- Event Sourcing: Complete audit trail
Technical Debt¶
Areas for improvement:
- Database query optimization
- Response caching layer
- Metric aggregation
- API versioning strategy
Next Steps¶
- Review Code Structure for detailed organization
- See Testing Guide for test architecture