Ethereum
Dart / Flutter
Web3Dart is the library Dart and Flutter developers reach for when they need to talk to Ethereum. One codebase ships an Ethereum wallet or dApp to iOS, Android, web, and desktop. Add it with flutter pub add web3dart, or dart pub add web3dart for a server-side or CLI Dart project with no Flutter dependency. One rule overrides everything else: a private key controls real ETH on chain 1, so keep it in flutter_secure_storage (Keychain on iOS, Keystore on Android) and never commit it or bake it into the binary.
Web3Dart runs in both Flutter apps and plain Dart projects, so flutter pub add web3dart covers the mobile case and the same package serves a headless Dart backend. For anything that signs Ethereum transactions, store the private key in flutter_secure_storage — a hardcoded key in source is a hardcoded key in everyone's APK.
Web3Dart Library
Web3Client takes two things: the Ethereum HTTP endpoint and a Dart http.Client() it uses for transport. getBalance returns an EtherAmount, which carries wei internally and converts to ether on demand, so you never juggle 18 decimal places by hand. For transactions that move ETH or hit a busy contract, set an explicit maxGas rather than leaning on auto-estimation — gas estimation runs an eth_estimateGas simulation that can fail or undershoot on Ethereum when a contract path is conditional, and a too-low limit reverts the transaction while still burning gas.
- GitHub: https://github.com/simolus3/web3dart
- Pub.dev: https://pub.dev/packages/web3dart
- Cross-platform Flutter dApps from a single Dart codebase
- Contract interaction and transaction signing for Ethereum
- HD wallet derivation (BIP-39/44) for seed-phrase wallets
- ENS resolution for
.ethnames - ERC-20 and ERC-721 token support, plus
eth_estimateGasgas estimation
Flutter Integration Examples
A StatefulWidget holds the latest EtherAmount in its state and calls setState once the balance comes back, so the UI repaints with the new ETH value. The trap is Flutter's rebuild model: build can run many times a second during animation or scrolling, so never fire an RPC call from inside build. Trigger reads from a button, a pull-to-refresh, or a timer, and cache the result so a dozen rebuilds don't turn into a dozen requests against your CU budget.
Smart Contract Integration
Build a DeployedContract from the ABI JSON and the address it lives at on Ethereum, then look up individual functions by name. Reads go through client.call() — an eth_call that returns the decoded result without spending gas, ideal for an ERC-20 balanceOf or a totalSupply. Anything that changes state goes through client.sendTransaction() with credentials, which signs and broadcasts, then hands you the transaction hash to watch for a receipt.
Error Handling and Utilities
Web3Dart throws RPCError and transport exceptions straight from the network layer, which is noisy to handle at the UI. Catch them and rethrow a domain-specific EthereumException so the rest of your app pattern-matches one type instead of several library internals. A small extension on EtherAmount is the other half: it gives you a formatEther helper that rounds to a fixed number of decimals, so a balance reads as 1.2345 ETH in the UI rather than a raw wei integer.