使用@metamask/detect-provider切换MetaMask账户始终读取首个账户问题
@metamask/detect-provider 切换账户未识别问题修复方案
问题根因
- 仅在钱包首次连接成功时获取一次当前账户,未监听MetaMask的账户变更事件,后续钱包内切换账户时程序无法感知状态变化
- 业务逻辑中硬编码/永久缓存了首次获取的第一个账户地址,调用时始终读取旧的缓存值,未同步钱包的最新选中状态
修复实现
1. 新增账户变更事件监听
初始化provider后必须注册accountsChanged事件回调,实时更新当前使用的账户:
import detectEthereumProvider from '@metamask/detect-provider'; // 全局维护当前生效的账户地址 let currentAccount = ''; const initMetaMask = async () => { const provider = await detectEthereumProvider(); if (!provider) { console.error('未检测到MetaMask钱包'); return; } // 首次连接请求账户授权 const accounts = await provider.request({ method: 'eth_requestAccounts' }); currentAccount = accounts[0]; // 监听账户切换事件 provider.on('accountsChanged', (newAccounts) => { // 切换后更新全局账户值 currentAccount = newAccounts[0]; // 此处可追加账户切换后的业务逻辑,例如重新拉取链上资产、重置之前的签名/交易状态 }); // 可选补充:监听链ID变更,避免跨链调用异常 provider.on('chainChanged', (newChainId) => { console.log('当前链ID已更新为', newChainId); }); }
2. 业务逻辑调用规范
- 所有需要用到当前账户的逻辑,禁止使用首次连接时缓存的固定值,统一读取全局维护的
currentAccount变量 - 页面每次重新挂载时,主动调用
eth_accounts接口同步最新账户状态,避免页面刷新后本地存储值和钱包实际状态不一致:
// 页面挂载时同步最新账户 const syncAccountStatus = async () => { const provider = await detectEthereumProvider(); if (provider) { const latestAccounts = await provider.request({ method: 'eth_accounts' }); if (latestAccounts[0] && latestAccounts[0] !== currentAccount) { currentAccount = latestAccounts[0]; } } }
内容的提问来源于stack exchange,提问作者Bassirou Degbembia
相关产品推荐
相关产品推荐

