Overview
This guide covers balance operations for both EVM and Solana chains, including balance retrieval, conversion utilities, and formatting.Prerequisites
- Dynamic SDK initialized (see Installation Guide)
- User authenticated (see Authentication Guide)
- Wallets available (see Wallet Creation)
Get Wallet Balance
The SDK provides a unified method to get balance for any wallet type:Copy
Ask AI
import DynamicSDKSwift
let sdk = DynamicSDK.instance()
func getBalance(wallet: BaseWallet) async {
do {
let balance = try await sdk.wallets.getBalance(wallet: wallet)
print("Balance: \(balance)")
} catch {
print("Failed to get balance: \(error)")
}
}
Display Balance with SwiftUI
Copy
Ask AI
import SwiftUI
import DynamicSDKSwift
@MainActor
class WalletBalanceViewModel: ObservableObject {
@Published var balance: String?
@Published var isLoading = false
@Published var errorMessage: String?
private let sdk = DynamicSDK.instance()
func fetchBalance(wallet: BaseWallet) {
isLoading = true
errorMessage = nil
Task {
do {
balance = try await sdk.wallets.getBalance(wallet: wallet)
} catch {
errorMessage = "Failed to get balance: \(error.localizedDescription)"
}
isLoading = false
}
}
}
struct WalletBalanceView: View {
let wallet: BaseWallet
@StateObject private var viewModel = WalletBalanceViewModel()
var body: some View {
VStack(alignment: .leading, spacing: 8) {
Text("Balance")
.font(.caption)
.foregroundColor(.secondary)
if viewModel.isLoading {
HStack {
ProgressView()
Text("Loading...")
.foregroundColor(.secondary)
}
} else if let balance = viewModel.balance {
Text(balance)
.font(.headline)
} else if let error = viewModel.errorMessage {
Text(error)
.foregroundColor(.red)
.font(.caption)
}
}
.onAppear {
viewModel.fetchBalance(wallet: wallet)
}
}
}
EVM Balance Conversions
Wei to ETH Conversion
Copy
Ask AI
import BigInt
/// Convert Wei to ETH
func weiToEth(_ wei: BigUInt, decimals: Int = 6) -> String {
let etherValue = Double(String(wei)) ?? 0.0
let ethValue = etherValue / pow(10.0, 18.0)
return String(format: "%.\(decimals)f", ethValue)
}
// Usage
let balanceWei: BigUInt = 1500000000000000000 // 1.5 ETH
let balanceEth = weiToEth(balanceWei)
print("Balance: \(balanceEth) ETH")
ETH to Wei Conversion
Copy
Ask AI
import BigInt
/// Convert ETH to Wei
func ethToWei(_ eth: Double) -> BigUInt {
let weiValue = eth * pow(10.0, 18.0)
return BigUInt(weiValue)
}
// Usage
let ethAmount = 1.5
let weiAmount = ethToWei(ethAmount)
print("\(ethAmount) ETH = \(weiAmount) Wei")
Gwei Conversions
Copy
Ask AI
import BigInt
/// Convert Wei to Gwei
func weiToGwei(_ wei: BigUInt) -> Double {
let gweiValue = Double(String(wei)) ?? 0.0
return gweiValue / pow(10.0, 9.0) // 1 Gwei = 10^9 Wei
}
/// Convert Gwei to Wei
func gweiToWei(_ gwei: Double) -> BigUInt {
let weiValue = gwei * pow(10.0, 9.0)
return BigUInt(weiValue)
}
// Usage for gas prices
let gasPriceGwei = 50.0
let gasPriceWei = gweiToWei(gasPriceGwei)
print("Gas Price: \(gasPriceGwei) Gwei = \(gasPriceWei) Wei")
Balance Formatting
Copy
Ask AI
import BigInt
/// Format EVM balance with appropriate units
func formatEvmBalance(_ wei: BigUInt) -> String {
let ethValue = Double(String(wei)) ?? 0.0
let eth = ethValue / pow(10.0, 18.0)
if eth >= 1.0 {
return String(format: "%.4f ETH", eth)
} else if eth >= 0.001 {
return String(format: "%.6f ETH", eth)
} else {
let gwei = ethValue / pow(10.0, 9.0)
return String(format: "%.2f Gwei", gwei)
}
}
Solana Balance Conversions
Solana uses lamports as its smallest unit, where 1 SOL = 10^9 lamports (9 decimal places).Lamports to SOL Conversion
Copy
Ask AI
/// Convert lamports to SOL
func lamportsToSol(_ lamports: UInt64, decimals: Int = 6) -> String {
let solValue = Double(lamports) / 1_000_000_000.0
return String(format: "%.\(decimals)f", solValue)
}
// Usage
let balanceLamports: UInt64 = 1_500_000_000 // 1.5 SOL
let balanceSol = lamportsToSol(balanceLamports)
print("Balance: \(balanceSol) SOL")
SOL to Lamports Conversion
Copy
Ask AI
/// Convert SOL to lamports
func solToLamports(_ sol: Double) -> UInt64 {
return UInt64(sol * 1_000_000_000)
}
// Usage
let solAmount = 1.5
let lamportsAmount = solToLamports(solAmount)
print("\(solAmount) SOL = \(lamportsAmount) lamports")
SOL Balance Formatting
Copy
Ask AI
/// Format SOL balance for display
func formatSolBalance(_ lamports: UInt64) -> String {
let sol = Double(lamports) / 1_000_000_000.0
if sol >= 1.0 {
return String(format: "%.4f SOL", sol)
} else if sol >= 0.001 {
return String(format: "%.6f SOL", sol)
} else {
return String(format: "%.9f SOL", sol)
}
}
Multi-Chain Balance Display
Handle balances for both EVM and Solana wallets:Copy
Ask AI
import DynamicSDKSwift
let sdk = DynamicSDK.instance()
func displayBalance(wallet: BaseWallet) async {
do {
let balance = try await sdk.wallets.getBalance(wallet: wallet)
let chain = wallet.chain.uppercased()
switch chain {
case "EVM":
print("Balance: \(balance) (in Wei)")
case "SOL":
print("Balance: \(balance) (in lamports)")
default:
print("Balance: \(balance)")
}
} catch {
print("Failed to get balance: \(error)")
}
}
// Display all wallet balances
func displayAllBalances() async {
for wallet in sdk.wallets.userWallets {
print("\(wallet.chain) wallet: \(wallet.address)")
await displayBalance(wallet: wallet)
}
}
Conversion Helper Class
Copy
Ask AI
import BigInt
/// Helper class for balance conversions
struct BalanceConverter {
/// EVM conversions
static func weiToEth(_ wei: BigUInt) -> Double {
let ethValue = Double(String(wei)) ?? 0.0
return ethValue / pow(10.0, 18.0)
}
static func ethToWei(_ eth: Double) -> BigUInt {
return BigUInt(eth * pow(10.0, 18.0))
}
static func weiToGwei(_ wei: BigUInt) -> Double {
let gweiValue = Double(String(wei)) ?? 0.0
return gweiValue / pow(10.0, 9.0)
}
/// Solana conversions
static func lamportsToSol(_ lamports: UInt64) -> Double {
return Double(lamports) / 1_000_000_000.0
}
static func solToLamports(_ sol: Double) -> UInt64 {
return UInt64(sol * 1_000_000_000)
}
/// Format for display
static func formatBalance(
value: String,
chain: String,
decimals: Int = 4
) -> String {
switch chain.uppercased() {
case "EVM":
if let wei = BigUInt(value) {
let eth = weiToEth(wei)
return String(format: "%.\(decimals)f ETH", eth)
}
case "SOL":
if let lamports = UInt64(value) {
let sol = lamportsToSol(lamports)
return String(format: "%.\(decimals)f SOL", sol)
}
default:
break
}
return value
}
}
// Usage
let formatted = BalanceConverter.formatBalance(
value: "1500000000000000000",
chain: "EVM",
decimals: 4
)
print(formatted) // "1.5000 ETH"
Common Token Decimals
| Chain | Token | Decimals | Unit |
|---|---|---|---|
| EVM | ETH | 18 | Wei |
| EVM | USDC | 6 | Smallest unit |
| EVM | USDT | 6 | Smallest unit |
| EVM | WBTC | 8 | Smallest unit |
| Solana | SOL | 9 | Lamports |
Best Practices
1. Cache Balances
Copy
Ask AI
@MainActor
class BalanceCache: ObservableObject {
@Published var balances: [String: String] = [:]
private let sdk = DynamicSDK.instance()
func refreshBalance(for wallet: BaseWallet) async {
do {
let balance = try await sdk.wallets.getBalance(wallet: wallet)
balances[wallet.address] = balance
} catch {
print("Failed to refresh balance: \(error)")
}
}
func refreshAllBalances() async {
for wallet in sdk.wallets.userWallets {
await refreshBalance(for: wallet)
}
}
}
2. Handle Precision
Copy
Ask AI
// Use BigUInt for EVM to avoid precision loss
import BigInt
let wei = BigUInt("1500000000000000000")! // 1.5 ETH
let eth = BalanceConverter.weiToEth(wei)
// Use UInt64 for Solana
let lamports: UInt64 = 1_500_000_000 // 1.5 SOL
let sol = BalanceConverter.lamportsToSol(lamports)
3. Refresh After Transactions
Copy
Ask AI
func sendTransactionAndRefresh(wallet: BaseWallet) async {
do {
// Send transaction
let txHash = try await sendTransaction(wallet: wallet)
// Wait a moment for blockchain confirmation
try await Task.sleep(nanoseconds: 2_000_000_000) // 2 seconds
// Refresh balance
let newBalance = try await sdk.wallets.getBalance(wallet: wallet)
print("New balance: \(newBalance)")
} catch {
print("Error: \(error)")
}
}
Next Steps
- Send ETH Transactions - Transfer ETH
- Send Solana Transactions - Transfer SOL
- Network Management - Switch networks
- ERC-20 Token Transfers - Send ERC-20 tokens