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 iOS SDK.
Understanding Balances
Privacy Boost tracks two types of balances:
| Balance Type | Description |
|---|
| Shielded | Private balance in the privacy pool — only you can see it |
| Wallet | Public balance in your connected wallet on-chain |
Get Single Token Balance
do {
let balance = try await sdk.getBalance(tokenAddress: "0x...")
print("Token: \(balance.tokenAddress)")
print("Shielded: \(balance.shieldedBalance)")
print("Wallet: \(balance.walletBalance)")
print("Symbol: \(balance.symbol ?? "Unknown")")
print("Decimals: \(balance.decimals)")
} catch {
print("Failed to get balance: \(error)")
}
Get All Balances
do {
let balances = try await sdk.getAllBalances()
for balance in balances {
print("\(balance.symbol ?? balance.tokenAddress):")
print(" Shielded: \(balance.shieldedBalance)")
print(" Wallet: \(balance.walletBalance)")
}
} catch {
print("Failed to get balances: \(error)")
}
Balance Type
struct TokenBalance {
let tokenAddress: String // Token contract address
let shieldedBalance: String // Private balance in wei
let walletBalance: String // Public balance in wei
let symbol: String? // Token symbol (e.g., "USDC")
let decimals: UInt8 // Token decimals (e.g., 18)
}
Convert between wei strings and human-readable format:
// Parse human-readable to wei
let weiAmount = try sdk.parseAmount("1.5", decimals: 18)
// Returns: "1500000000000000000"
// Format wei to human-readable
let humanAmount = try sdk.formatAmount("1500000000000000000", decimals: 18)
// Returns: "1.5"
// Format a balance for display
let balance = try await sdk.getBalance(tokenAddress: tokenAddress)
let formatted = try sdk.formatAmount(balance.shieldedBalance, decimals: balance.decimals)
print("Shielded: \(formatted) \(balance.symbol ?? "")")
Checking Sufficient Balance
Before performing operations, verify the user has enough balance:
func hasSufficientBalance(
tokenAddress: String,
requiredAmount: String
) async throws -> Bool {
let balance = try await sdk.getBalance(tokenAddress: tokenAddress)
guard let shielded = UInt64(balance.shieldedBalance),
let required = UInt64(requiredAmount) else {
return false
}
return shielded >= required
}
// Usage
if try await hasSufficientBalance(tokenAddress: token, requiredAmount: amount) {
let result = try await sdk.unshield(
tokenAddress: token,
amount: amount,
recipient: recipient
)
}
Displaying Balances in SwiftUI
struct BalanceListView: View {
@State private var balances: [TokenBalance] = []
@State private var isLoading = true
var body: some View {
List {
if isLoading {
ProgressView("Loading balances...")
} else if balances.isEmpty {
Text("No balances found")
.foregroundColor(.secondary)
} else {
ForEach(balances, id: \.tokenAddress) { balance in
BalanceRow(balance: balance)
}
}
}
.task {
await loadBalances()
}
.refreshable {
await loadBalances()
}
}
private func loadBalances() async {
isLoading = true
do {
balances = try await sdk.getAllBalances()
} catch {
print("Failed to load balances: \(error)")
}
isLoading = false
}
}
struct BalanceRow: View {
let balance: TokenBalance
var formattedShielded: String {
(try? sdk.formatAmount(balance.shieldedBalance, decimals: balance.decimals)) ?? "0"
}
var formattedWallet: String {
(try? sdk.formatAmount(balance.walletBalance, decimals: balance.decimals)) ?? "0"
}
var body: some View {
VStack(alignment: .leading, spacing: 4) {
Text(balance.symbol ?? balance.tokenAddress)
.font(.headline)
HStack {
Label("Shielded: \(formattedShielded)", systemImage: "lock.shield")
Spacer()
Label("Wallet: \(formattedWallet)", systemImage: "wallet.pass")
}
.font(.subheadline)
.foregroundColor(.secondary)
}
.padding(.vertical, 4)
}
}
Error Handling
do {
let balance = try await sdk.getBalance(tokenAddress: tokenAddress)
} catch SDKError.notAuthenticated {
print("Please log in first")
} catch SDKError.networkError(let message) {
print("Network error: \(message)")
} catch {
print("Balance error: \(error)")
}
Best Practices
1. Refresh After Operations
// Refresh balance after a deposit
let shieldResult = try await sdk.shield(
tokenAddress: tokenAddress,
amount: amount
)
let updatedBalance = try await sdk.getBalance(tokenAddress: tokenAddress)
2. Handle Zero Balances
func displayBalance(_ balance: TokenBalance) -> String {
if balance.shieldedBalance == "0" && balance.walletBalance == "0" {
return "0"
}
return (try? sdk.formatAmount(
balance.shieldedBalance,
decimals: balance.decimals
)) ?? "0"
}
3. Filter Non-Zero Balances
let allBalances = try await sdk.getAllBalances()
let nonZero = allBalances.filter { balance in
balance.shieldedBalance != "0" || balance.walletBalance != "0"
}
Next Steps