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

Flutter中使用Wallet_connect无法选择不同钱包的问题求助

问题描述

我在Flutter中使用walletconnect_dart包连接不同钱包,但点击不同钱包按钮时,所有按钮都会打开同一个钱包(比如全部打开MetaMask或Trust Wallet)。我是Flutter和Web3领域的新手,附上相关代码,希望获得解决方法或替代实现方案。

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:walletconnect_dart/walletconnect_dart.dart';

class Connect extends StatefulWidget {
  const Connect({Key? key}) : super(key: key);

  @override
  State<Connect> createState() => _ConnectState();
}

class _ConnectState extends State<Connect> {

  var connector = WalletConnect(
      bridge: 'https://bridge.walletconnect.org',
      clientMeta: const PeerMeta(
          name: 'IRISA ++',
          description: 'WalletConnect Developer App',
          url: 'https://metamask.io/',
          icons: [
            'https://files.gitbook.com/v0/b/gitbook-legacy-files/o/spaces%2F-LJJeCjcLrr53DcT1Ml7%2Favatar.png?alt=media'
          ]));

  loginUsingMetamask(BuildContext context) async {
    if (!connector.connected) {
      try {
        var session = await connector.createSession(onDisplayUri: (uri) async {
          var _uri = uri;
          await launchUrlString(uri, mode: LaunchMode.externalApplication);
        });
        print(session.accounts[0]);
        print(session.chainId);
        setState(() {
          var _session = session;
        });
      } catch (exp) {
        print(exp);
      }
    }
  }
  loginUsingTrust(BuildContext context) async {
    if (!connector.connected) {
      try {
        var session = await connector.createSession(onDisplayUri: (uri) async {
          await launchUrlString(uri, mode: LaunchMode.externalApplication);
        });
        setState(() {
        });
      } catch (exp) {
        print(exp);
      }
    }
  }
  loginUsingRain(BuildContext context) async {
    if (!connector.connected) {
      try {
        var session = await connector.createSession(onDisplayUri: (uri) async {
          await launchUrlString(uri, mode: LaunchMode.externalApplication);
        });
        setState(() {
        });
      } catch (exp) {
        print(exp);
      }
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white, //<-- SEE HERE
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset('lib/assets/images/wallet.png', width:400, height:200),
          const SizedBox(
            height: 60,
            child:Text('Connect your wallet',  style: TextStyle(
                fontSize: 28,
                fontWeight: FontWeight.bold,
                color: Colors.black)),
          ),

          SizedBox(
            width: 300, // <-- Your width
            height: 100, // <-- Your height
            child: ElevatedButton.icon(// <-- OutlinedButton
              onPressed: () => loginUsingMetamask(context),
              icon:Image.asset('lib/assets/images/metamask.png', width:50, height:50),
              label: const Text('MetaMask',  style: TextStyle(
                  fontSize: 28,
                  color: Colors.white)),
              style: ElevatedButton.styleFrom(
                  primary: Colors.brown,
                side: BorderSide(color: Colors.brown.shade900, width: 3), //<-- SEE HERE

              ),//elevated btton background
            ),
          ),
            const SizedBox(
              height: 10,
            ),
          SizedBox(
              width: 300, // <-- Your width
              height: 100, // <-- Your height
              child: OutlinedButton.icon( // <-- OutlinedButton
                onPressed: () => loginUsingTrust(context),
                icon: Image.asset('lib/assets/images/trustwallet1.png', width:50, height:50),
                label: const Text('Trust Wallet',  style: TextStyle(
                    fontSize: 28,
                    color: Colors.white)),
                style: ElevatedButton.styleFrom(
                  primary: Colors.grey.shade400,
                  side: BorderSide(color: Colors.blue.shade900, width: 3), //<-- SEE HERE
                ),
              ),
            ),
            const SizedBox(
              height: 10,
            ),
          SizedBox(
              width: 300, // <-- Your width
              height: 100, // <-- Your height
              child: OutlinedButton.icon( // <-- OutlinedButton
                onPressed: () => loginUsingRain(context),
                icon:Image.asset('lib/assets/images/rainbow.png', width:50, height:50),
                label: const Text('Rainbow',  style: TextStyle(
                    fontSize: 28,
                    color: Colors.white)),
                   style: ElevatedButton.styleFrom(
                  primary: Colors.blue,
                  side: BorderSide(color: Colors.blue.shade900, width: 3), //<-- SEE HERE

              ),
              ),
        ),
        ],
    ),
      )
    );
  }
}

问题原因

所有登录方法共用同一个WalletConnect实例,且仅调用通用的createSession()生成URI,该URI会默认唤起设备中优先级最高的钱包应用,而非指定钱包。

解决方法

针对不同钱包构造专属的深层链接(deeplink)替换通用URI,同时优化会话管理避免冲突:

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:walletconnect_dart/walletconnect_dart.dart';

class Connect extends StatefulWidget {
  const Connect({Key? key}) : super(key: key);

  @override
  State<Connect> createState() => _ConnectState();
}

class _ConnectState extends State<Connect> {
  late WalletConnect connector;

  @override
  void initState() {
    super.initState();
    _initConnector();
  }

  void _initConnector() {
    connector = WalletConnect(
      bridge: 'https://bridge.walletconnect.org',
      clientMeta: const PeerMeta(
        name: 'IRISA ++',
        description: 'WalletConnect Developer App',
        url: 'https://metamask.io/',
        icons: [
          'https://files.gitbook.com/v0/b/gitbook-legacy-files/o/spaces%2F-LJJeCjcLrr53DcT1Ml7%2Favatar.png?alt=media'
        ],
      ),
    );
  }

  // 通用登录方法,传入钱包专属deeplink前缀
  Future<void> _loginWithWallet(String walletDeeplinkPrefix) async {
    // 先断开已有会话,避免冲突
    if (connector.connected) {
      await connector.killSession();
    }

    try {
      var session = await connector.createSession(onDisplayUri: (uri) async {
        // 构造钱包专属唤起链接
        final walletUri = uri.replaceFirst('wc:', '$walletDeeplinkPrefix://wc?uri=');
        await launchUrlString(walletUri, mode: LaunchMode.externalApplication);
      });

      if (session.accounts.isNotEmpty) {
        print('连接账户: ${session.accounts[0]}');
        print('链ID: ${session.chainId}');
        setState(() {});
      }
    } catch (exp) {
      print('连接失败: $exp');
      // 失败后重置连接器,保证后续连接正常
      _initConnector();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset('lib/assets/images/wallet.png', width: 400, height: 200),
            const SizedBox(
              height: 60,
              child: Text(
                'Connect your wallet',
                style: TextStyle(
                  fontSize: 28,
                  fontWeight: FontWeight.bold,
                  color: Colors.black,
                ),
              ),
            ),
            SizedBox(
              width: 300,
              height: 100,
              child: ElevatedButton.icon(
                onPressed: () => _loginWithWallet('metamask'),
                icon: Image.asset('lib/assets/images/metamask.png', width: 50, height: 50),
                label: const Text(
                  'MetaMask',
                  style: TextStyle(fontSize: 28, color: Colors.white),
                ),
                style: ElevatedButton.styleFrom(
                  primary: Colors.brown,
                  side: BorderSide(color: Colors.brown.shade900, width: 3),
                ),
              ),
            ),
            const SizedBox(height: 10),
            SizedBox(
              width: 300,
              height: 100,
              child: OutlinedButton.icon(
                onPressed: () => _loginWithWallet('trust'),
                icon: Image.asset('lib/assets/images/trustwallet1.png', width: 50, height: 50),
                label: const Text(
                  'Trust Wallet',
                  style: TextStyle(fontSize: 28, color: Colors.white),
                ),
                style: ElevatedButton.styleFrom(
                  primary: Colors.grey.shade400,
                  side: BorderSide(color: Colors.blue.shade900, width: 3),
                ),
              ),
            ),
            const SizedBox(height: 10),
            SizedBox(
              width: 300,
              height: 100,
              child: OutlinedButton.icon(
                onPressed: () => _loginWithWallet('rainbow'),
                icon: Image.asset('lib/assets/images/rainbow.png', width: 50, height: 50),
                label: const Text(
                  'Rainbow',
                  style: TextStyle(fontSize: 28, color: Colors.white),
                ),
                style: ElevatedButton.styleFrom(
                  primary: Colors.blue,
                  side: BorderSide(color: Colors.blue.shade900, width: 3),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
补充说明
  • 不同钱包的deeplink前缀需对应官方规范,示例中使用的前缀为:
    • MetaMask: metamask
    • Trust Wallet: trust
    • Rainbow: rainbow
  • 若钱包deeplink格式不同,请参考对应钱包的官方文档调整链接构造逻辑。
  • 每次登录前断开旧会话,避免会话复用导致的异常;连接失败后重置连接器,保证后续连接可用性。

内容的提问来源于stack exchange,提问作者Tariq B AL-Maashani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 14:30:53