Skip to main content

useTokenPrice & useTokenPrices

Two standalone hooks for fetching real-time cryptocurrency prices. Neither requires OneProvider -- they can be used anywhere in your React tree.

Both hooks use PriceService internally, which provides:

  • Multi-source price aggregation with automatic fallback between providers.
  • Client-side caching to avoid redundant network requests within a short window.
  • Automatic retry on transient failures.

Import

import { useTokenPrice, useTokenPrices } from '@one_deploy/sdk';

useTokenPrice

Fetches the real-time USD price for a single token symbol.

Signature

function useTokenPrice(
symbol: string,
options?: UseTokenPriceOptions
): UseTokenPriceReturn;

Parameters

ParameterTypeRequiredDescription
symbolstringYesToken ticker symbol (e.g. 'ETH', 'BTC', 'USDC'). Case-insensitive.
optionsUseTokenPriceOptionsNoConfiguration for polling, currency, and API connection.

Options

interface UseTokenPriceOptions {
/** Target fiat currency for the price.
* Defaults to 'USD'. Supports ISO 4217 codes. */
currency?: string;

/** Enable automatic polling for price updates.
* Defaults to false. */
autoRefresh?: boolean;

/** Polling interval in milliseconds.
* Defaults to 30000 (30 seconds). Minimum: 5000. */
refreshInterval?: number;

/** Override the ONE Engine API URL. */
engineUrl?: string;

/** Your ONE project client ID (optional when inside OneProvider). */
clientId?: string;
}

Return Type

interface UseTokenPriceReturn {
/** The current price as a number, or null if not yet loaded. */
price: number | null;

/** Formatted price string (e.g. '3245.67'). */
priceFormatted: string | null;

/** The fiat currency the price is denominated in. */
currency: string;

/** 24-hour price change as a percentage (e.g. 2.34 for +2.34%). */
change24h: number | null;

/** Whether the initial fetch is in progress. */
isLoading: boolean;

/** Error object if the fetch failed, or null. */
error: OneSDKError | null;

/** Manually trigger a price refetch. */
refetch: () => Promise<void>;

/** ISO 8601 timestamp of the last successful update. */
lastUpdated: string | null;
}

Basic Usage

import { useTokenPrice } from '@one_deploy/sdk';

function EthPrice() {
const { price, change24h, isLoading, error } = useTokenPrice('ETH');

if (isLoading) return <span>Loading price...</span>;
if (error) return <span>Price unavailable</span>;

return (
<div>
<h2>ETH: ${price?.toLocaleString()}</h2>
<span style={{ color: (change24h ?? 0) >= 0 ? 'green' : 'red' }}>
{(change24h ?? 0) >= 0 ? '+' : ''}{change24h?.toFixed(2)}%
</span>
</div>
);
}

Live Price with Auto-Refresh

import { useTokenPrice } from '@one_deploy/sdk';

function LiveBtcPrice() {
const { price, priceFormatted, lastUpdated, isLoading } = useTokenPrice('BTC', {
autoRefresh: true,
refreshInterval: 10000, // update every 10 seconds
});

return (
<div>
<h3>BTC: ${priceFormatted ?? '...'}</h3>
{lastUpdated && <small>Updated: {new Date(lastUpdated).toLocaleTimeString()}</small>}
</div>
);
}

Price in a Different Currency

import { useTokenPrice } from '@one_deploy/sdk';

function EthEuroPrice() {
const { price, currency } = useTokenPrice('ETH', { currency: 'EUR' });

return <p>ETH: {price?.toLocaleString()} {currency}</p>;
}

useTokenPrices

Fetches prices for multiple tokens in a single batch request. More efficient than calling useTokenPrice multiple times.

Signature

function useTokenPrices(
symbols: string[],
options?: UseTokenPricesOptions
): UseTokenPricesReturn;

Parameters

ParameterTypeRequiredDescription
symbolsstring[]YesArray of token ticker symbols (e.g. ['ETH', 'BTC', 'USDC']).
optionsUseTokenPricesOptionsNoSame options as UseTokenPriceOptions.

Options

interface UseTokenPricesOptions {
/** Target fiat currency. Defaults to 'USD'. */
currency?: string;

/** Enable automatic polling. Defaults to false. */
autoRefresh?: boolean;

/** Polling interval in milliseconds. Defaults to 30000. */
refreshInterval?: number;

/** Override the ONE Engine API URL. */
engineUrl?: string;

/** Your ONE project client ID. */
clientId?: string;
}

Return Type

interface UseTokenPricesReturn {
/** Map of symbol to price data. */
prices: Record<string, TokenPriceData>;

/** Whether the initial fetch is in progress. */
isLoading: boolean;

/** Error object if the fetch failed, or null. */
error: OneSDKError | null;

/** Manually trigger a refetch for all symbols. */
refetch: () => Promise<void>;

/** ISO 8601 timestamp of the last successful batch update. */
lastUpdated: string | null;
}

interface TokenPriceData {
/** Token ticker symbol. */
symbol: string;

/** Current price as a number. */
price: number;

/** Formatted price string. */
priceFormatted: string;

/** The fiat currency the price is denominated in. */
currency: string;

/** 24-hour price change percentage. */
change24h: number;

/** 24-hour trading volume in fiat currency. */
volume24h: number;

/** Market capitalization in fiat currency. */
marketCap: number;
}

Basic Batch Usage

import { useTokenPrices } from '@one_deploy/sdk';

function PriceTable() {
const { prices, isLoading, error } = useTokenPrices(['ETH', 'BTC', 'USDC', 'USDT', 'SOL']);

if (isLoading) return <p>Loading prices...</p>;
if (error) return <p>Error: {error.message}</p>;

return (
<table>
<thead>
<tr>
<th>Token</th>
<th>Price</th>
<th>24h Change</th>
<th>Volume</th>
</tr>
</thead>
<tbody>
{Object.values(prices).map((p) => (
<tr key={p.symbol}>
<td>{p.symbol}</td>
<td>${p.priceFormatted}</td>
<td style={{ color: p.change24h >= 0 ? 'green' : 'red' }}>
{p.change24h >= 0 ? '+' : ''}{p.change24h.toFixed(2)}%
</td>
<td>${(p.volume24h / 1e6).toFixed(1)}M</td>
</tr>
))}
</tbody>
</table>
);
}

Live Dashboard with Auto-Refresh

import { useTokenPrices } from '@one_deploy/sdk';

const WATCHED_TOKENS = ['BTC', 'ETH', 'SOL', 'USDC', 'ARB', 'OP', 'MATIC'];

function PriceDashboard() {
const { prices, isLoading, lastUpdated, refetch } = useTokenPrices(WATCHED_TOKENS, {
autoRefresh: true,
refreshInterval: 15000,
});

return (
<div>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<h2>Market Prices</h2>
<div>
{lastUpdated && (
<small>Last update: {new Date(lastUpdated).toLocaleTimeString()}</small>
)}
<button onClick={refetch} disabled={isLoading}>Refresh</button>
</div>
</div>

<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, 200px)', gap: 16 }}>
{WATCHED_TOKENS.map((symbol) => {
const data = prices[symbol];
if (!data) return <div key={symbol}>Loading {symbol}...</div>;

return (
<div key={symbol} style={{ padding: 16, border: '1px solid #ddd', borderRadius: 8 }}>
<strong>{data.symbol}</strong>
<p>${data.priceFormatted}</p>
<small style={{ color: data.change24h >= 0 ? 'green' : 'red' }}>
{data.change24h >= 0 ? '+' : ''}{data.change24h.toFixed(2)}%
</small>
</div>
);
})}
</div>
</div>
);
}

Caching Behavior

Both hooks leverage PriceService internally, which applies a short-lived client-side cache (default: 10 seconds). This means:

  • Calling useTokenPrice('ETH') from two different components within 10 seconds results in only one network request.
  • Calling refetch() bypasses the cache and forces a fresh request.
  • The cache is scoped to the browser tab / React Native process.

No Provider Required

Like useWalletBalance, these hooks work without OneProvider:

import { useTokenPrice } from '@one_deploy/sdk';

// Renders anywhere -- no provider ancestor needed
function InlinePrice({ symbol }: { symbol: string }) {
const { priceFormatted } = useTokenPrice(symbol);
return <span>${priceFormatted ?? '...'}</span>;
}

See Also