use-truapi
Transactions

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

  • useTx submits 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 ParameterDefault type
K extends stringstring

Parameters

ParameterType
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.context

data

data: TxResult | undefined;

The last successfully resolved data for the mutation.

Inherited from
Omit.data

error

error: Error | null;

The error object for the mutation, if an error was encountered.

  • Defaults to null.
Inherited from
Omit.error

failureCount

failureCount: number;
Inherited from
Omit.failureCount

failureReason

failureReason: Error | null;
Inherited from
Omit.failureReason

isError

isError: boolean;

A boolean variable derived from status.

  • true if the last mutation attempt resulted in an error.
Inherited from
Omit.isError

isIdle

isIdle: boolean;

A boolean variable derived from status.

  • true if the mutation is in its initial state prior to executing.
Inherited from
Omit.isIdle

isPaused

isPaused: boolean;
Inherited from
Omit.isPaused

isPending

isPending: boolean;

A boolean variable derived from status.

  • true if the mutation is currently executing.
Inherited from
Omit.isPending

isSuccess

isSuccess: boolean;

A boolean variable derived from status.

  • true if the last mutation attempt was successful.
Inherited from
Omit.isSuccess

phase

phase: TxPhase;

reset

reset: () => void;
Returns

void


status

status: "idle" | "success" | "error" | "pending";

The status of the mutation.

  • Will be:
    • idle initial status prior to the mutation function executing.
    • pending if the mutation is currently executing.
    • error if the last mutation attempt resulted in an error.
    • success if the last mutation attempt was successful.
Inherited from
Omit.status

submit

submit: (build, options?) => Promise<TxResult>;
Parameters
ParameterType
build(api) => BatchableCall[] | Promise<BatchableCall[]>
options?SubmitOptions & object
Returns

Promise<TxResult>


submittedAt

submittedAt: number;
Inherited from
Omit.submittedAt

variables

variables: 
  | TxVariables<K, BatchableCall[], SubmitOptions & object>
  | undefined;

The variables object passed to the mutationFn.

Inherited from
Omit.variables

Vue

function useBatchTx<K>(options?): UseBatchTxResult<K>;

Like useTx but wraps the built calls in Utility.batch_all (atomic by default).

Type Parameters

Type ParameterDefault type
K extends stringstring

Parameters

ParameterType
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>

On this page