useTokenMetadata
Read a SEP-41 token / Stellar Asset Contract's metadata in React, powered by TanStack Query.
useTokenMetadata is the React wrapper around getTokenMetadata. It reads a SEP-41 token / Stellar Asset Contract's decimals, name, symbol, and owner by simulating the contract's read-only entrypoints — no account, signing, or fees — and exposes the result as a TanStack Query, so you get caching, refetching, and loading states for free.
The read works for any contract id, deployed or not yet funded. owner is undefined for contracts without an owner() function (notably Stellar Asset Contracts, which expose admin() instead). The query stays disabled until a non-empty address is provided, which makes it easy to chain after useSacAddress.
Import
import { useTokenMetadata } from "@bluxcc/react";Usage
Read a token contract directly:
import { useTokenMetadata } from "@bluxcc/react";
function TokenInfo() {
const { data, isLoading, error } = useTokenMetadata(
"CB64D3G7SM2RTH6JSGG34DDTFTQ5CFDKVDZJZSODMCX4NJ2HV2KN7OG",
);
if (isLoading) return <p>Loading…</p>;
if (error) return <p>{error.message}</p>;
// data → { decimals: 7, name: "USD Coin", symbol: "USDC", owner?: "G…" }
return <p>{data?.name} ({data?.symbol})</p>;
}root.render(
<BluxProvider
config={{
appName: "MyApp",
networks: [networks.testnet, networks.mainnet],
}}
>
<App />
</BluxProvider>
);Derive a classic asset's SAC, then read it
Pair it with useSacAddress to read a classic asset's metadata. Keep the query disabled until the SAC id is known:
import { useSacAddress, useTokenMetadata } from "@bluxcc/react";
function ClassicAsset() {
const { data: sac } = useSacAddress("USDC:GA5Z....KZVN");
const { data: meta } = useTokenMetadata(sac ?? "", undefined, {
enabled: Boolean(sac),
});
return <p>{meta?.symbol} · {meta?.decimals} decimals</p>;
}root.render(
<BluxProvider
config={{
appName: "MyApp",
networks: [networks.testnet, networks.mainnet],
}}
>
<App />
</BluxProvider>
);You can pass core options (currently just network) and TanStack Query options as the second and third arguments:
import { useTokenMetadata, networks } from "@bluxcc/react";
const { data } = useTokenMetadata(
"CB64...N7OG",
{ network: networks.mainnet }, // core options
{ enabled: true, staleTime: 60000 }, // TanStack options
);Always pass the address first, then core options, then TanStack Query options. The hook relies on this order to work correctly.
Parameters
address (required)
string
The token contract id (C…), e.g. a SAC from useSacAddress / getSacAddress. The query is disabled while this is empty.
network
string | undefined
Passed as { network } in the second argument. The network to read from. Import networks from @bluxcc/react to select one. Omit to use the active network.
Query Options
These are passed as the third argument and map directly to TanStack Query options.
| Option | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Set to false to disable automatic fetching. Also auto-disabled while address is empty. |
staleTime | number | Infinity | 0 | Time in ms before data is considered stale |
gcTime | number | Infinity | 300000 | Time in ms before inactive cache data is garbage collected |
retry | boolean | number | 3 | How many times to retry on failure |
retryDelay | number | function | — | Delay in ms between retry attempts |
refetchInterval | number | false | function | — | Continuously refetch at this interval in ms |
refetchOnMount | boolean | 'always' | true | Refetch on component mount if data is stale |
refetchOnWindowFocus | boolean | 'always' | true | Refetch when the window regains focus |
refetchOnReconnect | boolean | 'always' | true | Refetch when network reconnects |
refetchIntervalInBackground | boolean | — | Keep refetching even when tab is in background |
placeholderData | TokenMetadata | function | — | Placeholder data shown while query is pending (not persisted to cache) |
initialData | TokenMetadata | function | — | Initial data for the cache (persisted) |
initialDataUpdatedAt | number | function | — | Timestamp of when initialData was last updated |
select | function | — | Transform or select a subset of the returned data |
notifyOnChangeProps | string[] | 'all' | — | Limit re-renders to specific property changes |
structuralSharing | boolean | function | true | Retain references from old data for performance |
networkMode | 'online' | 'always' | 'offlineFirst' | 'online' | Controls when queries can run relative to network status |
meta | Record<string, unknown> | — | Attach arbitrary metadata to the query cache entry |
queryClient | QueryClient | — | Use a custom QueryClient instead of the nearest context one |
Return Type
data
TokenMetadata | undefined
type TokenMetadata = {
decimals: number; // number of decimal places the token uses
name: string; // human-readable token name
symbol: string; // token symbol / code
owner?: string; // owner() when present; undefined for a SAC
};Status Booleans
| Property | Type | Description |
|---|---|---|
isPending | boolean | No cached data and no completed fetch yet |
isSuccess | boolean | Query resolved successfully |
isError | boolean | Query failed |
isLoading | boolean | First fetch in-flight (isFetching && isPending) |
isFetching | boolean | Query function is currently executing |
isRefetching | boolean | Background refetch in progress |
isFetched | boolean | Query has been fetched at least once |
isFetchedAfterMount | boolean | Query fetched after component mounted |
isStale | boolean | Cached data is stale or older than staleTime |
isPlaceholderData | boolean | Currently showing placeholder data |
isLoadingError | boolean | Failed on the first fetch |
isRefetchError | boolean | Failed during a background refetch |
isPaused | boolean | Query wanted to fetch but was paused |
Other Returns
| Property | Type | Description |
|---|---|---|
status | 'pending' | 'success' | 'error' | Current query status |
fetchStatus | 'fetching' | 'idle' | 'paused' | Current fetch status |
error | null | Error | Error object if the query failed |
dataUpdatedAt | number | Timestamp of last successful fetch |
errorUpdatedAt | number | Timestamp of last error |
errorUpdateCount | number | Total number of errors |
failureCount | number | Failures since last success |
failureReason | null | Error | Reason for last retry failure |
refetch | function | Manually trigger a refetch |
This is a read-only simulation, so the user does not need to be connected. See getTokenMetadata for the BLUX: errors that surface on error.