useBatchTx
Submit several calls as one transaction via Utility.batch_all
useBatchTx is useTx for multiple calls at once: your
build callback returns an array of calls built against the typed api, and
submit(build, options?) wraps them in a single Utility.batch_all
transaction. One signature, one fee payment, atomic by default. The lifecycle
matches useTx, including phase:
"idle" → "signing" → "broadcasting" → "in-block" → "finalized" | "error".
On first submit the hook requests the ChainSubmit permission and connects
the signer if needed. The resolved TxResult reports dispatch failures as
data: check result.ok. In the default atomic mode a single failing call
reverts the whole batch and dispatchError carries the reason.
Usage
import { useBatchTx } from "@use-truapi/react";
import { MultiAddress } from "@polkadot-api/descriptors";
function PaySplit({ recipients, value }: { recipients: string[]; value: bigint }) {
const { submit, phase, isPending, error } = useBatchTx();
async function onPayAll() {
const result = await submit((api) =>
recipients.map((dest) =>
api.tx.Balances.transfer_keep_alive({
dest: MultiAddress.Id(dest),
value,
}),
),
);
if (!result.ok) console.error("batch reverted", result.dispatchError);
}
return (
<>
<button type="button" onClick={onPayAll} disabled={isPending}>
{isPending ? phase : `Pay ${recipients.length} recipients`}
</button>
{error && <p role="alert">{error.message}</p>}
</>
);
}<script setup lang="ts">
import { useBatchTx } from "@use-truapi/vue";
import { MultiAddress } from "@polkadot-api/descriptors";
const props = defineProps<{ recipients: string[]; value: bigint }>();
const { submit, phase, isPending, error } = useBatchTx();
async function onPayAll() {
const result = await submit((api) =>
props.recipients.map((dest) =>
api.tx.Balances.transfer_keep_alive({
dest: MultiAddress.Id(dest),
value: props.value,
}),
),
);
if (!result.ok) console.error("batch reverted", result.dispatchError);
}
</script>
<template>
<button type="button" :disabled="isPending" @click="onPayAll">
{{ isPending ? phase : `Pay ${recipients.length} recipients` }}
</button>
<p v-if="error" role="alert">{{ error.message }}</p>
</template>The calls don't have to target the same pallet; anything buildable against the typed api can go in the array:
const result = await submit((api) => [
api.tx.Balances.transfer_keep_alive({ dest: MultiAddress.Id(dest), value }),
api.tx.System.remark({ remark: Binary.fromText("paid invoice #42") }),
]);submit accepts all of useTx's submit options (waitFor, onStatus) plus
mode, which picks the Utility wrapper:
"batch_all"(default): atomic, if any call fails all calls revert."batch": stops at the first failure, earlier calls stay applied."force_batch": keeps executing the remaining calls after failures.
const result = await submit(buildCalls, {
mode: "force_batch",
waitFor: "finalized",
});To build against a specific chain, pass its key; the build callback then
receives that chain's typed api:
const { submit } = useBatchTx({ chain: "people" });reset() clears the mutation state and returns phase to "idle".
See also
useTxsubmits a single transaction with the same lifecycle.
API reference
React
function useBatchTx<K>(options?): UseBatchTxResult<K>;Like useTx but wraps the built calls in Utility.batch_all (atomic by default).
Type Parameters
| Type Parameter | Default type |
|---|---|
K extends string | string |
Parameters
| Parameter | Type |
|---|---|
options? | { chain?: K; mutation?: MutationOptions<TxResult, TxVariables<K, BatchableCall[], SubmitOptions & object>>; } |
options.chain? | K |
options.mutation? | MutationOptions<TxResult, TxVariables<K, BatchableCall[], SubmitOptions & object>> |
Returns
UseBatchTxResult<K>
Extends
Omit<NamedMutation<TxResult,TxVariables<K,AnyBatchCall[],SubmitOptions&object>>,"reset">
Type Parameters
| Type Parameter |
|---|
K extends ChainKey |
Properties
context
context: unknown;Inherited from
Omit.contextdata
data: TxResult | undefined;The last successfully resolved data for the mutation.
Inherited from
Omit.dataerror
error: Error | null;The error object for the mutation, if an error was encountered.
- Defaults to
null.
Inherited from
Omit.errorfailureCount
failureCount: number;Inherited from
Omit.failureCountfailureReason
failureReason: Error | null;Inherited from
Omit.failureReasonisError
isError: boolean;A boolean variable derived from status.
trueif the last mutation attempt resulted in an error.
Inherited from
Omit.isErrorisIdle
isIdle: boolean;A boolean variable derived from status.
trueif the mutation is in its initial state prior to executing.
Inherited from
Omit.isIdleisPaused
isPaused: boolean;Inherited from
Omit.isPausedisPending
isPending: boolean;A boolean variable derived from status.
trueif the mutation is currently executing.
Inherited from
Omit.isPendingisSuccess
isSuccess: boolean;A boolean variable derived from status.
trueif the last mutation attempt was successful.
Inherited from
Omit.isSuccessphase
phase: TxPhase;reset
reset: () => void;Returns
void
status
status: "idle" | "success" | "error" | "pending";The status of the mutation.
- Will be:
idleinitial status prior to the mutation function executing.pendingif the mutation is currently executing.errorif the last mutation attempt resulted in an error.successif the last mutation attempt was successful.
Inherited from
Omit.statussubmit
submit: (build, options?) => Promise<TxResult>;Parameters
| Parameter | Type |
|---|---|
build | (api) => BatchableCall[] | Promise<BatchableCall[]> |
options? | SubmitOptions & object |
Returns
Promise<TxResult>
submittedAt
submittedAt: number;Inherited from
Omit.submittedAtvariables
variables:
| TxVariables<K, BatchableCall[], SubmitOptions & object>
| undefined;The variables object passed to the mutationFn.
Inherited from
Omit.variablesVue
function useBatchTx<K>(options?): UseBatchTxResult<K>;Like useTx but wraps the built calls in Utility.batch_all (atomic by default).
Type Parameters
| Type Parameter | Default type |
|---|---|
K extends string | string |
Parameters
| Parameter | Type |
|---|---|
options? | { chain?: K; mutation?: MutationOptions<TxResult, TxVariables<K, BatchableCall[], SubmitOptions & object>>; } |
options.chain? | K |
options.mutation? | MutationOptions<TxResult, TxVariables<K, BatchableCall[], SubmitOptions & object>> |
Returns
UseBatchTxResult<K>