| name | midnight-api |
| description | Comprehensive guide to Midnight Network APIs (v8.0+) for building decentralized applications. Use when users need to integrate Midnight APIs including Compact Runtime, DApp Connector, ZSwap, Wallet, and Ledger APIs, connect DApps to Midnight wallets, generate and verify zero-knowledge proofs programmatically, manage transactions and blockchain state, deploy and interact with Compact smart contracts, query blockchain data via indexer, implement wallet functionality, handle Zswap private transactions, and build complete web3 applications on Midnight. |
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.0.4 | Complete TypeScript SDK |
| Compact Runtime | @midnight-ntwrk/compact-runtime | 0.16.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 SDK | @midnight-ntwrk/wallet-sdk-facade | 3.0.0 | Unified wallet operations, key management, transfers |
| 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
npm install @midnight-ntwrk/wallet-sdk-facade
Basic DApp Setup
import { MidnightProvider } from '@midnight-ntwrk/midnight-js';
import { DAppConnector } from '@midnight-ntwrk/dapp-connector-api';
const connect = async () => {
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.0.4)
Complete JavaScript/TypeScript SDK for building DApps.
import {
MidnightProvider,
Wallet,
Contract,
Transaction,
findById,
} from '@midnight-ntwrk/midnight-js';
const network = 'preprod';
const provider = await MidnightProvider.fetch({ network });
const wallet = await provider.wallet();
const connector = new DAppConnector();
await connector.ready;
2. DApp Connector API (v4.0.1)
Wallet connection interface.
import {
InitialAPI,
ConnectedAPI,
Configuration,
WalletConnectedAPI,
} from '@midnight-ntwrk/dapp-connector-api';
const getInitialAPI = (): InitialAPI | undefined => {
return (window as any).midnight;
};
const connect = async (): Promise<ConnectedAPI> => {
const initial = getInitialAPI();
if (!initial) throw new Error('Wallet not found');
return await initial.connect();
};
const config = await connected.getConfiguration();
const addresses = await connected.getAddresses();
const balance = await connected.getBalance();
const tx = await connected.makeTransfer({
to: recipientAddress,
amount: 1000000n,
token: 'midnight',
});
3. Compact Runtime API (v0.16.0)
Execute Compact contracts and generate proofs.
import {
runProgram,
createCircuitContext,
createWitnessContext,
ContractState,
QueryContext,
} from '@midnight-ntwrk/compact-runtime';
const results = await runProgram(
contract,
'circuitName',
{ arg1: value1 }
);
const ctx = await createCircuitContext(
contract,
arguments,
provingKey
);
const state = await queryLedgerState(
contractAddress,
fieldName
);
4. Ledger API (v8.0.3)
Low-level blockchain operations.
import {
LedgerState,
Transaction,
runProgram,
findById,
} from '@midnight/ledger';
const tx = await Transaction.create({
contract,
circuit: 'transfer',
inputs: { to, amount },
provingKey,
});
await tx.submit();
const receipt = await tx.wait();
const state = await LedgerState.fetch(contractAddress);
const value = await state.get('fieldName');
const txs = await findById(txHash);
5. Indexer API
Query blockchain data.
import { findById, findAll, findByKey } from '@midnight-ntwrk/midnight-js';
const tx = await findById(txHash);
const txs = await findByAddress(address, {
limit: 100,
from: startBlock,
});
const contractTxs = await findByContract(contractAddress);
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
import { MidnightAuth } from '@midnight-ntwrk/midnight-auth';
export default async function handler(req, res) {
const { address, signature } = req.body;
const isValid = await MidnightAuth.verify(address, message, signature);
if (isValid) {
const token = await MintToken.create({ address });
res.json({ token });
} else {
res.status(401).json({ error: 'Invalid signature' });
}
}
Vanilla TypeScript
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';
const input = await createZswapInput(coinInfo);
const output = await createZswapOutput({
recipient: recipientAddress,
amount: amount,
token: tokenType,
});
const newState = await receiveShielded(input);
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'
});
const coins = await provider.getCoins();
const selected = selectCoins(coins, amount);
const tx = await provider.createTransaction({
inputs: selected,
outputs: [{
recipient,
amount,
}],
changeAddress: await provider.getChangeAddress(),
});
return tx.submit();
}
Smart Contract Deployment
Compile and Deploy
npm install @midnight-ntwrk/compact-tools
npx compact build my-contract.compact
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 });
const artifact = require(contractPath);
const tx = await Contract.deploy(artifact);
await tx.submit();
const receipt = await tx.wait();
return receipt.contractAddress;
}
Real-World DApp Examples
From midnight-awesome-dapps
Wallet Connection - midnight-wallet-cli
import { WalletCLI } from 'midnight-wallet-cli';
const wallet = new WalletCLI();
await wallet.serve();
TypeScript SDK - Midday SDK
import { MiddaySDK } from '@no-witness-labs/midday-sdk';
const sdk = new MiddaySDK({ network: 'preprod' });
const wallet = await sdk.wallet.connect();
React Integration
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)
⚠️ 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:
- Open Lace Wallet → Settings → Midnight
- Select Undeployed network (not Preprod or Mainnet)
- Click Save configuration
Cross Reference Skills
This skill covers API integration and DApp plumbing. For related areas see these skills.
- midnight-concepts — Architecture, privacy, ZK proofs, tokenomics
- midnight-compact — Smart contract syntax, types, ledger operations, ZK patterns
- midnight-network — Node operations, indexer setup, proof server deployment
- midnight-wallet — Wallet SDK, shielded/unshielded transactions, key management
- midnight-dapp-dev — Frontend scaffolds, wallet connect UI, provider setup
- midnight-expert — Health diagnostics, fact checking, version compatibility
Inline References
- Verification methods:
references/verification-methods.md
- Code quality pipeline:
references/quality-pipeline.md
- Error catalog:
references/error-catalog.md
- Plugin infrastructure:
references/infrastructure.md
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