Full-stack frontend for the dotFlat collateralized stablecoin protocol.
Users manage CDP positions, deposits, auctions, and liquidity pools β all backed by a Redis-cached contract layer and a real-time block-watcher service.
Browser
β
ββββββββββ΄βββββββββ
β Nginx / React β :8008 (prod) Β· :3000 (dev)
ββββββββββ¬βββββββββ
β
βββββββββββββββΌβββββββββββββββ
β β β
/api/contracts /api/worker /api/rpc
β β β
βΌ βΌ βΌ
ββββββββββββββ βββββββββββββ Ethereum RPC
β Backend β β Block β (publicnode /
β Express β β Watcher β Infura / etc)
β :3001 β β :3002 β
βββββββ¬βββββββ βββββββ¬ββββββ
β β WebSocket
βββββββββ¬βββββββββ
βΌ
ββββββββββββ
β Redis β 60s TTL Β· auto-invalidated on tx
β :6379 β
ββββββββββββ
| Service | Port | Description |
|---|---|---|
| Frontend | 8008 / 3000 | React 19 SPA served by Nginx in prod, CRA dev server locally |
| Backend | 3001 | Express API β aggregates contract reads, serves cached responses |
| Block Watcher | 3002 / 3003 | Monitors new blocks via WebSocket, invalidates Redis on tx |
| Redis | 6379 | Shared cache β TTL 60s, write-through invalidation by watcher |
- π‘ WebSocket block monitoring β 1 subscription replaces NΓpolling; 50Γ RPC load reduction
- πΎ Three-layer cache β component state β Redis (60s TTL, auto-invalidated) β Ethereum RPC
- π Circuit breaker β
workerCircuitBreaker.jsdegrades gracefully when the watcher is unavailable - π Nginx RPC proxy β
/api/rpcsolves browser CORS and enables future server-side caching - β‘ Lazy-loaded pages β React Suspense + code splitting for fast initial load
- π DAO-gated contract calls β only authorized addresses can mutate; all reads go through cache
# Development β hot reload, production-like RPC proxy
docker compose --profile dev up -d
# β http://localhost:3008
# Development LOCAL β hot reload against a local Ganache/Hardhat node (:8545)
docker compose --profile dev-local up -d
# β http://localhost:3007
# Production β optimized build + full stack (frontend, backend, watcher, redis)
docker compose --profile prod up -d
# β http://localhost:8008
# Workers only β block-watcher + redis, no frontend
docker compose --profile workers up
# health: http://localhost:3002/healthnpm install
npm start # dev server β http://localhost:3000
npm run build # production build β /build
npm test # jest test runnerCopy .env.example to .env and adjust:
| Variable | Default | Purpose |
|---|---|---|
REACT_APP_ETHERSCAN_API_KEY |
β | ETH price fetch via Etherscan |
REACT_APP_WALLETCONNECT_PROJECT_ID |
β | WalletConnect modal |
REACT_APP_RPC_URL |
/api/rpc |
RPC endpoint (proxied or direct URL) |
REACT_APP_WORKERS_HEALTH_URL |
/api/worker/health |
Block watcher health endpoint |
RPC_WS_URL |
wss://ethereum.publicnode.com |
Block watcher WebSocket RPC |
RPC_HTTP_URL |
https://ethereum.publicnode.com |
Block watcher HTTP RPC |
START_BLOCK |
21677704 |
Block watcher indexing start |
ETHERSCAN_API_KEY |
β | ABI fetching for watched contracts |
CACHE_TTL |
60 |
Redis TTL in seconds |
LOG_LEVEL |
info |
Backend / watcher log level |
| Contract | Address |
|---|---|
| INTDAO (governance) | 0x55Ead3b40016b1d5417F5A20F2d1E53e2d1c9122 |
| CDP | 0xbCf58DE37791eFe60fE87a6d420FE8F7AEA99ef8 |
| flatCoin (DFC, ERC-20) | 0x1F709Cfa0C409E158C68EdcD32453809c9Eb69EE |
| Deposit | 0x44881F5ac2938AAaF4260d7DBE18997318788f9f |
| Auction | 0xBdFb52d4C9fBdE41805abBb206465aca3b3499D6 |
| Rule Token (RLE) | 0x3Dfa45997ddB7980Eb4D73CBfCf0E024F05b08a3 |
| Exchange Rate | 0x1DF609afDC67396a9f307de2BA3E3b667dEe8b5B |
Full contract config: src/utils/config.js
CI/CD via GitLab pipeline (.gitlab-ci.yml):
- Build β Kaniko (containerless) β GitLab Container Registry
- develop branch β auto-deploy to
beta.app.dotflat.io - master branch β auto-deploy to
app.dotflat.io - Orchestration: Kubernetes (K3s), rolling updates via
kubectl set image
See k8s/README.md for cluster setup notes (Redis namespace, FQDN config).
See ROADMAP.md.
- Quick Start β choosing the right dev mode
- Docker Setup β Compose profiles explained
- Workers β block-watcher architecture deep dive
- Block Watcher Page β cache inspection UI
- RPC Proxy β CORS solution and proxy config
- Caching β three-layer cache strategy
- Routing β client-side routing and deep linking
- Event Fetching β block range limit workarounds
- Uniswap Integration β swap/pool logic
- Oracle β commodities price feed system