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],
});
ESC
Type to search