# EIP-5792 call batches: one request, several calls

> EIP-5792 lets an app ask a wallet to send several calls at once and poll their status. What the batch id and status codes mean, and when calls are atomic.

Source: https://hashspan.dev/learn/eip-5792-call-batches

## Short answer

EIP-5792 adds wallet methods for sending several calls in one request, wallet_sendCalls, and for checking them, wallet_getCallsStatus. The wallet returns a batch id instead of a transaction hash, then reports a status code: 100 pending, 200 confirmed, 400 failed offchain, 500 reverted completely, 600 reverted partially. Whether the calls ran atomically is the wallet's answer, not a given.

Figure: EIP-5792 call batches: wallet_sendCalls returns a batch id rather than a transaction hash, wallet_getCallsStatus reports codes 100 to 600, and in a local run with viem's fallback hashspan recorded one send span, a confirm span for the batch and one per transaction.

## Why batch calls?

An agent that approves a token and then spends it makes two calls that belong together. Sent one by one, the second can fail after the first went through, and the agent sees two unrelated transactions.

EIP-5792 lets the app send both in one request ([EIP-5792](https://eips.ethereum.org/EIPS/eip-5792)). The wallet decides how to execute them, and reports back through one id.

## What comes back?

Not a transaction hash. `wallet_sendCalls` returns a **batch id**, and `wallet_getCallsStatus` reports progress for it:

| Code | Meaning |
|---|---|
| 100 | Pending: received, not yet complete on chain |
| 200 | Confirmed: included without reverts |
| 400 | Failed offchain: not included, and the wallet won't retry |
| 500 | Reverted completely: only gas charges may be on chain |
| 600 | Reverted partially: some calls' changes may be on chain |

The status response also carries the receipts the wallet knows about, and `atomic`: whether the calls ran together, with nothing in between.

## What if the wallet doesn't support it?

viem can fall back. With `experimental_fallback`, `sendCalls` sends the calls as plain transactions, one after another, when the wallet doesn't implement `wallet_sendCalls`. They are not atomic then.

We ran that on a local chain: two transfers in one `sendCalls`, against a node without EIP-5792. viem sent two transactions, in blocks 3 and 4, and `waitForCallsStatus` reported code 200 with two receipts. The batch id viem made up for them is longer than a hash: it encodes both transaction hashes.

**In a hashspan trace:**
Since 0.9, `@hashspan/viem` traces `sendCalls`, `waitForCallsStatus` and `sendCallsSync` ([ADR 0022](https://github.com/selimaytac/hashspan/blob/main/docs/adr/0022-call-batches.md)). From the local run above:

  - `send 31337`: `blockchain.call_batch.id`, `.sender`, `.call_count` `2`
  - `confirm 31337`: `blockchain.call_batch.status` `success`, `.status_code` `200`, `.atomic` `false`, `.transaction_hashes` with both hashes, `blockchain.block.number` `4`
  - one more `confirm 31337` per fallback transaction, linked to the batch's send span, each with its own fee

The batch's confirm span records no fee; the fallback transactions' confirm spans carry theirs. Status 400 ends it with `error.type` `failed`. The [call batch attributes](https://hashspan.dev/docs/reference/attributes/call-batches) list every field.

## FAQ

### Is the batch id a transaction hash?

No. It's an identifier the wallet chose for the batch. The transactions behind it, if any, show up in the status response's receipts.

### Are the calls in a batch atomic?

Only if the wallet says so. An app can ask for atomic execution, and the status response tells whether the wallet ran them atomically.

### What does status 600 mean?

The batch reverted partially: some of its calls' changes may be on chain, others not.
