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()
);