transactBatch
results[i] is { status: "fulfilled", value: TransactResult } or { status: "rejected", reason },
in input order — a failed row leaves the others untouched. approvals is how many times the wallet
was actually asked.
Every item runs the same transact flow it would have run alone, up to the point where it would sign,
then waits. Proofs are computed concurrently (proofConcurrency, default 2) so they all exist before
the user is prompted; items are then released to submit submitConcurrency at a time (default 3).
Why a second prompt can appear
A stale-root retry re-proves, which changes that item’s digest, so it cannot be covered by the signature already given. Every item that had to re-prove is signed together in a new wave: one extra approval for the retries, never one per row. That is exactly whatapprovals counts — 1, plus one per wave. Surface it, so a second prompt
reads as what it is rather than as a bug.
Viewing-key registration, the other prompt on this path, is shared between flows that start together,
so a batch for a wallet that has not registered yet raises it once rather than N times.
Batching calls you already drive
If your code already callstransact, partialWithdraw or transfer per row, you can batch those
approvals without restructuring the rows. Give each call one item of a coordinator:
Limits
The practical batch size is lower than 64. The chain keeps a ring of the 100 most recent roots, and
items proved against one root push that root out of the ring as they land. Size a batch as
(100 − expected foreign inserts while it submits) / 2 and chunk above that; transactBatch throws
rather than truncate if you pass more than the maximum.
Related
- Request authentication — the single-request contract this builds on
- API reference — types and signatures
- UTXO transactions — the per-row flows being batched