Deployment & Configuration
What are the prerequisites for running the SDK locally?
- Node.js 22+, npm
- Docker (for Midnight proof server and Arweave Local)
- 1AM wallet extension (latest version) — or Lace, or another dApp Connector-compatible wallet (browser connector flows only)
- Wander wallet extension (Arweave browser flows only)
The DataRegistry contract ships pre-compiled with the SDK package (compiled circuits and keys included) — the Midnight Compact compiler is only needed if you're modifying the contract itself, not for normal SDK usage.
How do I start the local Midnight proof server?
docker run -p 6300:6300 midnightntwrk/proof-server:8.0.3 -- midnight-proof-server -vHow do I start a local Arweave node for testing?
docker run -d --rm -p 1984:1984 textury/arlocal
# or: npx arlocalNo real AR tokens are needed — arlocal auto-funds test wallets.
What Midnight networks does the adapter support?
Out of the box, with built-in default endpoints, undeployed (localhost), preprod, and preview. Any other network works too — pass its name as network and explicitly supply nodeEndpoint, nodeWsEndpoint, indexerEndpoint, indexerWsEndpoint, and proofServerEndpoint; the adapter only rejects a network name if defaults are missing and any of those endpoints are left unset.
How do I configure MidnightChainAdapter for browser vs Node.js?
Use the walletMode discriminated union:
Node.js (provider mode) — caller supplies a pre-built, synced WalletFacade:
{
walletMode: "provider",
walletProvider, // AdapterWalletProvider built and synced by the app
privateStatePassword, // password for local LevelDB state encryption
zkArtifactsPath, // optional: absolute path to keys/ and zkir/ dirs — the SDK
// ships its own compiled copy (see below), no separate compile needed
}Browser (connector mode) — delegates to a wallet extension (1AM, Lace, or another dApp Connector wallet):
{
walletMode: "connector",
connectorName: "1am", // wallet to prefer under window.midnight
zkConfigBaseUrl: window.location.origin, // base URL serving keys/ and zkir/
}walletMode is required.
Does WebAuthnPrfEncryptionAdapter work in a Node.js app?
Only partially. register() and authenticate() require real browser globals — window, navigator.credentials, PublicKeyCredential — and throw WEBAUTHN_PRF_UNAVAILABLE if they're missing, which is always the case in a plain Node.js process. isSupported() behaves the same way: it returns false (rather than throwing) whenever window is undefined.
So the interactive passkey ceremony only runs in a real browser tab, or in an Electron renderer process (which exposes those same browser globals) — never in a Node.js backend, CLI, or Electron main process.
The one part of the adapter that does work in Node is fromPublicKey(): it only needs raw public-key bytes and never touches WebAuthn, so a Node.js backend can use it for upload-only delegation on behalf of a browser-registered passkey owner (see WebAuthnPrfEncryptionAdapter in Adapters).
How do I configure ArweaveBundlerStorageAdapter for managed uploads?
new ArweaveBundlerStorageAdapter({
signingServerUrl: "https://dstorage.pro",
// Token format: <credential>.<base64url_modulus> — issued by the signing server.
// The modulus (512 bytes, base64url) is the server's RSA-4096 public key and is
// used to pin the expected signing key at construction time.
authToken: process.env.DSTORAGE_AUTH_TOKEN ?? "",
});How do I reuse an existing DataRegistry contract?
Pass the previously deployed address:
new MidnightChainAdapter({
contractAddress: "02abc123…",
// … rest of config
});Omit contractAddress to deploy a new contract on first init().
Where do ZK artifacts live and how are they served?
DataRegistry is dStorage's own fixed contract — not something you compile yourself. Its compiled ZK artifacts (prover/verifier keys and ZKIR) ship inside the @dstorage-tech/dstorage-sdk package at dist/contracts/dataregistry/managed/{keys,zkir}.
- Node.js: pass an absolute path via
zkArtifactsPath. The adapter readskeys/andzkir/from that directory. Resolve the bundled copy via the package's ownpackage.jsonrather than hardcoding anode_modulespath:typescriptimport { createRequire } from "node:module"; import path from "node:path"; const zkArtifactsPath = path.join( path.dirname(createRequire(import.meta.url).resolve("@dstorage-tech/dstorage-sdk/package.json")), "dist/contracts/dataregistry/managed", ); - Browser: copy
keys/andzkir/fromnode_modules/@dstorage-tech/dstorage-sdk/dist/contracts/dataregistry/managed/into your application's public assets directory, then passzkConfigBaseUrl: window.location.origin. Artifacts are fetched over HTTP. (Thestarter-template'snpm run devdoes this automatically — seescripts/copy-zk-artifacts.mjs.)