You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用MetaMask对Flutter应用进行身份认证?已试WalletConnect等库未果

Flutter 连接 MetaMask 实现登录认证方案

依赖配置

首先在pubspec.yaml中添加所需依赖:

dependencies:
  flutter:
    sdk: flutter
  walletconnect_flutter_v2: ^2.0.0
  web3dart: ^2.7.0
  crypto: ^3.0.3

初始化 WalletConnect V2 客户端

先去 WalletConnect 官网申请免费的ProjectID,然后初始化客户端:

import 'package:walletconnect_flutter_v2/walletconnect_flutter_v2.dart';
import 'package:web3dart/web3dart.dart';
import 'dart:convert';
import 'package:crypto/crypto.dart';

late Web3App _web3App;

void initWalletConnect() async {
  _web3App = await Web3App.createInstance(
    projectId: '你的ProjectID',
    metadata: const PairingMetadata(
      name: '你的应用名称',
      description: 'MetaMask 登录认证',
      url: 'https://your-app-url.com',
      icons: ['https://your-app-url.com/icon.png'],
    ),
  );
}

连接 MetaMask 钱包

发起连接请求,指定目标链(示例用 Goerli 测试网,主网替换为eip155:1):

Future<String?> connectMetaMask() async {
  try {
    final session = await _web3App.connect(
      requiredNamespaces: {
        'eip155': RequiredNamespace(
          chains: ['eip155:5'],
          methods: ['eth_accounts', 'personal_sign'],
          events: [],
        ),
      },
    );

    if (session != null) {
      final accounts = session.namespaces['eip155']?.accounts;
      if (accounts?.isNotEmpty == true) {
        // 提取以太坊地址格式
        final addressHex = accounts!.first.split(':').last;
        return EthereumAddress.fromHex(addressHex).hexEip55;
      }
    }
  } catch (e) {
    print('连接失败:$e');
  }
  return null;
}

签名验证实现登录

通过让用户签名随机消息完成身份认证,防止重放攻击:

Future<bool> verifyLogin(String userAddress) async {
  final session = _web3App.activeSession;
  if (session == null) return false;

  // 生成带时间戳的随机消息
  final loginMessage = '登录验证:${DateTime.now().millisecondsSinceEpoch}';
  final messageBytes = utf8.encode(loginMessage);

  try {
    // 请求 MetaMask 签名
    final signatureResult = await session.request(
      topic: session.topic,
      chainId: 'eip155:5',
      request: SessionRequestParams(
        method: 'personal_sign',
        params: [
          bytesToHex(messageBytes, include0x: true),
          userAddress,
        ],
      ),
    );

    if (signatureResult != null) {
      // 验证签名是否匹配用户地址
      final signatureBytes = hexToBytes(signatureResult.toString().replaceFirst('0x', ''));
      final signerAddress = await EthereumAddress.fromHex(userAddress).verifySignature(
        messageBytes,
        signatureBytes,
      );

      return signerAddress.hexEip55 == userAddress;
    }
  } catch (e) {
    print('签名验证失败:$e');
  }
  return false;
}

调用流程示例

在登录按钮的点击事件中串联逻辑:

void handleLoginTap() async {
  final address = await connectMetaMask();
  if (address != null) {
    final isAuthenticated = await verifyLogin(address);
    if (isAuthenticated) {
      // 登录成功,跳转主页或保存用户信息
      print('登录成功,账户:$address');
    } else {
      // 签名无效,提示用户
      print('身份验证失败');
    }
  } else {
    // 连接失败,提示用户检查 MetaMask
    print('未成功连接 MetaMask');
  }
}

注意事项

  • 移动端需配置 URL Scheme:Android 在AndroidManifest.xml中添加<data android:scheme="metamask"/>;iOS 在Info.plist中添加CFBundleURLSchemes数组,包含metamask。
  • 优先用测试网(如 Goerli)调试,避免主网资产风险。
  • 确保用户已安装 MetaMask App(移动端)或浏览器插件(Web 端)。

内容的提问来源于stack exchange,提问作者cheo jose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 15:47:41