You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Wagmi v2 useConnect钩子钱包列表显示不一致及指定钱包选项的问题咨询

Wagmi v2 useConnect钩子钱包列表显示不一致及指定钱包选项的问题咨询

我来帮你逐个拆解并解决这些问题,结合你的配置和使用场景具体分析:


1. 为什么有时会同时显示“Injected”和“MetaMask”?

Wagmi的injected连接器会自动扫描浏览器中所有注入的Ethereum钱包提供者(比如MetaMask、Coinbase Wallet等)。当浏览器存在window.ethereum对象时:

  • 如果该对象带有isMetaMask属性(MetaMask注入的专属标识),Wagmi会将其识别为MetaMask独立选项
  • 如果MetaMask扩展加载时机晚于页面初始化,Wagmi初始检测时只能找到通用的Ethereum注入对象,就会显示Injected通用选项;等MetaMask加载完成后,又会额外识别出MetaMask实例,最终出现两个选项叠加的情况

简单说,这是浏览器扩展加载延迟+Wagmi实时检测逻辑共同导致的。

2. 为什么钱包列表的选项数量会在1/2/3之间变化?

核心原因有三个:

  • WalletConnect的条件加载:你的配置中只有当projectId存在时才会加入WalletConnect连接器。如果Vite环境变量没正确加载(比如你用了Create React App的REACT_APP_前缀,但Vite默认只识别VITE_开头的变量),WalletConnect就会消失
  • Injected钱包的检测不确定性:MetaMask的注入时机不稳定,页面加载时可能还未完成注入,导致Wagmi有时检测到MetaMask、有时只检测到通用Injected,极端情况下甚至检测不到任何注入钱包
  • AutoConnect的干扰autoConnect: true会在页面加载时尝试连接上次使用的钱包,临时改变连接器的状态展示

3. 如何限制钱包选项仅显示MetaMask和WalletConnect?

你需要给injected连接器添加过滤规则,只保留MetaMask;同时修复环境变量的加载问题,确保WalletConnect稳定出现。修改后的配置如下:

优化后的Wagmi配置代码

import { createConfig, http } from "wagmi";
import { mainnet, sepolia } from "wagmi/chains";
import { injected, walletConnect } from "wagmi/connectors";

// Vite环境变量需用VITE_前缀,这里替换为正确的获取方式
const projectId = import.meta.env.VITE_WALLETCONNECT_PROJECT_ID;

// 配置injected连接器,仅过滤MetaMask
const metaMaskConnector = injected({
  chains: [mainnet, sepolia],
  targetFilter: (target) => {
    // 只保留带有MetaMask标识的注入提供者
    return target.hasOwnProperty('isMetaMask') && target.isMetaMask;
  },
});

const connectors = [
  metaMaskConnector,
  ...(projectId
    ? [
        walletConnect({
          projectId,
          metadata: {
            name: "MyApp",
            description: "My application",
            url: window.location.origin,
            icons: [],
          },
          chains: [mainnet, sepolia],
        }),
      ]
    : []),
];

export const config = createConfig({
  chains: [mainnet, sepolia],
  connectors,
  transports: {
    [mainnet.id]: http(),
    [sepolia.id]: http(),
  },
  autoConnect: true,
});

关键改动:

  • injected连接器加targetFilter,彻底屏蔽通用Injected选项,只保留MetaMask
  • 适配Vite环境变量规则:将环境变量名改为VITE_WALLETCONNECT_PROJECT_ID,用import.meta.env获取,避免WalletConnect因变量未加载消失

4. 如何让钱包列表保持完全一致?

结合上面的配置,再做3个优化即可:

(1)组件中用稳定的方式获取连接器

推荐使用Wagmi的useConnectors钩子获取连接器列表,而非useConnect返回的connectors,确保拿到的是你配置中固定的连接器:

import { useConnect } from 'wagmi';
import { useConnectors } from 'wagmi';

function WalletSelector() {
  const { connect } = useConnect();
  const connectors = useConnectors(); // 获取配置中定义的所有固定连接器

  return (
    <div className="wallet-selector">
      {connectors.map((connector) => (
        <button
          key={connector.id}
          onClick={() => connect({ connector })}
          disabled={!connector.ready}
        >
          {connector.name}
        </button>
      ))}
    </div>
  );
}

(2)处理MetaMask加载延迟

监听ethereum#initialized事件,在MetaMask完成注入后自动更新连接器状态:

import { useEffect } from 'react';
import { useConnectors } from 'wagmi';

function WalletSelector() {
  const connectors = useConnectors();
  const { connect } = useConnect();

  useEffect(() => {
    function onEthereumReady() {
      // MetaMask注入完成后,Wagmi会自动同步连接器状态
    }

    if (window.ethereum) {
      onEthereumReady();
    } else {
      window.addEventListener('ethereum#initialized', onEthereumReady, { once: true });
    }

    return () => window.removeEventListener('ethereum#initialized', onEthereumReady);
  }, []);

  // ... 渲染逻辑
}

(3)固定环境变量加载

在你的.env文件中确保变量名符合Vite规则:

# .env文件内容
VITE_WALLETCONNECT_PROJECT_ID=你的WalletConnect项目ID

额外注意事项

  • 测试无MetaMask的场景:如果浏览器没装MetaMask,injected连接器会被过滤,只显示WalletConnect(当projectId存在时)
  • 禁用不必要的自动检测:通过targetFilter固定injected连接器的目标,彻底避免通用Injected选项出现
  • 重启Vite服务:修改.env文件后必须重启开发服务器,否则环境变量不会生效

按这个方案调整后,你的钱包列表就只会稳定显示MetaMask(浏览器安装时)和WalletConnect(变量存在时),不会再出现选项数量或名称的波动了。

火山引擎 最新活动