Balances and transfers
Token Components
These primitives are designed to work together in real token workflows: picking an asset, showing balances, entering a transfer amount, and composing the full send or swap form.
Core building blocks
Use the pieces independently or compose them into a full token form.
Best for
The docs examples are optimized around common token movement workflows.
Data access
Drop down to useTokenBalances when you need full custom rendering.
TokenIcon
Render a logo, identicon fallback, or symbol surface for a token.
TokenSelector
Search and choose an asset with optional balance visibility.
TokenAmountInput
Capture amounts with balance-aware and USD-aware affordances.
Prerequisites
These components require the AvaCloudKitProvider context. The TokenSelector auto-fetch mode and useTokenBalances hook call the ListTokenBalances API endpoint. See the Getting Started guide for setup.
TokenIcon
Displays a token's logo with automatic fallback to an address-based identicon or a generic icon.
import { TokenIcon } from '@avalabs/avacloud-kit-ui-preview';
// With logo URL
<TokenIcon logoUri="https://..." symbol="AVAX" size={40} />
// Falls back to identicon when no logo (or logo fails to load)
<TokenIcon address="0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E" symbol="USDC" size={40} />
// Generic fallback when neither logo nor address provided
<TokenIcon symbol="???" size={40} />Sizes
<TokenIcon logoUri="https://..." symbol="AVAX" size={20} />
<TokenIcon logoUri="https://..." symbol="AVAX" size={32} />
<TokenIcon logoUri="https://..." symbol="AVAX" size={48} />TokenIcon Props
Prop
Type
TokenSelector
A dropdown selector for tokens with search, balance display, and automatic data fetching. Follows the same Popover pattern as ChainSelect.
Auto-fetch Mode
Provide chainId and walletAddress to automatically fetch token balances:
import { useState } from 'react';
import { TokenSelector } from '@avalabs/avacloud-kit-ui-preview';
import type { TokenBalance } from '@avalabs/avacloud-kit-ui-preview/client';
function Example() {
const [token, setToken] = useState<TokenBalance | null>(null);
return (
<TokenSelector
chainId="43114"
walletAddress="0x71C7656EC7ab88b098defB751B7401B5f6d8976F"
selectedTokenAddress={token?.address}
onSelect={setToken}
showBalances
/>
);
}Manual Mode
Provide your own token list via the tokens prop:
<TokenSelector
tokens={myTokenList}
isLoading={false}
selectedTokenAddress={selected?.address}
onSelect={setSelected}
/>Disabled State
<TokenSelector onSelect={() => {}} placeholder="Wallet not connected" disabled />TokenSelector Props
Prop
Type
TokenBalance
Display a single token balance for a wallet. Auto-fetches when chainId and walletAddress are provided. When tokenAddress is omitted or set to the zero address, the native token is used.
import { TokenBalance } from '@avalabs/avacloud-kit-ui-preview';
<TokenBalance
chainId="43114"
walletAddress="0x71C7656EC7ab88b098defB751B7401B5f6d8976F"
/>;Manual Mode
<TokenBalance token={token} />TokenBalance Props
Prop
Type
TokenAmountInput
A card-based input for entering token amounts with Max button, balance display, USD conversion, and error handling.
Basic Usage
import { useState } from 'react';
import { TokenAmountInput } from '@avalabs/avacloud-kit-ui-preview';
const avaxPrice = {
currencyCode: 'USD',
value: 38.5,
};
function Example() {
const [amount, setAmount] = useState('');
return (
<TokenAmountInput
value={amount}
onChange={setAmount}
symbol="AVAX"
decimals={18}
balance="1500000000000000000" // 1.5 AVAX in wei
price={avaxPrice}
logoUri="https://..."
tokenAddress="native"
/>
);
}With Error
Consumer business logic provides the error message via the error prop:
const usdcPrice = {
currencyCode: 'USD',
value: 1,
};
<TokenAmountInput
value={amount}
onChange={setAmount}
symbol="USDC"
decimals={6}
balance="50000000" // 50 USDC
price={usdcPrice}
error="Insufficient balance"
/>Minimal (No Token Selected)
<TokenAmountInput
value={amount}
onChange={setAmount}
decimals={18}
showMaxButton={false}
showBalance={false}
showUsdValue={false}
label="Transfer amount"
placeholder="Enter amount"
/>TokenAmountInput Props
Prop
Type
Full Composition Example
All three components work together. TokenBalance data flows from TokenSelector.onSelect directly into TokenAmountInput's props:
import { useState } from 'react';
import {
ChainSelect,
TokenSelector,
TokenAmountInput,
formatTokenAmount,
} from '@avalabs/avacloud-kit-ui-preview';
import type { TokenBalance } from '@avalabs/avacloud-kit-ui-preview/client';
function SendForm({ walletAddress }: { walletAddress: string }) {
const [chainId, setChainId] = useState('43114');
const [token, setToken] = useState<TokenBalance | null>(null);
const [amount, setAmount] = useState('');
// Consumer-side balance validation
const insufficientBalance = (() => {
if (!token || !amount) return undefined;
const humanBalance = formatTokenAmount(token.balance, token.decimals);
if (parseFloat(amount) > parseFloat(humanBalance)) {
return 'Insufficient balance';
}
return undefined;
})();
return (
<div className="space-y-3">
<ChainSelect
selectedChainId={chainId}
onSelect={(id) => {
setChainId(id);
setToken(null);
setAmount('');
}}
/>
<TokenSelector
chainId={chainId}
walletAddress={walletAddress}
selectedTokenAddress={token?.address}
onSelect={(t) => { setToken(t); setAmount(''); }}
showBalances
/>
<TokenAmountInput
value={amount}
onChange={setAmount}
symbol={token?.symbol}
decimals={token?.decimals}
balance={token?.balance}
price={token?.price}
logoUri={token?.logoUri}
tokenAddress={token?.address}
error={insufficientBalance}
disabled={!token}
/>
</div>
);
}useTokenBalances Hook
For custom UIs, use the hook directly:
import { useTokenBalances } from '@avalabs/avacloud-kit-ui-preview';
function MyTokenList() {
const { data, isLoading, isError } = useTokenBalances({
chainId: '43114',
address: '0x71C7656EC7ab88b098defB751B7401B5f6d8976F',
pageSize: 25,
});
if (isLoading) return <div>Loading...</div>;
if (isError) return <div>Error loading balances</div>;
return (
<ul>
{data?.tokens.map((token) => (
<li key={token.address}>
{token.symbol}: {formatTokenAmount(token.balance, token.decimals)}
</li>
))}
</ul>
);
}useTokenBalances Options
| Option | Type | Default | Description |
|---|---|---|---|
chainId | string | Required | EVM chain ID |
address | string | Required | Wallet address |
pageToken | string | "" | Pagination token |
pageSize | number | 25 | Results per page |
enabled | boolean | true | Whether the query is enabled |
Utility Functions
Token formatting utilities are also exported for use in custom components:
import {
formatTokenAmount,
formatUsdValue,
isValidTokenInput,
} from '@avalabs/avacloud-kit-ui-preview';
// Convert raw balance to human-readable
formatTokenAmount('1500000000000000000', 18); // "1.5"
formatTokenAmount('1000000', 6); // "1"
formatTokenAmount('100', 18); // "<0.000001"
formatTokenAmount('0', 18); // "0"
// Format USD values
formatUsdValue(1234.56); // "$1,234.56"
formatUsdValue(0.005); // "<$0.01"
formatUsdValue(undefined); // undefined
// Validate user input (for custom amount inputs)
isValidTokenInput('1.5', 18); // true
isValidTokenInput('1.1234567', 6); // false (too many decimals)
isValidTokenInput('abc', 18); // false
isValidTokenInput('', 18); // true (empty is valid)Common Chain IDs
| Chain | Chain ID |
|---|---|
| Avalanche C-Chain Mainnet | 43114 |
| Avalanche C-Chain Testnet (Fuji) | 43113 |