Documentation Index
Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
Use this file to discover all available pages before exploring further.
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: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
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
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
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
/// 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
/// 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
/// 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
/// 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
/// 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: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
/// 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
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
// 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
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
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