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 'package:dynamic_sdk/dynamic_sdk.dart';
final sdk = DynamicSDK.instance;
Future<String> getBalance(BaseWallet wallet) async {
try {
final balance = await sdk.wallets.getBalance(wallet: wallet);
print('Balance: $balance');
return balance;
} catch (e) {
print('Failed to get balance: $e');
rethrow;
}
}
Display Balance with Flutter
Copy
Ask AI
import 'package:flutter/material.dart';
import 'package:dynamic_sdk/dynamic_sdk.dart';
class WalletBalanceWidget extends StatefulWidget {
final BaseWallet wallet;
const WalletBalanceWidget({Key? key, required this.wallet}) : super(key: key);
@override
State<WalletBalanceWidget> createState() => _WalletBalanceWidgetState();
}
class _WalletBalanceWidgetState extends State<WalletBalanceWidget> {
final sdk = DynamicSDK.instance;
String? balance;
bool isLoading = false;
String? errorMessage;
@override
void initState() {
super.initState();
_fetchBalance();
}
Future<void> _fetchBalance() async {
setState(() {
isLoading = true;
errorMessage = null;
});
try {
final balanceValue = await sdk.wallets.getBalance(wallet: widget.wallet);
setState(() => balance = balanceValue);
} catch (e) {
setState(() => errorMessage = 'Failed to get balance: $e');
} finally {
setState(() => isLoading = false);
}
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Balance',
style: TextStyle(fontSize: 12, color: Colors.grey),
),
const SizedBox(height: 8),
if (isLoading)
const Row(
children: [
SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(strokeWidth: 2),
),
SizedBox(width: 8),
Text('Loading...', style: TextStyle(color: Colors.grey)),
],
)
else if (balance != null)
Text(
balance!,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
)
else if (errorMessage != null)
Text(
errorMessage!,
style: const TextStyle(fontSize: 12, color: Colors.red),
),
],
);
}
}
EVM Balance Conversions
Wei to ETH Conversion
Copy
Ask AI
import 'package:web3dart/web3dart.dart';
/// Convert Wei to ETH
String weiToEth(BigInt wei, {int decimals = 6}) {
final ethValue = wei / BigInt.from(10).pow(18);
return ethValue.toStringAsFixed(decimals);
}
// Usage
final balanceWei = BigInt.from(1500000000000000000); // 1.5 ETH
final balanceEth = weiToEth(balanceWei);
print('Balance: $balanceEth ETH');
ETH to Wei Conversion
Copy
Ask AI
import 'package:web3dart/web3dart.dart';
/// Convert ETH to Wei
BigInt ethToWei(double eth) {
return BigInt.from(eth * 1e18);
}
// Usage
final ethAmount = 1.5;
final weiAmount = ethToWei(ethAmount);
print('$ethAmount ETH = $weiAmount Wei');
Gwei Conversions
Copy
Ask AI
/// Convert Wei to Gwei
double weiToGwei(BigInt wei) {
return wei.toDouble() / 1e9; // 1 Gwei = 10^9 Wei
}
/// Convert Gwei to Wei
BigInt gweiToWei(double gwei) {
return BigInt.from(gwei * 1e9);
}
// Usage for gas prices
final gasPriceGwei = 50.0;
final gasPriceWei = gweiToWei(gasPriceGwei);
print('Gas Price: $gasPriceGwei Gwei = $gasPriceWei Wei');
Balance Formatting
Copy
Ask AI
/// Format EVM balance with appropriate units
String formatEvmBalance(BigInt wei) {
final eth = wei.toDouble() / 1e18;
if (eth >= 1.0) {
return '${eth.toStringAsFixed(4)} ETH';
} else if (eth >= 0.001) {
return '${eth.toStringAsFixed(6)} ETH';
} else {
final gwei = wei.toDouble() / 1e9;
return '${gwei.toStringAsFixed(2)} 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
String lamportsToSol(int lamports, {int decimals = 6}) {
final solValue = lamports / 1e9;
return solValue.toStringAsFixed(decimals);
}
// Usage
final balanceLamports = 1500000000; // 1.5 SOL
final balanceSol = lamportsToSol(balanceLamports);
print('Balance: $balanceSol SOL');
SOL to Lamports Conversion
Copy
Ask AI
/// Convert SOL to lamports
int solToLamports(double sol) {
return (sol * 1e9).toInt();
}
// Usage
final solAmount = 1.5;
final lamportsAmount = solToLamports(solAmount);
print('$solAmount SOL = $lamportsAmount lamports');
SOL Balance Formatting
Copy
Ask AI
/// Format SOL balance for display
String formatSolBalance(int lamports) {
final sol = lamports / 1e9;
if (sol >= 1.0) {
return '${sol.toStringAsFixed(4)} SOL';
} else if (sol >= 0.001) {
return '${sol.toStringAsFixed(6)} SOL';
} else {
return '${sol.toStringAsFixed(9)} SOL';
}
}
Multi-Chain Balance Display
Handle balances for both EVM and Solana wallets:Copy
Ask AI
import 'package:dynamic_sdk/dynamic_sdk.dart';
final sdk = DynamicSDK.instance;
Future<void> displayBalance(BaseWallet wallet) async {
try {
final balance = await sdk.wallets.getBalance(wallet: wallet);
final chain = wallet.chain.toUpperCase();
switch (chain) {
case 'EVM':
print('Balance: $balance (in Wei)');
break;
case 'SOL':
print('Balance: $balance (in lamports)');
break;
default:
print('Balance: $balance');
}
} catch (e) {
print('Failed to get balance: $e');
}
}
// Display all wallet balances
Future<void> displayAllBalances() async {
for (final wallet in sdk.wallets.userWallets) {
print('${wallet.chain} wallet: ${wallet.address}');
await displayBalance(wallet);
}
}
Conversion Helper Class
Copy
Ask AI
/// Helper class for balance conversions
class BalanceConverter {
/// EVM conversions
static double weiToEth(BigInt wei) {
return wei.toDouble() / 1e18;
}
static BigInt ethToWei(double eth) {
return BigInt.from(eth * 1e18);
}
static double weiToGwei(BigInt wei) {
return wei.toDouble() / 1e9;
}
/// Solana conversions
static double lamportsToSol(int lamports) {
return lamports / 1e9;
}
static int solToLamports(double sol) {
return (sol * 1e9).toInt();
}
/// Format for display
static String formatBalance({
required String value,
required String chain,
int decimals = 4,
}) {
switch (chain.toUpperCase()) {
case 'EVM':
final wei = BigInt.tryParse(value);
if (wei != null) {
final eth = weiToEth(wei);
return '${eth.toStringAsFixed(decimals)} ETH';
}
break;
case 'SOL':
final lamports = int.tryParse(value);
if (lamports != null) {
final sol = lamportsToSol(lamports);
return '${sol.toStringAsFixed(decimals)} SOL';
}
break;
}
return value;
}
}
// Usage
final 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
import 'package:flutter/foundation.dart';
import 'package:dynamic_sdk/dynamic_sdk.dart';
class BalanceCache extends ChangeNotifier {
final Map<String, String> _balances = {};
final sdk = DynamicSDK.instance;
Map<String, String> get balances => _balances;
Future<void> refreshBalance(BaseWallet wallet) async {
try {
final balance = await sdk.wallets.getBalance(wallet: wallet);
_balances[wallet.address] = balance;
notifyListeners();
} catch (e) {
print('Failed to refresh balance: $e');
}
}
Future<void> refreshAllBalances() async {
for (final wallet in sdk.wallets.userWallets) {
await refreshBalance(wallet);
}
}
}
2. Handle Precision
Copy
Ask AI
// Use BigInt for EVM to avoid precision loss
final wei = BigInt.parse('1500000000000000000'); // 1.5 ETH
final eth = BalanceConverter.weiToEth(wei);
// Use int for Solana
final lamports = 1500000000; // 1.5 SOL
final sol = BalanceConverter.lamportsToSol(lamports);
3. Refresh After Transactions
Copy
Ask AI
Future<void> sendTransactionAndRefresh(BaseWallet wallet) async {
try {
// Send transaction
final txHash = await sendTransaction(wallet: wallet);
print('Transaction sent: $txHash');
// Wait a moment for blockchain confirmation
await Future.delayed(const Duration(seconds: 2));
// Refresh balance
final newBalance = await sdk.wallets.getBalance(wallet: wallet);
print('New balance: $newBalance');
} catch (e) {
print('Error: $e');
}
}
FutureBuilder Example
Copy
Ask AI
import 'package:flutter/material.dart';
import 'package:dynamic_sdk/dynamic_sdk.dart';
class BalanceDisplay extends StatelessWidget {
final BaseWallet wallet;
const BalanceDisplay({Key? key, required this.wallet}) : super(key: key);
@override
Widget build(BuildContext context) {
return FutureBuilder<String>(
future: DynamicSDK.instance.wallets.getBalance(wallet: wallet),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text(
'Error: ${snapshot.error}',
style: const TextStyle(color: Colors.red),
);
}
if (snapshot.hasData) {
final formatted = BalanceConverter.formatBalance(
value: snapshot.data!,
chain: wallet.chain,
);
return Text(
formatted,
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
);
}
return const Text('No data');
},
);
}
}
Next Steps
- Send ETH Transactions - Transfer ETH
- Send Solana Transactions - Transfer SOL
- Network Management - Switch networks
- ERC-20 Token Transfers - Send ERC-20 tokens