Documentation Index
Fetch the complete documentation index at: https://docs.privacyboost.io/llms.txt
Use this file to discover all available pages before exploring further.
Balance Management
This guide covers querying and managing token balances in the Privacy Boost SDK.
Understanding Balances
Privacy Boost tracks two types of balances:
| Balance Type | Description |
|---|
| Shielded | Private balance in the privacy pool |
| Wallet | Public balance in your connected wallet |
Get Single Token Balance
const tokenAddress = '0x...';
const balance = await sdk.vault.getBalance(tokenAddress);
console.log('Shielded:', balance.shielded);
console.log('Wallet:', balance.wallet);
// Returns: TokenBalance { tokenAddress, shielded, wallet, symbol?, decimals? }
Get All Balances
const balances = await sdk.vault.getAllBalances();
for (const balance of balances) {
console.log(`Token: ${balance.tokenAddress}`);
console.log(` Symbol: ${balance.symbol}`);
console.log(` Shielded: ${balance.shielded}`);
console.log(` Wallet: ${balance.wallet}`);
console.log(` Decimals: ${balance.decimals}`);
}
Balance Type
interface TokenBalance {
tokenAddress: Hex; // Token contract address
shielded: bigint; // Private balance
wallet: bigint; // Wallet balance
symbol?: string; // Token symbol (e.g., "USDC")
decimals?: number; // Token decimals (e.g., 18)
}
Refreshing Balances
Balances are cached locally. Refresh to get the latest:
// Refresh a specific token
await sdk.vault.refreshBalance('0x...token-address');
// Refresh all tracked balances
await sdk.vault.refreshBalances();
Get information about a token:
const token = await sdk.vault.getToken('0x...token-address');
console.log('Name:', token.name); // "USD Coin"
console.log('Symbol:', token.symbol); // "USDC"
console.log('Decimals:', token.decimals); // 6
interface TokenMetadata {
address: Hex;
symbol: string;
decimals: number;
name: string;
}
Supported Tokens
Get list of all supported tokens:
const tokens = await sdk.vault.getSupportedTokens();
for (const token of tokens) {
console.log(`${token.symbol} (${token.address})`);
}
parseAmount and formatAmount are standalone utilities exported from the SDK package.
Parse Human-Readable to BigInt
import { parseAmount } from '@sunnyside-io/privacy-boost';
// Parse "1.5" using a token's decimals
const usdc = parseAmount('1.5', 6);
// Returns: 1500000n
const weth = parseAmount('1.5', 18);
// Returns: 1500000000000000000n
import { formatAmount } from '@sunnyside-io/privacy-boost';
const formatted = formatAmount(1500000n, 6);
// Returns: "1.5"
const ethFormatted = formatAmount(1500000000000000000n, 18);
// Returns: "1.5"
Native ETH
Native ETH is represented by the zero address:
const ETH_ADDRESS = '0x0000000000000000000000000000000000000000';
// Check if token is native ETH
import { isNativeEth } from '@sunnyside-io/privacy-boost';
if (isNativeEth(tokenAddress)) {
console.log('This is native ETH');
}
UI Example
import { useState, useEffect } from 'react';
function BalanceList() {
const [balances, setBalances] = useState<TokenBalance[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function loadBalances() {
setLoading(true);
await sdk.vault.refreshBalances();
const allBalances = await sdk.vault.getAllBalances();
setBalances(allBalances);
setLoading(false);
}
loadBalances();
}, []);
const formatBalance = (amount: bigint, decimals: number) => {
return formatAmount(amount, decimals);
};
if (loading) return <div>Loading balances...</div>;
return (
<table>
<thead>
<tr>
<th>Token</th>
<th>Shielded</th>
<th>Wallet</th>
</tr>
</thead>
<tbody>
{balances.map((balance) => (
<tr key={balance.tokenAddress}>
<td>{balance.symbol}</td>
<td>{formatBalance(balance.shielded, balance.decimals || 18)}</td>
<td>{formatBalance(balance.wallet, balance.decimals || 18)}</td>
</tr>
))}
</tbody>
</table>
);
}
Balance Polling
Keep balances updated with polling:
function useBalancePolling(intervalMs = 30000) {
const [balances, setBalances] = useState<TokenBalance[]>([]);
useEffect(() => {
async function sync() {
await sdk.vault.refreshBalances();
setBalances(await sdk.vault.getAllBalances());
}
sync(); // Initial sync
const interval = setInterval(sync, intervalMs);
return () => clearInterval(interval);
}, [intervalMs]);
return balances;
}
Balance Calculations
Total Portfolio Value
async function getTotalValue(prices: Record<string, number>) {
const balances = await sdk.vault.getAllBalances();
let total = 0;
for (const balance of balances) {
const price = prices[balance.tokenAddress.toLowerCase()] || 0;
const amount = Number(balance.shielded) / 10 ** (balance.decimals || 18);
total += amount * price;
}
return total;
}
Check Sufficient Balance
async function hasSufficientBalance(
tokenAddress: Hex,
requiredAmount: bigint
): Promise<boolean> {
const balance = await sdk.vault.getBalance(tokenAddress);
return balance.shielded >= requiredAmount;
}
Error Handling
try {
const balance = await sdk.vault.getBalance(tokenAddress);
} catch (error) {
switch (error.code) {
case 'TOKEN_NOT_FOUND':
console.log('Token not supported');
break;
case 'SYNC_FAILED':
console.log('Failed to sync balance');
break;
default:
console.log('Balance error:', error.message);
}
}
Best Practices
const tokenCache = new Map<string, TokenMetadata>();
async function getTokenCached(address: string) {
const key = address.toLowerCase();
if (!tokenCache.has(key)) {
const metadata = await sdk.vault.getToken(address);
tokenCache.set(key, metadata);
}
return tokenCache.get(key)!;
}
2. Handle Zero Balances
function formatBalance(balance: TokenBalance): string {
if (balance.shielded === 0n && balance.wallet === 0n) {
return '0';
}
return formatAmount(balance.shielded, balance.decimals || 18);
}
3. Refresh After Operations
async function depositWithRefresh(params: DepositParams) {
const result = await sdk.vault.shield(params);
// Refresh balance after deposit
await sdk.vault.refreshBalance(params.tokenAddress);
return result;
}
Next Steps