> ## 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.

# Balances

# 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

```typescript theme={null}
const tokenAddress = '0x...';
const balance = await sdk.vault.getBalance(tokenAddress);

console.log('Shielded:', balance.shieldedBalance);
console.log('Wallet:', balance.walletBalance);
// Returns: TokenBalance { tokenAddress, shieldedBalance, walletBalance, symbol?, decimals?, noteCount? }
```

## Get All Balances

```typescript theme={null}
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.shieldedBalance}`);
  console.log(`  Wallet: ${balance.walletBalance}`);
  console.log(`  Decimals: ${balance.decimals}`);
}
```

### Balance Type

```typescript theme={null}
interface TokenBalance {
  tokenAddress: Hex;        // Token contract address
  shieldedBalance: bigint;  // Private (shielded) balance
  walletBalance: bigint;    // Public wallet balance
  symbol?: string;          // Token symbol (e.g., "USDC")
  decimals?: number;        // Token decimals (e.g., 18)
  noteCount?: number;       // Number of shielded notes backing the balance
}
```

## Refreshing Balances

Balances are cached locally. Refresh to get the latest:

```typescript theme={null}
// Refresh a specific token
await sdk.vault.refreshBalance('0x...token-address');

// Refresh all tracked balances
await sdk.vault.refreshBalances();
```

## Token Metadata

Get information about a token:

```typescript theme={null}
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
```

### Token Metadata Type

```typescript theme={null}
interface TokenMetadata {
  address: Hex;
  symbol: string;
  decimals: number;
  name: string;
}
```

## Supported Tokens

Get list of all supported tokens:

```typescript theme={null}
const tokens = await sdk.vault.getSupportedTokens();

for (const token of tokens) {
  console.log(`${token.symbol} (${token.address})`);
}
```

## Formatting Amounts

`parseAmount` and `formatAmount` are standalone utilities exported from the SDK package.

### Parse Human-Readable to BigInt

```typescript theme={null}
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
```

### Format BigInt to Human-Readable

```typescript theme={null}
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:

```typescript theme={null}
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

```typescript theme={null}
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.shieldedBalance, balance.decimals || 18)}</td>
            <td>{formatBalance(balance.walletBalance, balance.decimals || 18)}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}
```

## Balance Polling

Keep balances updated with polling:

```typescript theme={null}
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

```typescript theme={null}
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.shieldedBalance) / 10 ** (balance.decimals || 18);
    total += amount * price;
  }

  return total;
}
```

### Check Sufficient Balance

```typescript theme={null}
async function hasSufficientBalance(
  tokenAddress: Hex,
  requiredAmount: bigint
): Promise<boolean> {
  const balance = await sdk.vault.getBalance(tokenAddress);
  return balance.shieldedBalance >= requiredAmount;
}
```

## Error Handling

```typescript theme={null}
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

### 1. Cache Token Metadata

```typescript theme={null}
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

```typescript theme={null}
function formatBalance(balance: TokenBalance): string {
  if (balance.shieldedBalance === 0n && balance.walletBalance === 0n) {
    return '0';
  }
  return formatAmount(balance.shieldedBalance, balance.decimals || 18);
}
```

### 3. Refresh After Operations

```typescript theme={null}
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

* [Deposits Guide](./deposits)
* [Withdrawals Guide](./withdrawals)
* [Transactions Guide](./transactions)
* [Error Handling](./error-handling)
