Architecture Overview
Nester follows a layered architecture separating concerns across clients, backend services, blockchain, and external integrations.
System Diagram
┌─────────────────────────────────────────────────────────────┐
│ CLIENTS │
│ │
│ Website (Next.js) DApp (Next.js 16) Mobile (RN) │
│ Marketing/Landing Stellar Wallets iOS/Android │
│ │ (future) │
└──────────────────────────────┼──────────────────────────────┘
│ REST API
┌──────────────────────────────┼──────────────────────────────┐
│ BACKEND LAYER │
│ │ │
│ ┌───────────────────────────▼───────────────────────────┐ │
│ │ API Gateway (Go + Chi Router) │ │
│ │ │ │
│ │ ┌─────────────┐ ┌──────────────┐ ┌───────────────┐ │ │
│ │ │ Vault │ │ Off-Ramp │ │ User / Auth │ │ │
│ │ │ Manager │ │ Orchestrator │ │ Service │ │ │
│ │ └─────────────┘ └──────────────┘ └───────────────┘ │ │
│ │ ┌─────────────┐ ┌──────────────┐ ┌───────────────┐ │ │
│ │ │ Yield │ │ LP Matching │ │ Event │ │ │
│ │ │ Router │ │ & Aggregator │ │ Listener │ │ │
│ │ └─────────────┘ └──────────────┘ └───────────────┘ │ │
│ │ ┌─────────────┐ ┌──────────────┐ ┌───────────────┐ │ │
│ │ │ Rebalancer │ │ Fiat Gateway │ │ AML / │ │ │
│ │ │ Service │ │ (Paystack) │ │ Compliance │ │ │
│ │ └─────────────┘ └──────────────┘ └───────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────▼───────────────────────────┐ │
│ │ Prometheus Intelligence (Python + FastAPI) │ │
│ │ │ │
│ │ Vault Strategy Portfolio Market Intelligence │ │
│ │ Analyzer Analyzer (DeFiLlama, etc.) │ │
│ │ Conversational AI Risk Scoring │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────▼───────────────────────────┐ │
│ │ PostgreSQL (Supabase) │ │
│ │ users │ vaults │ positions │ shares │ yield_snapshots │ │
│ │ transactions │ events │ lp_providers │ offramp_reqs │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌──────────────────────────────┼──────────────────────────────┐
│ BLOCKCHAIN LAYER (Stellar / Soroban) │
│ │ │
│ ┌───────────────────────────▼───────────────────────────┐ │
│ │ Smart Contracts (Rust / Soroban SDK) │ │
│ │ │ │
│ │ VaultFactory Vault Contracts │ │
│ │ Deploy/manage deposit / withdraw / position │ │
│ │ vault instances nVault share token mint/burn │ │
│ │ maturity & penalty logic │ │
│ │ Escrow/Settlement Yield Source Adapters │ │
│ │ Off-ramp lock Blend / Kamino / Aave │ │
│ │ release / refund deposit / withdraw / balanceOf │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
│ Stellar Network: Horizon API / Soroban RPC │
└─────────────────────────────────────────────────────────────┘Data Flow: Deposit
User clicks "Deposit 1000 USDC into Balanced Vault"
│
▼
┌─────────────────┐ ┌──────────────────┐
│ Frontend │────▶│ Go Backend │
│ Build Soroban TX │ │ POST /deposit │
└────────┬────────┘ │ Validate + build │
│ │ TX envelope │
▼ └────────┬─────────┘
┌─────────────────┐ │
│ Wallet Extension │◀────────────┘
│ Sign TX │ TX envelope returned
└────────┬────────┘
│ Signed TX
▼
┌─────────────────┐ ┌──────────────────┐
│ Stellar Network │────▶│ Event Listener │
│ Execute TX │ │ Index deposit │
│ Vault.deposit() │ │ Update positions │
└─────────────────┘ └──────────────────┘Data Flow: Off-Ramp
User clicks "Withdraw ₦500,000 to GTBank"
│
▼
┌──────────────┐ ┌────────────────┐ ┌─────────────┐
│ Frontend │───▶│ Go Backend │───▶│ LP Matcher │
│ POST │ │ Validate KYC │ │ Find best │
│ /offramp/req │ │ Lock escrow │ │ GTBank node │
└──────────────┘ └───────┬────────┘ └──────┬──────┘
│ │
▼ ▼
┌────────────────┐ ┌─────────────┐
│ Soroban │ │ Paystack │
│ Escrow.lock() │ │ API │
│ Reserve USDC │ │ Transfer │
└────────────────┘ │ ₦500,000 │
└──────┬──────┘
┌────────────────────┘
▼
┌────────────────┐ ┌─────────────┐
│ Webhook │───▶│ Soroban │
│ transfer.ok │ │ release() │
│ │ │ USDC → LP │
└────────────────┘ └─────────────┘Project Structure
bash
nester/
├── apps/
│ ├── website/ # Marketing site (Next.js + pnpm)
│ ├── dapp/
│ │ ├── frontend/ # DApp (Next.js 16 + npm)
│ │ ├── backend/ # API (Go + Chi — migrating from Node.js)
│ │ └── contracts/ # Soroban smart contracts (Rust)
│ └── intelligence/ # Prometheus AI (Python + FastAPI)
├── packages/
│ └── contracts/ # Shared contract types/ABIs
└── mobile/ # React Native app (future)Database Schema
sql
-- Core tables (PostgreSQL / Supabase)
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
wallet_addr TEXT UNIQUE NOT NULL,
kyc_status TEXT DEFAULT 'none', -- none | pending | approved
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE vaults (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL, -- "Conservative", "Balanced", etc.
vault_type TEXT NOT NULL, -- conservative | balanced | growth | defi500
contract_id TEXT NOT NULL, -- Soroban contract address
total_shares NUMERIC DEFAULT 0,
total_assets NUMERIC DEFAULT 0,
apy_current NUMERIC DEFAULT 0,
status TEXT DEFAULT 'active', -- active | paused
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE positions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
vault_id UUID REFERENCES vaults(id),
shares NUMERIC NOT NULL,
deposited_at TIMESTAMPTZ DEFAULT now(),
maturity_at TIMESTAMPTZ,
UNIQUE(user_id, vault_id)
);
CREATE TABLE yield_snapshots (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
vault_id UUID REFERENCES vaults(id),
apy NUMERIC NOT NULL,
tvl NUMERIC NOT NULL,
recorded_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE offramp_requests (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
amount_usd NUMERIC NOT NULL,
amount_fiat NUMERIC NOT NULL,
currency TEXT NOT NULL, -- NGN | GHS | KES
bank_code TEXT NOT NULL,
account_num TEXT NOT NULL,
status TEXT DEFAULT 'pending', -- pending | escrowed | settled | failed | refunded
tx_hash TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);