Skip to main content
Version: Canary 🚧

DApp Connector API v4.0.0 release notes

  • Version: v4.0.0
  • Date: 28 January 2026
  • Environment: Preview, PreProd

High-level summary​

This release represents a complete redesign of the DApp Connector API. It introduces a type-based architecture, network-aware connections, granular balance/address methods, proving delegation, and CAIP-372 compatible wallet discovery. Breaking changes affect all developers using v3.0.0.


Audience​

This release note is critical for developers who:

  • Use @midnight-ntwrk/dapp-connector-api in their DApps.
  • Integrate wallet functionality into Midnight applications.
  • Maintain wallet implementations compatible with the DApp Connector API.

What changed (Summary of updates)​

  • Complete API redesign from interface-based to type-based architecture.
  • Replaced enable()/isEnabled() connection model with network-aware connect(networkId).
  • Removed dependencies on @midnight-ntwrk/wallet-api and @midnight-ntwrk/zswap.
  • Added proving delegation via getProvingProvider() method.
  • Added atomic swap support via makeIntent() method.
  • Added granular balance and address methods replacing single state() method.
  • Added new error codes: PermissionRejected and Disconnected.
  • Changed APIError from class to type for cross-boundary compatibility.
  • Added comprehensive specification documentation.

New features​

Below is a detailed breakdown of the new features added in this release.

Proving delegation (getProvingProvider)​

Allows DApps to delegate ZK proof generation to the wallet. This enables wallets to offer different proving modalities (local, remote, hardware-accelerated) based on user preferences, improving flexibility and user experience. DApps provide a KeyMaterialProvider and receive a ProvingProvider compatible with Midnight Ledger's interface.

Intent creation (makeIntent)​

Creates transactions with purposefully imbalanced intents for atomic swap scenarios. Allows specifying desired inputs and outputs with configurable intent IDs and fee payment options. Essential for DEX integrations and peer-to-peer token swaps.

Transfer creation (makeTransfer)​

Simplified method for creating transfer transactions with specified outputs. Handles all complexity of coin selection and transaction construction internally.

Data signing (signData)​

Enables signing arbitrary data using wallet keys with configurable encoding (hex, base64, text) and key type selection. Data is automatically prefixed to prevent accidental transaction signing.

Transaction history (getTxHistory)​

Retrieves paginated transaction history relevant to the wallet, including transaction hashes and detailed status information (pending, confirmed, finalized, discarded).

Connection status (getConnectionStatus)​

Allows DApps to check if a wallet connection is still valid and which network it's connected to.

Hint usage (hintUsage)​

Enables DApps to hint which API methods they intend to use, allowing wallets to proactively request user permissions for better UX.

CAIP-372 compatible discovery​

New InitialAPI type includes rdns (reverse DNS identifier), name, icon, and apiVersion for standardized wallet discovery compatible with the CAIP-372 draft specification.


New features requiring configuration updates​

Below is a detailed breakdown of the new features requiring configuration updates.

Network-aware connection​

All DApps must update their connection logic to specify the target network. This ensures DApps connect to the correct network and enables multi-network wallet support.

Required updates:

  • Replace wallet.enable() with wallet.connect(networkId).
  • Use 'preview' for Preview, 'mainnet' for Mainnet, other strings for test networks.

Improvements​

Below is a detailed breakdown of the improvements added in this release.

Granular balance methods​

Replaced single state() method with specific methods (getShieldedBalances, getUnshieldedBalances, getDustBalance) providing clearer semantics and enabling finer-grained permission control.

Granular address methods​

Separate methods for retrieving different address types (getShieldedAddresses, getUnshieldedAddress, getDustAddress) with Bech32m encoding.

Type-based architecture​

Moved from interface/class-based design to TypeScript types, eliminating cross-boundary instanceof issues and reducing bundle size by removing the ts-custom-error dependency.

Enhanced transaction balancing​

Split transaction balancing into balanceUnsealedTransaction and balanceSealedTransaction providing appropriate methods for different use cases.


Deprecations​

Here is a list of deprecated features in this release.

Prover server URI​

  • Starts: v4.0.0
  • Full removal: v5.0.0 (planned)
  • Replacement: getProvingProvider() method

Migration steps:

  • Stop using proverServerUri in your configuration.
  • Use getProvingProvider(keyMaterialProvider) to obtain a proving provider.
  • Integrate with Midnight.js's ZKConfigProvider for key material resolution.

Breaking changes​

Below is a detailed breakdown of the breaking changes and required actions for developers.

Complete API redesign​

The entire API structure has been redesigned from interface-based to type-based architecture.

What breaks: All existing DApp integrations using v3.0.0 API.

Required actions:

  • Update all imports to use new type names.
  • Replace DAppConnectorAPI with InitialAPI.
  • Replace DAppConnectorWalletAPI with WalletConnectedAPI.
  • Replace DAppConnectorWalletState usage with individual method calls.

Code example:

// v3.0.0
const wallet: DAppConnectorAPI = window.midnight?.someWallet;
const enabled = await wallet.isEnabled();
const walletApi = await wallet.enable();
const state = await walletApi.state();
console.log(state.address);

// v4.0.0
const wallet: InitialAPI = window.midnight?.someWallet;
const connectedApi = await wallet.connect('preview');
const addresses = await connectedApi.getShieldedAddresses();
console.log(addresses.shieldedAddress);

Connection model​

Removed enable() and isEnabled() methods, replaced with connect(networkId).

What breaks: All connection logic in existing DApps.

Required actions:

  • Replace wallet.enable() with wallet.connect(networkId).
  • Remove isEnabled() checks; use getConnectionStatus() instead.
  • Provide network ID parameter (use 'preview' for Preview, 'mainnet' for Mainnet).

State access removal​

Removed state() method returning combined wallet state.

What breaks: Any code accessing state().address, state().coinPublicKey, etc.

Required actions:

  • Replace state() with appropriate granular methods.
  • Use getShieldedAddresses() for shielded address and keys.
  • Use getUnshieldedAddress() for unshielded address.
  • Use getShieldedBalances() / getUnshieldedBalances() for balances.

Code example:

// v3.0.0
const state = await walletApi.state();
const address = state.address;
const coinPubKey = state.coinPublicKey;

// v4.0.0
const { shieldedAddress, shieldedCoinPublicKey } = await connectedApi.getShieldedAddresses();

Transaction balancing​

Replaced balanceAndProveTransaction(tx, newCoins) with balanceUnsealedTransaction(tx) and balanceSealedTransaction(tx).

What breaks: All transaction balancing logic.

Required actions:

  • Determine if your use case needs unsealed (contract interactions) or sealed (swap completion) balancing.
  • Update method calls and handle string-based transaction format.
  • Remove newCoins parameter (no longer needed).

Code example:

// v3.0.0
const provedTx = await walletApi.balanceAndProveTransaction(tx, newCoins);

// v4.0.0
const { tx: balancedTx } = await connectedApi.balanceUnsealedTransaction(serializedTx);

APIError type​

APIError changed from a class extending CustomError to a type alias.

What breaks: instanceof APIError checks.

Required actions:

  • Replace error instanceof APIError with error.type === 'DAppConnectorAPIError'.
  • Update error handling logic.

Code example:

// v3.0.0
try {
await walletApi.submitTransaction(tx);
} catch (error) {
if (error instanceof APIError) {
console.log(error.code);
}
}

// v4.0.0
try {
await connectedApi.submitTransaction(tx);
} catch (error) {
if (error.type === 'DAppConnectorAPIError') {
console.log(error.code);
}
}

Configuration interface​

ServiceUriConfig renamed to Configuration, added networkId, made proverServerUri optional and deprecated.

What breaks: Code importing or using ServiceUriConfig.

Required actions:

  • Update imports to use Configuration type.
  • Handle optional proverServerUri.
  • Validate networkId matches expected network.

Removed dependencies​

Removed @midnight-ntwrk/wallet-api and @midnight-ntwrk/zswap as dependencies.

What breaks: Type imports that relied on these transitive dependencies.

Required action: Update transaction types to use string serialization format.