Skip to main content
Query token balances by Spark address using the SparkReadonlyClient. Public queries respect privacy mode: if a wallet is private, unauthenticated requests return empty results.
Holders

Your Balance

Check how many tokens you hold:
const balances = await wallet.getIssuerTokenBalances();
for (const { tokenIdentifier, balance } of balances) {
  if (!tokenIdentifier) continue;
  console.log(tokenIdentifier, balance);
}

Check Any Address

Pass an address to check someone else’s balance:
import { SparkReadonlyClient } from "@buildonspark/spark-sdk";

const client = SparkReadonlyClient.createPublic({ network: "MAINNET" });

const [tokenIdentifier] = await wallet.getIssuerTokenIdentifiers();
if (!tokenIdentifier) throw new Error("No token identifiers found for this issuer");

const holderBalances = await client.getTokenBalance("spark1abc...", [tokenIdentifier]);
const info = holderBalances.get(tokenIdentifier);

console.log("User balance:", info?.ownedBalance);

Display Amounts

Convert base units to human-readable format:
const holderBalances = await client.getTokenBalance("spark1abc...", [tokenIdentifier]);
const info = holderBalances.get(tokenIdentifier);
if (!info) throw new Error("No balance found (zero balance, unknown token, or privacy mode)");

function formatUnits(amount: bigint, decimals: number): string {
  const negative = amount < 0n;
  const value = negative ? -amount : amount;
  const base = 10n ** BigInt(decimals);
  const whole = value / base;
  const fraction = value % base;

  const fractionStr = fraction.toString().padStart(decimals, "0").replace(/0+$/, "");
  const out = fractionStr ? `${whole.toString()}.${fractionStr}` : whole.toString();
  return negative ? `-${out}` : out;
}

console.log(`${formatUnits(info.ownedBalance, info.tokenMetadata.decimals)} ${info.tokenMetadata.tokenTicker}`);

All Token Balances

Get all token balances for an address:
const tokenBalances = await client.getTokenBalance("spark1abc...");

function formatUnits(amount: bigint, decimals: number): string {
  const negative = amount < 0n;
  const value = negative ? -amount : amount;
  const base = 10n ** BigInt(decimals);
  const whole = value / base;
  const fraction = value % base;

  const fractionStr = fraction.toString().padStart(decimals, "0").replace(/0+$/, "");
  const out = fractionStr ? `${whole.toString()}.${fractionStr}` : whole.toString();
  return negative ? `-${out}` : out;
}

for (const [tokenId, info] of tokenBalances) {
  console.log(`${info.tokenMetadata.tokenTicker}: ${formatUnits(info.ownedBalance, info.tokenMetadata.decimals)}`);
}

Listen for Changes

Get notified when balances change:
wallet.on("transfer:claimed", async (transferId, newBalance) => {
  console.log("Transfer received:", transferId);
  
  const updated = await wallet.getBalance();
  console.log("New balance:", updated.balance);
});