Early Access The dStorage SDK is under active development (v0.0.x). APIs may still change — it's safe to follow the guides, but hold off on production use for now.
Skip to content

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?

sh
docker run -p 6300:6300 midnightntwrk/proof-server:8.0.3 -- midnight-proof-server -v

How do I start a local Arweave node for testing?

sh
docker run -d --rm -p 1984:1984 textury/arlocal
# or: npx arlocal

No 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:

typescript
{
  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):

typescript
{
  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?

typescript
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:

typescript
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 reads keys/ and zkir/ from that directory. Resolve the bundled copy via the package's own package.json rather than hardcoding a node_modules path:
    typescript
    import { 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/ and zkir/ from node_modules/@dstorage-tech/dstorage-sdk/dist/contracts/dataregistry/managed/ into your application's public assets directory, then pass zkConfigBaseUrl: window.location.origin. Artifacts are fetched over HTTP. (The starter-template's npm run dev does this automatically — see scripts/copy-zk-artifacts.mjs.)