IPrivacy.batchTransfer
batchTransfer(
bytes32 batchId,
PrivacyTransferRequest[] requests
) external returns (bool success) Submits multiple shielded transfers under a single batchId, sharing preflight but producing an independent commitment append and event per item. Each item's PrivacyTransferRequest must set a valid expiresAtUnix; any expired item rejects the entire batch with a plain string revert (IPrivacy declares no typed custom errors). Batch gas is charged as a residual proof surcharge plus a fixed per-item cost.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
batchId | bytes32 | ✓ | A caller-supplied non-zero identifier that must be unique within the EVM transaction. Duplicates within one transaction revert with duplicate privacy batchId in EVM transaction. |
requests | PrivacyTransferRequest[] | ✓ | The batch items. Each request needs its own valid expiresAtUnix. The list must be non-empty and stay within the chain-configured batch size limit. |
Returns
Type:
bool Returns true on success. Any item failure reverts the whole batch.
Errors
| Code | Name | Description |
|---|---|---|
expiresAtUnix is required | expiresAtUnix is required | String revert. At least one item had expiresAtUnix == 0. |
transfer payload has expired | transfer payload has expired | String revert. At least one item's expiresAtUnix was at or before the current block time. |
privacy batch transfer requires at least one item | privacy batch transfer requires at least one item | String revert. requests was empty. |
invalid batchId | invalid batchId | String revert. batchId was zero. |
duplicate privacy batchId in EVM transaction | duplicate privacy batchId in EVM transaction | String revert. The same batchId was submitted twice in one EVM transaction. |
privacy batch output commitment already exists | privacy batch output commitment already exists | String revert. An output commitment in the batch collides with an existing on-chain commitment. |
Examples
Submitting a small batch with per-item expiry
Reusing a single expiresAtUnix across all batch items is fine — the check is per-item but does not require distinct values.
const nowSec = Math.floor(Date.now() / 1000);
const expiresAtUnix = BigInt(nowSec + 300);
const batchId = "0x2b9c1e5f8a1d40d7b7c9f0e13a8bd21e4c6a8e12f9d0b3e2f1a4c5b6d7e8f901" as const;
const requests = items.map((it) => ({
...it,
expiresAtUnix, // every item must set this
}));
await wallet.writeContract({
address: "0x100000000000000000000000000000000000000b",
abi: privacyAbi,
functionName: "batchTransfer",
args: [batchId, requests],
});