# Batching

ensforge has separate batching models for reads and writes. Reads use Multicall when calls are
compatible. Writes use wallet call capabilities when available and preserve a sequential fallback.

## Batch reads

Create requests through methods in any group, then execute them through `sdk.batch.readBatch`.

:::code-group
```ts [profile.ts]
import { sdk } from "./client";

const profile = await sdk.batch.readBatch({
  owner: sdk.name.getOwner.request({ name: "sdk.eth" }),
  resolver: sdk.resolution.getResolver.request({ name: "sdk.eth" }),
  avatar: sdk.records.getAvatar.request({ name: "sdk.eth" }),
});

profile.owner;
profile.resolver;
profile.avatar;
```

```ts [client.ts]
// [!include ~/snippets/sdk/client.ts]
```
:::

The result object retains the key and result type of every request. Compatible direct contract reads
are grouped by chain, block context, and Multicall requirements. CCIP Read and other incompatible
requests execute through their required transport path.

## Settle reads independently

Use `readBatchSettled` when one failure should not discard successful entries.

```ts
const results = await sdk.batch.readBatchSettled({
  owner: sdk.name.getOwner.request({ name }),
  avatar: sdk.records.getAvatar.request({ name }),
});

if (results.avatar.status === "failure") {
  console.error(results.avatar.cause);
}
```

## Batch writes

Write methods expose `.call`, which prepares calldata without submitting it.

```ts
const calls = [
  sdk.records.setText.call({ name, key: "url", value: url }),
  sdk.records.setText.call({ name, key: "com.github", value: github }),
];

const result = await sdk.batch.sendCalls({
  calls,
  mode: "auto",
});
```

In `auto` mode, ensforge inspects wallet capabilities. It uses wallet call batching when supported
and otherwise executes the prepared calls sequentially. Sequential fallback is **not atomic**: an
earlier transaction can succeed before a later transaction fails.

## Prepare and inspect first

```ts
const prepared = await sdk.batch.prepareCalls({ calls });
const simulations = await sdk.batch.simulateCalls({ calls: prepared });
```

Use this path when the application needs to display targets, values, estimated gas, or simulation
failures before requesting wallet approval.

See the Core [Batching guide](/core/guides/batching) for grouping, CCIP Read, capability, and
atomicity details.
