Professional Express backend service with Redis caching for fetching token prices from the TokenDataStream smart contract.
- 🚀 Express.js REST API
- 💾 Redis caching with configurable TTL
- ⛓️ Blockchain integration via viem
- 🔒 Security middleware (Helmet, CORS)
- 📝 Request logging with Morgan
- ✅ Health check endpoints
- 🎯 TypeScript with strict type checking
- 🏗️ Professional code structure using functions
- Node.js >= 18
- Redis server running
- RPC endpoint for blockchain access
# Install dependencies
npm install
# Copy environment variables
cp .env.example .env
# Edit .env with your configurationEdit .env file with your settings:
PORT=3001
NODE_ENV=development
RPC_URL=https://rpc.testnet.autonomys.xyz
CHAIN_ID=1315
REDIS_HOST=localhost
REDIS_PORT=6379
PRICE_CACHE_TTL=60# Run in development mode with hot reload
npm run dev# Build TypeScript
npm run build
# Start production server
npm startGET /api/healthReturns the health status of Redis and blockchain connections.
GET /api/pricesOptional query parameters:
cache=false- Bypass cache and fetch fresh data
Example response:
{
"success": true,
"data": {
"prices": [
{
"symbol": "IDRX",
"name": "Indonesian Rupiah Token",
"address": "0x056620afe01E33802ce50637438677Dc7b4841E0",
"price": "0.000065",
"priceRaw": "65000000000000",
"decimals": 18,
"updatedAt": 1701234567,
"roundId": "1"
}
],
"timestamp": 1701234567890,
"cached": true
}
}GET /api/prices/:symbolExample:
GET /api/prices/wethPOST /api/prices/refreshForces a refresh of all prices, bypassing the cache.
backend/
├── src/
│ ├── config/ # Configuration files
│ │ ├── abi.ts # Contract ABI
│ │ ├── constants.ts # Contract addresses & metadata
│ │ └── env.ts # Environment variables
│ ├── middleware/ # Express middleware
│ │ └── error.middleware.ts
│ ├── routes/ # API routes
│ │ ├── health.routes.ts
│ │ └── price.routes.ts
│ ├── services/ # Business logic
│ │ ├── blockchain.service.ts
│ │ ├── price.service.ts
│ │ └── redis.service.ts
│ ├── app.ts # Express app setup
│ └── index.ts # Entry point
├── .env.example # Environment template
├── package.json
├── tsconfig.json
└── README.md
The backend follows a layered architecture with clear separation of concerns:
- Routes Layer: Handle HTTP requests and responses
- Service Layer: Business logic and orchestration
- Infrastructure Layer: External service interactions (Redis, Blockchain)
- Redis Service: Manages caching operations
- Blockchain Service: Interacts with smart contracts
- Price Service: Orchestrates price fetching with caching logic
- Token prices are cached in Redis with configurable TTL (default: 60 seconds)
- Cache keys follow the pattern:
price:{symbol} - Cache can be bypassed by adding
?cache=falseto requests - Use
/api/prices/refreshto force a cache refresh for all tokens
All errors are handled consistently and return JSON responses:
{
"success": false,
"error": "Error message",
"stack": "Stack trace (development only)"
}- Helmet.js for security headers
- CORS configuration
- Input validation
- Error stack traces only in development
MIT