Skip to content

JorisZierold/midnight-dapp-template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸŒ™ Midnight dApp Template

Midnight Network

Compact TypeScript React

A production-ready starter template for building decentralized applications on Midnight Network

πŸ“– Table of Contents

🎯 Overview

This template provides a complete, production-ready foundation for building decentralized applications on the Midnight blockchain. It showcases the full integration stack from smart contracts to frontend, with a focus on developer experience and best practices.

This template uses a simple counter contract to demonstrate the core patterns you'll need for any Midnight dApp:

  • βœ… Smart contract development in Compact
  • βœ… Cross-platform API (Browser + Node.js)
  • βœ… React frontend with wallet integration
  • βœ… Interactive CLI tools
  • βœ… Comprehensive testing setup
  • βœ… Turborepo monorepo configuration

🎨 Why This Template?

The Problem

Building a Midnight dApp from scratch requires understanding:

  • Compact smart contracts
  • Zero-knowledge proof generation
  • Wallet integration (Browser + Node.js)
  • Cross-platform provider configuration
  • Complex build tooling and monorepo setup

The Solution

This template gives you a working reference implementation that you can:

  1. Fork and start building immediately
  2. Learn from clean, documented code
  3. Extend without fighting the existing architecture

Perfect for: New Midnight developers, hackathons, proof-of-concepts, and production dApps.

✨ Features

πŸ” Privacy-First Architecture

  • Zero-knowledge proof generation
  • Private state management
  • Public ledger state

🌐 Full-Stack Integration

  • Frontend: React + Tailwind CSS with Midnight Lace wallet
  • Backend: Node.js CLI with comprehensive testing
  • Contract: Compact smart contract with type-safe bindings

πŸ”„ Cross-Platform API

  • Single API codebase works in both browser and Node.js
  • Environment abstraction layer
  • Platform-specific optimizations

πŸ› οΈ Developer Experience

  • Turborepo for fast, cached builds
  • TypeScript everywhere
  • Hot reload for development
  • Comprehensive error handling

πŸ§ͺ Testing Infrastructure

  • Contract simulation tests
  • API integration tests
  • Type-safe test patterns

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Web Frontend      β”‚    β”‚   CLI Interface     β”‚
β”‚                     β”‚    β”‚                     β”‚
β”‚ β€’ React + Tailwind  β”‚    β”‚ β€’ Interactive Menu  β”‚
β”‚ β€’ Wallet Connect    β”‚    β”‚ β€’ Contract Deploy   β”‚
β”‚ β€’ Real-time State   β”‚    β”‚ β€’ State Queries     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                          β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚   Unified API       β”‚
          β”‚                     β”‚
          β”‚ β€’ Type-Safe         β”‚
          β”‚ β€’ Cross-Platform    β”‚
          β”‚ β€’ Provider Pattern  β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚  Counter Contract   β”‚
          β”‚                     β”‚
          β”‚ β€’ Compact Language  β”‚
          β”‚ β€’ Public State      β”‚
          β”‚ β€’ ZK Circuits       β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚  Midnight Network   β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Architecture Decisions

  1. Monorepo with Turborepo: Fast, cached builds across all packages
  2. Unified API Layer: Single codebase for browser and Node.js
  3. Environment Abstraction: Platform-specific code isolated and testable
  4. Contract-First Design: Type safety flows from contract to UI

πŸš€ Quick Start

Prerequisites

  • Node.js v18 or higher
  • Yarn v1.22+
  • Midnight Lace Wallet (for web interface)

Installation

# Install dependencies
yarn install

# Build all packages
yarn build

Run the Web App

yarn start
# Access at http://127.0.0.1:8080/

Run the CLI

# Interactive CLI with testnet
yarn cli

# Wallet options:
# 1. Create a new wallet (generates and displays seed)
# 2. Import wallet from seed (for existing wallets)

# After wallet setup:
# 1. Deploy a new counter contract
# 2. Increment counter by 1
# 3. Increment counter by custom amount
# 4. View counter value
# 5. Join an existing counter contract
# 6. Exit

Run Tests

# Test smart contract
yarn test-contract

# Test API
yarn test-api

# Lint all packages
yarn lint

πŸ“ Project Structure

midnight-dapp-template/
β”œβ”€β”€ apps/
β”‚   └── web/                    # React web application
β”‚       β”œβ”€β”€ src/
β”‚       β”‚   β”œβ”€β”€ ui/
β”‚       β”‚   β”‚   β”œβ”€β”€ components/ # React components
β”‚       β”‚   β”‚   β”œβ”€β”€ contexts/   # State management
β”‚       β”‚   β”‚   β”œβ”€β”€ hooks/      # Custom React hooks
β”‚       β”‚   β”‚   └── config/     # App configuration
β”‚       β”‚   └── main.tsx        # Entry point
β”‚       └── vite.config.ts      # Vite build config
β”‚
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ contracts/              # Smart contracts
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   β”œβ”€β”€ counter.compact # Counter contract
β”‚   β”‚   β”‚   β”œβ”€β”€ index.ts        # Contract exports
β”‚   β”‚   β”‚   β”œβ”€β”€ witnesses.ts    # Witness functions
β”‚   β”‚   β”‚   └── test/           # Contract tests
β”‚   β”‚   └── package.json
β”‚   β”‚
β”‚   β”œβ”€β”€ api/                    # Unified API layer
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   β”œβ”€β”€ common/         # Shared code
β”‚   β”‚   β”‚   β”œβ”€β”€ browser/        # Browser-specific
β”‚   β”‚   β”‚   └── node/           # Node.js-specific
β”‚   β”‚   └── package.json
β”‚   β”‚
β”‚   β”œβ”€β”€ cli/                    # CLI tools
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   └── cli.ts          # Interactive CLI
β”‚   β”‚   └── package.json
β”‚   β”‚
β”‚   β”œβ”€β”€ compact/                # Contract compilation
β”‚   β”œβ”€β”€ ui/                     # Shared UI components
β”‚   β”œβ”€β”€ eslint-config/          # Shared ESLint config
β”‚   └── typescript-config/      # Shared TypeScript config
β”‚
β”œβ”€β”€ turbo.json                  # Turborepo configuration
β”œβ”€β”€ package.json                # Root package.json
└── README.md                   # This file

πŸ’» Development Guide

Smart Contract Development

The counter contract is located at packages/contracts/src/counter.compact:

export ledger counter: Counter;

export circuit increment(): [] {
  counter.increment(1);
}

export circuit incrementBy(amount: Uint<32>): [] {
  assert(amount > 0, "Amount must be greater than 0");
  counter.increment(amount);
}

To modify the contract:

  1. Edit counter.compact
  2. Run yarn compact to compile
  3. Run yarn test-contract to test
  4. Update API types if needed

API Development

The API provides a unified interface for both browser and Node.js:

// Deploy a contract
const counterApi = await CounterAPI.deploy(providers);

// Increment the counter
await counterApi.increment();

// Get current value
const value = await counterApi.getCounter();

// Subscribe to state changes
counterApi.state$.subscribe((state) => {
  console.log(`Counter: ${state.counter}`);
});

Key patterns:

  • packages/api/src/common/ - Shared logic
  • packages/api/src/browser/ - Browser-specific (Lace wallet)
  • packages/api/src/node/ - Node.js-specific (CLI wallet)

Frontend Development

The React app demonstrates:

  • Wallet connection with Midnight Lace
  • Real-time state subscriptions via RxJS
  • Contract deployment and interaction
  • Error handling and loading states
  • Custom hooks for business logic separation

Architecture highlights:

  • useCounterAPI hook - Abstracts all CounterAPI logic
  • useMidnightWallet hook - Manages wallet connection state
  • Component separation - UI components focus on presentation

To customize the UI:

  1. Edit apps/web/src/ui/components/App.tsx for UI
  2. Edit apps/web/src/ui/hooks/useCounterAPI.ts for contract logic
  3. Run yarn start for hot reload
  4. Test in browser with Lace wallet

CLI Development

The CLI provides:

  • Contract deployment
  • Interactive operations
  • State queries
  • Wallet management

To add CLI commands:

  1. Edit packages/cli/src/cli.ts
  2. Add menu options and handlers
  3. Test with yarn cli

πŸ“š Documentation

Package Documentation

External Resources

πŸ”§ Common Commands

# Development
yarn compact          # Compile smart contracts
yarn build            # Build all packages
yarn start            # Start web app
yarn cli              # Run CLI

# Testing
yarn test-contract    # Test smart contract
yarn test-api         # Test API
yarn lint             # Lint all packages
yarn format           # Format code

# Specific builds
yarn build:contracts  # Build only contracts
yarn build:api        # Build only API
yarn build:cli        # Build only CLI
yarn build:app        # Build only web app

🀝 Extending This Template

Adding New Features

  1. Add a circuit to counter.compact
  2. Update types in packages/api/src/common/types.ts
  3. Add API method in packages/api/src/common/api.ts
  4. Update UI/CLI to call the new method

Common Extensions

  • Add private state: Modify witnesses.ts and contract
  • Add parameters: Update circuit signatures and API
  • Add queries: Implement pure circuits for state reading
  • Integrate external modules: Import from other contracts

πŸ” Troubleshooting

Contract Compilation Fails

Solution: Run yarn compact from the root directory. No COMPACT_PATH environment variable is required.

Browser Build Errors

Issue: Node.js modules appearing in browser bundle

Solutions:

  • Check Vite aliases in apps/web/vite.config.ts
  • Verify import paths use environment-specific imports
  • Add missing aliases or external declarations
  • When adding Node.js dependencies to API, ensure they're:
    • Excluded from browser builds in optimizeDeps.exclude
    • Marked as external in build.rollupOptions.external
    • Have browser alternatives aliased properly

Module Resolution Errors

Issue: "Cannot find module" in different environments

Solutions:

  • Check package.json exports in packages/api/package.json
  • Use correct import path (browser-api vs node-api)
  • See packages/api/PATH_RESOLUTION.md for details

CLI Connection Issues

Issue: Cannot connect to testnet

Solutions:

  • Check network configuration in packages/cli/*.yml
  • Verify proof server availability
  • Use yarn cli (defaults to external proof server)
  • Check if testnet is working:
curl -s https://rpc.testnet-02.midnight.network \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"chain_getHeader","params":[],"id":1}' | jq '.result.number'

If this returns an error or the same block number after waiting a few minutes, the testnet may be down. Check the Midnight Discord for status updates.

πŸ“„ License

This project uses dual licensing:

  • 🎨 Web App & Smart Contracts - MIT License

    • Freely usable in commercial and proprietary projects
    • Perfect for building your own dApps
  • πŸ”§ Infrastructure (API, CLI, tooling) - GPL-3.0

    • Contains architectural patterns from the original midnight-kitties project
    • Derivatives must remain open source

Why Dual License?

The web app and smart contracts are original work you'll want to customize for your product. We use MIT so you can use them freely without restrictions.

The underlying infrastructure (environment abstraction, provider patterns, build configs) is derived from midnight-kitties and respects its GPL-3.0 license.

See LICENSE for complete details and attribution.


Built with ❀️ for the Midnight community

Documentation β€’ Twitter

About

Midnight E2E dApp Template for testing and development

Resources

License

Stars

Watchers

Forks