Watch Token Balance
Watches for real-time changes to token balances using WebSocket subscriptions. The function fetches the current token balance immediately and then subscribes to ongoing updates, calling the provided callback whenever the balance changes. Supports both Token Extensions (Token-2022) and Classic Tokens.
Returns: () => void - A cleanup function to stop watching
const stopWatching = connection.watchTokenBalance(
ownerAddress,
mintAddress,
(error, balance) => {
if (error) {
console.error("Error:", error);
return;
}
console.log("Balance:", balance);
},
useTokenExtensions // Optional: default is true
);
// Later, to stop watching:
stopWatching();Parameters
ownerAddress:Address- The wallet address that owns the tokensmintAddress:Address- The token mint addresscallback:(error: any, balance: TokenBalance | null) => void- Called with (error, balance) on each balance changeerror:any- Any error that occurred (null if successful)balance:TokenBalance | null- The token balance object (null if error occurred)amount:bigint- Raw token amount as a BigInt (in base units)decimals:number- Number of decimal places for the tokenuiAmount:number | null- Formatted amount with decimalsuiAmountString:string- String representation of the UI amount
useTokenExtensions:boolean(optional) - Use Token-2022 program instead of classic Token program (default: true)
Returns
Returns a cleanup function that stops watching for balance changes. Call this function when you no longer need to watch the balance.
Examples
Watch a token balance and log changes:
const stopWatching = connection.watchTokenBalance(
"GkFTrgp8FcCgkCZeKreKKVHLyzGV6eqBpDHxRzg1brRn", // wallet address
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC mint
(error, balance) => {
if (error) {
console.error("Error watching balance:", error);
return;
}
console.log(`Balance: ${balance.uiAmountString} tokens`);
console.log(`Raw amount: ${balance.amount}`);
console.log(`Decimals: ${balance.decimals}`);
}
);
// Stop watching after 10 seconds
setTimeout(() => {
stopWatching();
console.log("Stopped watching balance");
}, 10000);Watch a classic token balance:
const stopWatching = connection.watchTokenBalance(
walletAddress,
mintAddress,
(error, balance) => {
if (error) {
console.error("Error:", error);
return;
}
console.log(`Balance: ${balance.uiAmountString}`);
},
false // Use classic Token program
);Watch a token balance and update UI state:
const [balance, setBalance] = useState<TokenBalance | null>(null);
useEffect(() => {
const stopWatching = connection.watchTokenBalance(
walletAddress,
tokenMintAddress,
(error, newBalance) => {
if (error) {
console.error("Error:", error);
return;
}
setBalance(newBalance);
}
);
// Cleanup on unmount
return stopWatching;
}, [walletAddress, tokenMintAddress]);Notes
- The callback is called immediately with the current balance, then again whenever the balance changes
- The function uses WebSocket subscriptions for real-time updates
- Always call the cleanup function when you’re done watching to prevent memory leaks
- If the token account doesn’t exist yet, the callback receives a zero balance
- By default, the function uses Token Extensions (Token-2022). Set
useTokenExtensionstofalsefor classic tokens
Error Handling
The callback receives an error as the first parameter if something goes wrong. Common errors include:
- Invalid address
- RPC connection failures
- Network issues
Always check for errors in your callback before using the balance value. If the token account doesn’t exist, the function will return a zero balance rather than an error.
See also: Get Token Account Balance, Transfer Tokens