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(变量存在时),不会再出现选项数量或名称的波动了。




