---
url: https://dstorage.pro/docs/guide/local-simulator-adapters.md
---
# Local & Simulator Adapters

The [Mock Adapters](/guide/mock-adapters) guide used fully in-memory adapters. This guide swaps
them for `ArweaveLocalStorageAdapter` and `MidnightSimulatorChainAdapter` — adapters that behave
like the real thing (real network calls to a local Arweave node, and real execution of the
DataRegistry contract) but still need no Midnight proof server, no wallet extension, and no real
tokens.

This is a good next step once Mock Adapters feels too simplified: `refId` values now use the
real circuit-derived format, and ownership checks run exactly as they would against the live
chain — so tests written against these adapters exercise realistic behavior.

## Prerequisites

* Node.js 22 or later
* [arlocal](https://github.com/textury/arlocal) — a local Arweave-compatible node
* No Midnight proof server, wallet extension, or DUST tokens needed —
  `MidnightSimulatorChainAdapter` runs the real `DataRegistry` circuits in-process

Fast track: clone [`dstorage-starter-template`](https://github.com/dStorageTech/dstorage-starter-template) and wire up this guide's adapters in minutes.

## Step 1 — Start arlocal

```sh
docker run -d --rm -p 1984:1984 textury/arlocal
# or, without Docker:
npx arlocal
```

No real AR tokens are needed — arlocal auto-funds test wallets.

Once you've finished working through this guide, stop arlocal so it doesn't keep running in the
background. If you started it with `npx arlocal`, press Ctrl+C in that terminal. If you
started it with Docker, run:

```sh
docker stop $(docker ps -q --filter ancestor=textury/arlocal)
```

The `--rm` flag used when starting the container cleans it up automatically once stopped.

## Step 2 — Configure the SDK

This guide keeps the same three-adapter shape from Mock Adapters, but swaps two of them out for
versions that behave like the real thing — only `encryptionAdapters` stays as-is:

* **`storageAdapters`** — `ArweaveLocalStorageAdapter.createWithTestWallet()` replaces
  `MockStorageAdapter`. It generates a fresh, disposable JWK test wallet (not connected to real
  funds) and funds it with test AR against your running arlocal instance.
* **`chainAdapters`** — `MidnightSimulatorChainAdapter` replaces `MockChainAdapter`, running the
  real `DataRegistry` contract logic in-process instead of simulating it in memory. It's still
  not talking to the Midnight network — no node, indexer, or proof server involved — just a much
  more faithful in-process simulator than `MockChainAdapter`'s.
* **`encryptionAdapters`** — unchanged. `PasswordEncryptionAdapter` still protects the per-upload
  encryption key exactly as it did in the Mock Adapters guide.

```typescript
import {
  DStorage,
  ArweaveLocalStorageAdapter,
  MidnightSimulatorChainAdapter,
  PasswordEncryptionAdapter,
} from "@dstorage-tech/dstorage-sdk";

const { adapter: storageAdapter } = await ArweaveLocalStorageAdapter.createWithTestWallet({
  fundAr: 5, // amount of test AR to fund the generated wallet with
});

const sdk = new DStorage({
  storageAdapters: [storageAdapter],
  chainAdapters: [new MidnightSimulatorChainAdapter()],
  encryptionAdapters: [
    new PasswordEncryptionAdapter({
      password: "Correct-Horse-Battery!",
      salt: "myapp:v1",
    }),
  ],
});
```

## Step 3 — Init, store, retrieve

The API is identical to the Mock Adapters guide — that's the point, adapters are interchangeable:

```typescript
await sdk.init();

const { chainRefId } = await sdk.store(
  new TextEncoder().encode("hello, dStorage"),
);

const { bytes } = await sdk.retrieveByRefId(chainRefId);
console.log(new TextDecoder().decode(bytes)); // "hello, dStorage"
```

What's different from Mock under the hood:

* **`chainRefId`** is now generated by running the real `DataRegistry` contract logic — a 32-byte
  hex ID, not the random placeholder ID that `MockChainAdapter` uses.
* **Ownership checks** are enforced by the simulator just as they would be by the real contract
  running on the Midnight network, so tests here catch ownership bugs that Mock's simplified
  checks would miss.
* **Uploads are sent over the network** to your local arlocal instance, instead of just being
  held in memory like `MockStorageAdapter` did.
* **`storageId`** is now a real Arweave transaction ID in your local arlocal instance, instead of
  a random placeholder — it's not on the real Arweave network, but it can actually be looked up
  there.

## Learn More

* Browse the [FAQ](/faq/adapters#adapters) for the full adapter reference.
* Next: [Managed Payments Service](/guide/managed-payments-service) routes this guide's storage
  and chain payments through dStorage Pro's `TEST` sandbox service.
