BluxBlux

Read Contracts

Read state from Soroban smart contracts by simulating contract calls.

readContracts is a Soroban helper that reads data from one or more smart contracts. It builds each call, simulates it against the network (no signature, no fee, no on-chain state change), and returns the decoded results. Use it for any read-only contract method — token balances, metadata, pool reserves, configuration, and so on.

It accepts an array of calls and runs them in parallel, so you can batch several reads in a single request. For one call, use readContract — it takes a single call and returns { raw, value } instead of arrays.

readContracts simulates against a null source account, so it never spends fees or requires the user to be connected. For methods that mutate state, use writeContract.

Type

type IContractCall = {
  address: string;   // C… contract ID, SEP-2 address, or .xlm name
  fn: string;        // function name to invoke
  args: unknown[];   // native values in the function's positional order
};

type ReadContractsOptions = {
  network?: string;    // Omit to use the active network
};

// Returns the simulation objects and the decoded native values,
// index-aligned with the calls you passed in.
type ReadContractsResult<TValues extends readonly unknown[]> = {
  raws: SimulateTransactionResponse[];
  values: TValues;
};

const readContracts: <TValues extends readonly unknown[] = readonly unknown[]>(
  calls: IContractCall[],
  options?: ReadContractsOptions,
) => Promise<ReadContractsResult<TValues>>;

Native contract arguments

Pass ordinary JavaScript values in the same order as the contract function's parameters. Blux loads the deployed contract spec and encodes every value as the declared Soroban type, so args does not require the ToScVal class.

args: [
  "alice.xlm",      // resolved and encoded when the spec declares Address
  "1000000000",     // encoded as i128 when the spec declares i128
  true,              // encoded as bool when the spec declares bool
]

Common native values include:

Soroban parameterJavaScript value
Address, string, or symbolstring
Booleanboolean
IntegerSafe number, bigint, or decimal string
BytesUint8Array
Vector or tupleArray
MapMap or an array of [key, value] entries
StructAn object or tuple matching the contract definition

For wide integers such as i128, prefer a bigint or decimal string so the value cannot lose precision. Argument count, order, and shape must still match the contract spec.

Address-typed values accept G…, C…, SEP-2 federation addresses, and .xlm names. Resolution also works when an ABI Address is nested in an option, vector, tuple, map, struct, or union. See address resolution.

Existing code may continue passing pre-encoded xdr.ScVal arguments. Native values and pre-encoded values can also be mixed, but manual encoding is no longer required.

Usage

Read a single value — for example a token's balance:

import { core } from "@bluxcc/core";

const { values } = await core.readContracts<[string]>([
  {
    address: "CB64D3G7SM2RTH6JSGG34DDTFTQ5CFDKVDZJZSODMCX4NJ2HV2KN7OG",
    fn: "balance",
    args: ["alice.xlm"],
  },
]);

console.log(values[0]); // decoded balance, e.g. "1000000000"

Batch several reads at once — results are index-aligned with the calls:

import { core } from "@bluxcc/core";

const TOKEN = "CB64D3G7SM2RTH6JSGG34DDTFTQ5CFDKVDZJZSODMCX4NJ2HV2KN7OG";

const { values } = await core.readContracts<[string, number, string]>([
  { address: TOKEN, fn: "name", args: [] },
  { address: TOKEN, fn: "decimals", args: [] },
  { address: TOKEN, fn: "balance", args: ["GA...USER"] },
]);

const [name, decimals, balance] = values;

Return types

The deployed ABI is loaded at runtime, so TypeScript cannot infer a return type from runtime address, fn, and network strings. Pass one tuple generic for the batch, in the same order as the calls:

const result = await core.readContracts<[string, number, string]>(calls);

result.values[0]; // string
result.values[1]; // number
result.values[2]; // string

Omit the generic when the return shapes are not known; values are then readonly unknown[]. Include null in an entry's type when that function can return no value.

bigint results are returned as strings so they're safe to serialize. The raw simulation objects are available under raws if you need footprint or resource details.

On this page