Data Architecture
The frontend uses a hybrid data fetching model — some data comes from the database, some from APIs, and some directly from the blockchain. Understanding which source is used for what is key to working on the frontend.
Data Sources
1. PostgreSQL via Prisma (Server Components)
For data that lives in the NMT database and doesn't change in real-time:
| Data | Example |
|---|---|
| User settings | Preferences, notification settings |
| Safe configurations | Linked Safes, modules, delegates |
| Historical positions | Past position data |
| Pool metadata | Cached pool information |
How it works: Next.js Server Components call Prisma directly. No API hop needed — the database query runs on the server during page rendering.
// Example: Server component reading from DB
const safes = await prisma.safe_account.findMany({
where: { user_id: userId }
});
2. Next.js API Routes (Client Components)
For data that requires server-side processing, API key protection, or multi-source aggregation:
| Data | Route | Source |
|---|---|---|
| Pool listings | /api/v1/pools |
Prisma (DB) |
| Position summaries | /api/v1/positions |
Prisma (DB) |
| Chart data | /api/v1/positions/stacked-chart |
Prisma (DB) |
| Token balances | /api/v1/zerion/balances |
Zerion API |
| Portfolio chart | /api/v1/zerion/chart |
Zerion API |
How it works: Client components use SWR for data fetching. The Next.js API routes query Prisma or proxy to external services, keeping API keys server-side.
3. Blockchain via Viem (Client Components)
For real-time on-chain data:
| Data | Method |
|---|---|
| Token balances | readContract / getBalance |
| Allowances | readContract |
| Transaction receipts | waitForTransactionReceipt |
How it works: Viem connects to RPC endpoints (dRPC/Alchemy) to read blockchain state directly.
4. External APIs (Client Components)
For data from third-party providers:
| Provider | Data | Method |
|---|---|---|
| Zerion | Portfolio history, balances | REST API |
| CoinGecko | Token prices | REST API |
| Moralis | Transaction history | REST API |
| CometChat | Chat messages, presence | WebSocket SDK |
Prisma Schema
The Prisma schema is split across multiple files in prisma/schema/:
| File | Contents |
|---|---|
schema.prisma |
Main schema, user, wallet, auth models |
tokens.prisma |
Token and price models |
safe.prisma |
Safe account, delegate, module models |
liquidity-positions.prisma |
Position and valuation models |
nmt-v2.prisma |
Updated v2 models |
introspected.prisma |
Auto-generated from existing DB |
The schema includes 50+ models and 129+ migrations.
State Management
The frontend uses several patterns for state:
| Pattern | Use Case |
|---|---|
| React Context | Global state (wallet connection, theme) |
| SWR | Server state caching and revalidation |
| URL state | Filters, pagination (via search params) |
| Local state | Form inputs, UI toggles |