BluxBlux

useReadContracts

Read state from Soroban smart contracts in React, powered by TanStack Query.

useReadContracts is the React wrapper around readContracts. It reads data from one or more Soroban smart contracts by simulating the calls (no signature, no fee) and exposes the result as a TanStack Query, so you get caching, refetching, and loading states for free.

Use useReadContract when you only need one call. Use useReadContracts when you want several reads at the same time — the results come back index-aligned with the calls you passed in.

Import

import { useReadContracts } from "@bluxcc/react";

Native contract arguments

Pass native JavaScript values in the contract function's positional order. The hook uses the deployed contract spec to encode each value as the declared Soroban type, so args does not require ToScVal.

Addresses, strings, and symbols are passed as strings; booleans as booleans; bytes as Uint8Array; and vectors or tuples as arrays. Integers accept safe numbers, bigint values, or decimal strings. Prefer bigint or a decimal string for wide integers such as i128.

The contract address and every value whose ABI type is Address also accept .xlm names and SEP-2 federation addresses, including nested address values. See address resolution.

Pre-encoded xdr.ScVal arguments remain supported, but manual encoding is optional.

Usage

Read a token's name, decimals, and a user's balance in one batch:

import { useReadContracts } from "@bluxcc/react";

const TOKEN = "CB64D3G7SM2RTH6JSGG34DDTFTQ5CFDKVDZJZSODMCX4NJ2HV2KN7OG";

function TokenInfo({ account }: { account: string }) {
  const { data, isLoading } = useReadContracts<[string, number, string]>([
    { address: TOKEN, fn: "name", args: [] },
    { address: TOKEN, fn: "decimals", args: [] },
    { address: TOKEN, fn: "balance", args: ["alice.xlm"] },
  ]);

  if (isLoading) return <p>Loading…</p>;

  const [name, decimals, balance] = data?.values ?? [];
  return <p>{name}: {balance}</p>;
}
root.render(
  <BluxProvider
    config={{
      appId: "your-app-id",
      appName: "MyApp",
      networks: [networks.testnet, networks.mainnet],
    }}
  >
    <App />
  </BluxProvider>
);

Return types

Runtime contract addresses and function names do not give TypeScript a compile-time ABI. Pass an array/tuple generic whose entries match the calls:

const query = useReadContracts<[string, number, string]>([
  { address: TOKEN, fn: "name", args: [] },
  { address: TOKEN, fn: "decimals", args: [] },
  { address: TOKEN, fn: "balance", args: ["alice.xlm"] },
]);

query.data?.values[2]; // string

Omit the generic for readonly unknown[], and include null for any call that may return no value.

You can pass network options and TanStack Query options (such as enabled) as the second and third arguments:

const { data } = useReadContracts(
  calls,
  { network: networks.mainnet },
  { enabled: isAuthenticated, staleTime: 60000 }
);

The hook returns the standard TanStack Query result. The contract data lives on data as { raws, values }, index-aligned with the calls you passed in.

On this page