midnight-api

Installation
SKILL.md

Midnight API Integration (v8.0+)

Complete guide to integrating Midnight Network APIs for building privacy-preserving decentralized applications.

API Ecosystem Overview

Midnight provides multiple specialized APIs:

API Package Version Purpose
Midnight.js @midnight-ntwrk/midnight-js 4.x Complete TypeScript SDK
Compact Runtime @midnight-ntwrk/compact-runtime 0.15.0 Execute contracts, generate ZK proofs
DApp Connector @midnight-ntwrk/dapp-connector-api 4.0.1 Connect to wallets
Ledger @midnight/ledger 8.0.3 Blockchain transactions
Wallet API Various Latest Wallet operations

Quick Start

Install Dependencies

npm install @midnight-ntwrk/midnight-js
npm install @midnight-ntwrk/dapp-connector-api
npm install @midnight-ntwrk/compact-runtime
npm install @midnight/ledger

Basic DApp Setup

import { MidnightProvider } from '@midnight-ntwrk/midnight-js';
import { DAppConnector } from '@midnight-ntwrk/dapp-connector-api';

// Connect to Midnight
const connect = async () => {
  // Check for injected wallet
  if (typeof window !== 'undefined' && window.midnight) {
    const provider = new MidnightProvider(window.midnight);
    await provider.ready;
    return provider;
  }
  throw new Error('Midnight wallet not found');
};

Core APIs

1. Midnight.js SDK (v4.x)

Complete JavaScript/TypeScript SDK for building DApps.

import { 
  MidnightProvider,    // Main provider
  Wallet,             // Wallet connection
  Contract,           // Contract instance
  Transaction,        // Transaction builder
  findById,           // Indexer queries
} from '@midnight-ntwrk/midnight-js';

// Network configuration (REQUIRED)
const network = 'preprod'; // or 'testnet-02', 'mainnet'

// Initialize provider
const provider = await MidnightProvider.fetch({ network });

// Connect wallet
const wallet = await provider.wallet();
// Or use DApp connector
const connector = new DAppConnector();
await connector.ready;

2. DApp Connector API (v4.0.4)

Wallet connection interface.

import { 
  InitialAPI,
  ConnectedAPI,
  Configuration,
  WalletConnectedAPI,
} from '@midnight-ntwrk/dapp-connector-api';

// Check for injected wallet
const getInitialAPI = (): InitialAPI | undefined => {
  return (window as any).midnight;
};

// Connect
const connect = async (): Promise<ConnectedAPI> => {
  const initial = getInitialAPI();
  if (!initial) throw new Error('Wallet not found');
  
  return await initial.connect();
};

// Get configuration (respects user privacy)
const config = await connected.getConfiguration();

// Get all addresses
const addresses = await connected.getAddresses();

// Get balance
const balance = await connected.getBalance();

// Make transfer
const tx = await connected.makeTransfer({
  to: recipientAddress,
  amount: 1000000n,
  token: 'midnight', // or custom token
});

3. Compact Runtime API (v0.15.0)

Execute Compact contracts and generate proofs.

import {
  runProgram,
  createCircuitContext,
  createWitnessContext,
  ContractState,
  QueryContext,
} from '@midnight-ntwrk/compact-runtime';

// Run a circuit
const results = await runProgram(
  contract,           // Compiled contract
  'circuitName',     // Circuit to run
  { arg1: value1 }   // Arguments
);

// Create circuit context for proof generation
const ctx = await createCircuitContext(
  contract,
  arguments,
  provingKey
);

// Query ledger state
const state = await queryLedgerState(
  contractAddress,
  fieldName
);

4. Ledger API (v8.0.3)

Low-level blockchain operations.

import {
  LedgerState,
  Transaction,
  runProgram,
  findById,
} from '@midnight/ledger';

// Submit transaction
const tx = await Transaction.create({
  contract,
  circuit: 'transfer',
  inputs: { to, amount },
  provingKey,
});
await tx.submit();

// Wait for confirmation
const receipt = await tx.wait();

// Query state
const state = await LedgerState.fetch(contractAddress);
const value = await state.get('fieldName');

// Query via indexer
const txs = await findById(txHash);

5. Indexer API

Query blockchain data.

import { findById, findAll, findByKey } from '@midnight-ntwrk/midnight-js';

// Find transaction
const tx = await findById(txHash);

// Find by address
const txs = await findByAddress(address, {
  limit: 100,
  from: startBlock,
});

// Find by contract
const contractTxs = await findByContract(contractAddress);

// Query with filters
const results = await findAll({
  contract: contractAddress,
  circuit: 'transfer',
  fromBlock: 1000,
  toBlock: 2000,
});

Wallet Integration Patterns

React + Wallet Connection

import { useMidnight } from '@midnight-ntwrk/midnight-react';

function WalletButton() {
  const { connect, disconnect, address, balance } = useMidnight();
  
  return address ? (
    <button onClick={disconnect}>
      Disconnect ({balance} TNS)
    </button>
  ) : (
    <button onClick={connect}>Connect Wallet</button>
  );
}

Next.js + Wallet Connect

// pages/api/auth.ts
import { MidnightAuth } from '@midnight-ntwrk/midnight-auth';

export default async function handler(req, res) {
  const { address, signature } = req.body;
  
  // Verify signature
  const isValid = await MidnightAuth.verify(address, message, signature);
  
  if (isValid) {
    // Create session
    const token = await MintToken.create({ address });
    res.json({ token });
  } else {
    res.status(401).json({ error: 'Invalid signature' });
  }
}

Vanilla TypeScript

// Simple wallet connection
class WalletConnection {
  private connector: DAppConnector;
  
  async connect(): Promise<string> {
    await this.connector.ready;
    const api = await this.connector.connect();
    const addresses = await api.getAddresses();
    return addresses[0];
  }
  
  async getBalance(): Promise<bigint> {
    const api = await this.connector.connect();
    return api.getBalance();
  }
}

ZSwap Private Transactions

Creating Shielded Transfers

import {
  createZswapInput,
  createZswapOutput,
  ZswapLocalState,
  receiveShielded,
  sendShielded,
} from '@midnight-ntwrk/compact-runtime';

// Create input from received coin
const input = await createZswapInput(coinInfo);

// Create output for recipient
const output = await createZswapOutput({
  recipient: recipientAddress,
  amount: amount,
  token: tokenType,
});

// Receive to update local state
const newState = await receiveShielded(input);

// Send shielded tokens
const { tx, newState: finalState } = await sendShielded({
  inputs: [input],
  outputs: [output],
  change: changeOutput,
});

Full Transfer Example

import { 
  MidnightProvider, 
  findById,
} from '@midnight-ntwrk/midnight-js';

async function sendShielded(
  recipient: string,
  amount: bigint
): Promise<string> {
  const provider = await MidnightProvider.fetch({ 
    network: 'preprod' 
  });
  
  // Get unspent coins
  const coins = await provider.getCoins();
  
  // Select coins (UTXO model)
  const selected = selectCoins(coins, amount);
  
  // Create shielded transaction
  const tx = await provider.createTransaction({
    inputs: selected,
    outputs: [{
      recipient,
      amount,
    }],
    changeAddress: await provider.getChangeAddress(),
  });
  
  // Wait for confirmation
  return tx.submit();
}

Smart Contract Deployment

Compile and Deploy

# 1. Install tools
npm install @midnight-ntwrk/compact-tools

# 2. Compile contract
npx compact build my-contract.compact

# 3. Deploy
npx midnight-deploy --network preprod --contract my-contract.json

Programmatic Deployment

import { 
  MidnightProvider,
  Contract,
} from '@midnight-ntwrk/midnight-js';

async function deploy(
  contractPath: string,
  network: string = 'preprod'
): Promise<string> {
  const provider = await MidnightProvider.fetch({ network });
  
  // Read compiled contract
  const artifact = require(contractPath);
  
  // Deploy
  const tx = await Contract.deploy(artifact);
  await tx.submit();
  
  // Wait for confirmation
  const receipt = await tx.wait();
  
  return receipt.contractAddress;
}

Real-World DApp Examples

From midnight-awesome-dapps

Wallet Connection - midnight-wallet-cli

// Using CLI for local development
// npm install midnight-wallet-cli
import { WalletCLI } from 'midnight-wallet-cli';

const wallet = new WalletCLI();
// Starts local DApp connector server
await wallet.serve();
// Then connect via http://localhost:9848

TypeScript SDK - Midday SDK

// npm install @no-witness-labs/midday-sdk
import { MiddaySDK } from '@no-witness-labs/midday-sdk';

const sdk = new MiddaySDK({ network: 'preprod' });
const wallet = await sdk.wallet.connect();

React Integration

// Using midnight-react
import { MidnightProvider } from '@midnight-ntwrk/midnight-react';

function App() {
  return (
    <MidnightProvider network="preprod">
      <YourDApp />
    </MidnightProvider>
  );
}

Complete Code Examples

1. Connect Wallet

import { DAppConnector } from '@midnight-ntwrk/dapp-connector-api';

async function connectWallet(): Promise<string | null> {
  const connector = new DAppConnector();
  await connector.ready;
  
  const api = await connector.connect();
  const addresses = await api.getAddresses();
  
  return addresses[0] ?? null;
}

2. Make Payment

async function makePayment(
  toAddress: string,
  amount: bigint
): Promise<string> {
  const connector = new DAppConnector();
  await connector.ready;
  
  const api = await connector.connect();
  const result = await api.makeTransfer({
    to: toAddress,
    amount: amount,
  });
  
  return result.txId;
}

3. Query Balance

async function getBalance(address: string): Promise<bigint> {
  const connector = new DAppConnector();
  await connector.ready;
  
  const api = await connector.connect();
  const balance = await api.getBalance();
  
  return balance;
}

4. Deploy Contract

import { MidnightProvider } from '@midnight-ntwrk/midnight-js';

async function deployContract(
  artifact: any,
  network: string = 'preprod'
): Promise<string> {
  const provider = await MidnightProvider.fetch({ network });
  const tx = await provider.deploy(artifact);
  await tx.wait();
  
  return tx.contractAddress;
}

5. Call Contract Circuit

async function callCircuit(
  contract: string,
  circuit: string,
  args: any
): Promise<any> {
  const provider = await MidnightProvider.fetch({ network: 'preprod' });
  
  const result = await provider.call({
    contract,
    circuit,
    args,
  });
  
  return result;
}

Awesome DApp References for Learning

Official Examples

SDKs and Tools

DeFi Integration

Identity

Additional Resources

Network Endpoints (Official)

Network RPC URL Indexer Faucet Explorer Status
Mainnet https://rpc.mainnet.midnight.network https://indexer.mainnet.midnight.network/api/v4/graphql - - Production
Preprod https://rpc.preprod.midnight.network https://indexer.preprod.midnight.network/api/v4/graphql https://faucet.preprod.midnight.network https://explorer.preprod.midnight.network Active
Preview https://rpc.preview.midnight.network https://indexer.preview.midnight.network/api/v4/graphql https://faucet.preview.midnight.network https://explorer.preview.midnight.network Discontinued

⚠️ Important: Both Testnet-02 and Preview are discontinued. Use Preprod for all testing.

Preprod is the active test network where:

  • DUST must be generated programmatically (see midnight-dust-generator)
  • tNIGHT available from Preprod faucet

Troubleshooting

  • Wallet not found: Install Lace wallet or use midnight-wallet-cli
  • Network mismatch: Always call setNetworkId() before operations
  • Insufficient balance: Use faucet for testnet tokens
  • Proof generation failing: Check proof server is running
  • Transaction rejected: Check fees and account state

Lace Wallet Configuration

When using local networks (like undeployed), ensure Lace is configured correctly:

  1. Open Lace Wallet → Settings → Midnight
  2. Select Undeployed network (not Preprod or Mainnet)
  3. Click Save configuration

Error: "Expected undeployed address, got Preprod address"

  • This means you're trying to use a Preprod address in the Undeployed network
  • Switch Lace to use Undeployed network to get correct addresses
  • Use the unshielded (mn1q...) address for the local network
Related skills

More from mzf11125/midnight_agent_skills

Installs
7
GitHub Stars
4
First Seen
Feb 22, 2026