如何为Flutter跨平台(移动端+Web)应用对接Metamask钱包?
Flutter 跨平台对接 Metamask + web3dart 实现交易签名与发送
核心方案
用 WalletConnect 作为跨平台桥接层,统一对接 Metamask(支持 Web/安卓/iOS),再结合 web3dart 处理交易构建、签名与上链逻辑,解决单一工具包平台限制的问题。
步骤实现
1. 依赖配置
在 pubspec.yaml 中添加必要依赖:
dependencies: flutter: sdk: flutter walletconnect_dart: ^2.0.0 # 选用最新稳定版 web3dart: ^0.25.0 http: ^0.13.0 # 用于链节点请求
2. 初始化 WalletConnect 与 web3dart 客户端
import 'package:walletconnect_dart/walletconnect_dart.dart'; import 'package:web3dart/web3dart.dart'; import 'package:http/http.dart' as http; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:url_launcher/url_launcher.dart'; // 替换为你的链节点地址(如Infura、Alchemy) final String rpcUrl = "https://goerli.infura.io/v3/你的节点密钥"; final httpClient = http.Client(); final web3Client = Web3Client(rpcUrl, httpClient); // 初始化 WalletConnect 连接器 final connector = WalletConnect( bridge: 'https://bridge.walletconnect.org', clientMeta: const PeerMeta( name: '你的Flutter应用', description: '跨平台Web3交易应用', url: 'https://your-app-domain.com', icons: ['https://your-app-icon.png'], ), );
3. 连接 Metamask
Future<void> connectMetamask() async { if (!connector.connected) { // 发起会话请求,指定链ID(Goerli测试网为5,主网为1) final session = await connector.createSession(chainId: 5); // 分平台处理唤起逻辑 if (kIsWeb) { // Web端直接唤起Metamask扩展弹窗 await connector.launchUri(session.uri); } else { // 移动端通过Deep Link跳转Metamask App await launchUrl(Uri.parse(session.uri.toString())); } } }
注意:移动端需配置Metamask的Deep Link规则(安卓在
AndroidManifest.xml,iOS在Info.plist),确保跳转后能返回当前应用。
4. 获取账户与签名交易
连接成功后,通过WalletConnect获取用户地址,再用web3dart构建交易并请求签名:
// 获取已连接的账户地址 EthereumAddress? getConnectedAddress() { if (connector.connected && connector.session?.accounts.isNotEmpty == true) { return EthereumAddress.fromHex(connector.session!.accounts.first); } return null; } // 构建并签名发送交易 Future<String> sendTransaction() async { final address = getConnectedAddress(); if (address == null || !connector.connected) { throw Exception('未连接Metamask钱包'); } // 构建基础转账交易参数 final transaction = Transaction( from: address, to: EthereumAddress.fromHex('目标收款地址'), value: EtherAmount.fromUnitAndValue(EtherUnit.ether, 0.01), // 0.01 ETH gasPrice: await web3Client.getGasPrice(), maxGas: 21000, ); // 通过WalletConnect请求Metamask签名交易 final signedTx = await connector.sendTransaction( from: address.hex, to: transaction.to?.hex, value: transaction.value.getInWei.toString(), gas: transaction.maxGas.toString(), gasPrice: transaction.gasPrice?.getInWei.toString(), ); // 将已签名交易发送到链上 final txHash = await web3Client.sendRawTransaction(signedTx); return txHash; }
5. 监听连接状态
添加监听处理连接断开、账户切换等场景:
// 监听连接成功事件 connector.on('connect', (session) { // 更新UI状态、获取账户地址 }); // 监听连接断开事件 connector.on('disconnect', (session) { // 重置应用内钱包状态 });
关键注意事项
- 优先使用WalletConnect与web3dart的最新稳定版,避免兼容性问题
- 测试阶段使用测试网(如Goerli),避免主网资产损失
- Web端需提前检测用户是否安装Metamask扩展,引导用户安装
- 移动端需处理从Metamask返回后的会话恢复逻辑
内容的提问来源于stack exchange,提问作者elishambadi
相关产品推荐
相关产品推荐

