Lending Protocol on Midnight

I’ve built a privacy-preserving collateralized lending protocol on the Midnight Network using Compact 0.28.0 and midnight-js 3.0.0.

The protocol allows users to:

  • Deposit tNight as collateral

  • Mint a synthetic stablecoin (pUSD) against that collateral

  • Maintain a minimum 150% collateral ratio

  • Repay debt and withdraw collateral

  • Liquidate undercollateralized positions

All collateral and debt balances are private, enforced via zero-knowledge circuits, while global protocol totals remain public for solvency verification.

Conceptually similar to MakerDAO, but fully adapted to Midnight’s ZK-first architecture.


What I Have Successfully Built

:one: Compact ZK Smart Contract

  • Written in lending.compact

  • 5 circuits:

    • depositCollateral

    • mintPUSD

    • repayPUSD

    • withdrawCollateral

    • liquidate

  • Collateral ratio enforced via multiplication constraints:

    collateral × 100 ≥ debt × 150
    
    
  • 30 unit tests passing using an in-memory LendingSimulator

  • ZK keys + bindings generated via npm run compact


:two: Full Backend (REST API – Express)

Located in lending-api/

Wallet Endpoints

  • Initialize / restore wallet

  • Get balances and addresses

  • Wait for funds

  • Register DUST

  • Get DUST balance

Contract Endpoints

  • Deploy new lending contract

  • Join existing contract

State Endpoints

  • Public protocol state

  • Private position state

  • Health check endpoint

Action Endpoints

  • Deposit collateral

  • Mint pUSD

  • Repay pUSD

  • Withdraw collateral

  • Liquidate position

BigInt values are serialized properly, errors categorized with errorType.


:three: React Web Frontend

Located in lending-ui/

Pages:

  • Setup (wallet + deploy/join)

  • Dashboard (public protocol state)

  • My Position (private state + ratio health)

  • Actions (deposit/mint/repay/withdraw/liquidate)

UX features:

  • Live ratio preview while typing

  • Color-coded health indicator

  • ZK proof loading feedback

  • Auto-refresh

  • Error classification

  • Dark themed UI

Frontend communicates with the backend via typed API client.


:four: CLI Interface

Fully functional terminal version with:

  • Wallet creation / restore

  • Contract deploy/join

  • DUST monitoring

  • All 5 lending operations

  • Private position view

  • Public protocol state view

Works in:

  • Standalone mode (Docker local stack)

  • Preview

  • Preprod


:five: Proof Server Integration

Using:

midnightntwrk/proof-server:7.0.0

Via:

docker compose -f proof-server.yml up

System expects proof server on:

localhost:6300


Current Blocker

The entire system works locally in standalone mode and via CLI, and the UI + API also run correctly in dev.

However, I am currently stuck at:

  • Proper backend deployment (API server)

  • Proper proof server deployment

  • Understanding best practices for:

    • Hosting proof server in production

    • Connecting deployed backend to proof server

    • Handling ZK key files in production

    • Network configuration for Preview/Preprod in hosted environment

I want guidance specifically on:

  • How to deploy the backend properly

  • How to deploy or host the proof server correctly

  • How production architecture should look for a Midnight ZK dApp


That’s the current state of the project.

1 Like