跳至主要内容

useTokenPrice & useTokenPrices

两个用于获取实时加密货币价格的 独立 hooks。两者都不需要 OneProvider——可以在 React 树中的任意位置使用。

两个 hooks 内部都使用 PriceService,该服务提供:

  • 多源价格聚合,在 provider 之间自动回退。
  • 客户端缓存,避免短时间内的重复网络请求。
  • 自动重试,应对临时性故障。

导入

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

useTokenPrice

获取单个代币符号的实时 USD 价格。

签名

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

参数

参数类型必需描述
symbolstring代币符号(例如 'ETH''BTC''USDC')。不区分大小写。
optionsUseTokenPriceOptions轮询、货币和 API 连接的配置。

选项

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;
}

返回类型

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;
}

基本用法

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>
);
}

自动刷新的实时价格

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>
);
}

不同货币的价格

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

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

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

useTokenPrices

在单次批量请求中获取 多个代币 的价格。比多次调用 useTokenPrice 更高效。

签名

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

参数

参数类型必需描述
symbolsstring[]代币符号数组(例如 ['ETH', 'BTC', 'USDC'])。
optionsUseTokenPricesOptionsUseTokenPriceOptions 相同的选项。

选项

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;
}

返回类型

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;
}

基本批量用法

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>
);
}

带自动刷新的实时仪表板

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>
);
}

缓存行为

两个 hooks 内部都使用 PriceService,该服务应用了 短时客户端缓存(默认:10 秒)。这意味着:

  • 在 10 秒内从两个不同组件调用 useTokenPrice('ETH') 只会发起一次网络请求。
  • 调用 refetch() 会绕过缓存并强制发起新请求。
  • 缓存的作用域为浏览器标签页 / React Native 进程。

无需 Provider

useWalletBalance 一样,这些 hooks 无需 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>;
}

另请参阅