Token balance are currently supported on: Ethereum, Worldchain, Shape, Zksync, Optimism, Polygon, Geist, Arbitrum, Blast, Linea, Base, Scroll, Gnosis, BNB, Avalanche, Apechain, Lens, Soneium, Rootstock, Abstract, Settlus, Ink, Solana, Bitcoin runes.Dynamic supports fetching the top 3000 tokens by market cap.
React
React Native
JavaScript SDK
Swift
Flutter
The Dynamic UI components (DynamicWidget and UserProfile) have a built in UI for displaying multi asset balances, we strongly recommend using those components if you can! Learn more in
the Multi-Asset UI section.
Hook
You can fetch token balances for a user’s wallet using the useTokenBalances hook:import { useTokenBalances } from "@dynamic-labs/sdk-react-core";
const { tokenBalances, isLoading, isError, error } = useTokenBalances();
Return Value
This hook returns an object for tokenBalances with the following properties:| Property | Type | Description |
|---|
| networkId | integer | The network ID of the token i.e. 1 for Ethereum, 137 for Polygon, etc. |
| address | string | The address of the token. |
| name | string | The name of the token. |
| symbol | string | The symbol of the token. |
| decimals | integer | The number of decimals the token has. |
| logoURI | string | The URI of the token’s logo image. |
| balance | float | The balance of the token in the user’s wallet. |
| rawBalance | integer | The raw balance of the token in the user’s wallet. |
Reference
You can find the full reference for the useTokenBalances hook here.Full Example
import { useDynamicContext, useTokenBalances } from "@dynamic-labs/sdk-react-core";
const Balances = () => {
const { primaryWallet } = useDynamicContext();
const { tokenBalances, isLoading, isError, error } = useTokenBalances();
if(!primaryWallet) return <div>No wallet connected</div>;
if (isLoading) return <div>Loading...</div>;
if (isError) return <div>Error: {error.message}</div>;
return (
<div>
{tokenBalances.map((token) => (
<div key={token.address}>
<img src={token.logoURI} alt={token.symbol} />
<div>{token.name}</div>
<div>{token.symbol}</div>
<div>{token.balance}</div>
</div>
))}
</div>
);
};
// React Native does not have a built-in token balances hook.
// Options:
// - Use Dynamic UI (User Profile) which shows multi-asset balances
// - Or build your own by combining:
// a) dynamicClient.wallets.getBalance for native balance
// b) A third-party indexer for ERC-20/solana/sui tokens
import { dynamicClient } from '<path to client file>'
export async function getNativeBalanceRN() {
const wallet = dynamicClient.wallets.primary
if (!wallet) return null
const { balance } = await dynamicClient.wallets.getBalance({ wallet })
return balance
}
Use getMultichainBalances when you need token balances across chains (EVM, Solana, etc.).import { getMultichainBalances } from '@dynamic-labs-sdk/client';
export async function fetchBalances(address) {
const { chainBalances } = await getMultichainBalances({
balanceRequest: {
filterSpamTokens: true,
balanceRequests: [
{ address, chain: 'EVM', networkIds: [1, 137] },
{ address, chain: 'SOL', networkIds: [101] },
],
},
});
return chainBalances;
}
Pass whitelistedContracts inside each balance request to keep specific tokens when spam filtering is enabled. Native Balance Retrieval
Swift doesn’t have a built-in hook for token balances like React. Instead, you can fetch native balances using the SDK and integrate with third-party indexers for ERC-20 token lists if needed.import DynamicSwiftSDK
// Get native balance from an EthereumWallet
do {
let balance = try await ethereumWallet.getBalance(.Latest)
print("Balance: \(balance)")
} catch {
print("Failed fetching balance: \(error)")
}
For Token Balances
To get comprehensive token balances on Swift, you’ll need to:
- Fetch native balances using the SDK (as shown above)
- Integrate with third-party services like:
- Covalent API for multi-chain token data
- Moralis API for token balances
- Etherscan API for Ethereum tokens
- Chain-specific RPC calls for token contract data
Example Implementation
import DynamicSwiftSDK
import Foundation
class TokenBalancesManager {
private var balances: [TokenBalance] = []
func fetchBalances() async {
do {
// Get native balance
let balance = try await ethereumWallet.getBalance(.Latest)
// You would then call your chosen third-party API here
// let tokenBalances = try await fetchTokenBalancesFromAPI(walletAddress: wallet.address)
balances = [TokenBalance(type: "native", balance: balance)]
} catch {
print("Failed to fetch balances: \(error)")
}
}
}
struct TokenBalance {
let type: String
let balance: String
}
Native Balance Retrieval
Flutter doesn’t have a built-in hook for token balances like React. Instead, you can fetch native balances using the SDK and integrate with third-party indexers for ERC-20 token lists if needed.import 'package:dynamic_sdk/dynamic_sdk.dart';
// Get native balance for primary wallet
Future<String?> getNativeBalance() async {
final wallet = DynamicSDK.instance.wallets.primary;
if (wallet == null) return null;
final result = await DynamicSDK.instance.wallets.getBalance(wallet: wallet);
return result.balance;
}
For Token Balances
To get comprehensive token balances on Flutter, you’ll need to:
- Fetch native balances using the SDK (as shown above)
- Integrate with third-party services like:
- Covalent API for multi-chain token data
- Moralis API for token balances
- Etherscan API for Ethereum tokens
- Chain-specific RPC calls for token contract data
Example Implementation
import 'package:dynamic_sdk/dynamic_sdk.dart';
import 'package:flutter/material.dart';
class TokenBalances extends StatefulWidget {
@override
_TokenBalancesState createState() => _TokenBalancesState();
}
class _TokenBalancesState extends State<TokenBalances> {
List<TokenBalance> balances = [];
bool loading = false;
Future<void> fetchBalances() async {
setState(() {
loading = true;
});
try {
final wallet = DynamicSDK.instance.wallets.primary;
if (wallet == null) return;
// Get native balance
final result = await DynamicSDK.instance.wallets.getBalance(wallet: wallet);
// You would then call your chosen third-party API here
// final tokenBalances = await fetchTokenBalancesFromAPI(wallet.address);
setState(() {
balances = [TokenBalance(type: 'native', balance: result.balance)];
});
} catch (e) {
print('Failed to fetch balances: $e');
} finally {
setState(() {
loading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Token Balances'),
if (loading) Text('Loading...'),
...balances.map((item) => Text('${item.type}: ${item.balance}')),
],
);
}
}
class TokenBalance {
final String type;
final String balance;
TokenBalance({required this.type, required this.balance});
}