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

如何使用ethers.js检测MetaMask等Web3钱包是否处于解锁状态

检测Web3钱包解锁状态的稳定通用方案

目前不存在所有钱包都通用的直接检测API,但是可以通过EIP-1102、EIP-1193规定的标准钱包交互逻辑间接实现,兼容绝大多数遵守EIP规范的钱包(包括MetaMask、Coinbase Wallet、WalletConnect等),不需要依赖MetaMask私有的实验性方法。


核心实现逻辑

  • 核心原理是调用钱包标准RPC方法eth_accounts:钱包解锁且已授权当前站点时,会直接返回账户列表;如果未授权,调用eth_requestAccounts会触发授权弹窗;如果钱包处于锁定状态,会先触发解锁弹窗,解锁完成后才会进入授权流程。
  • 如果需要纯静默检测不触发弹窗,可以通过eth_accounts的返回结果判断,不会触发任何用户交互。

代码实现(基于ethers.js v6)

场景1:检测同时允许触发解锁/授权弹窗(适合登录场景)

import { BrowserProvider } from "ethers";

async function checkWalletUnlocked() {
  if (!window.ethereum) throw new Error("未检测到Web3钱包");
  const provider = new BrowserProvider(window.ethereum);
  try {
    const accounts = await provider.send("eth_accounts", []);
    if (accounts.length > 0) {
      // 已解锁且已授权
      return true;
    }
    // 已解锁但未授权,触发授权流程
    await provider.send("eth_requestAccounts", []);
    return true;
  } catch (err) {
    // 错误码4001代表用户主动拒绝解锁/授权
    if (err.code === 4001) return false;
    // 其余错误默认判定为钱包未解锁/不可用
    return false;
  }
}

场景2:静默检测不触发任何弹窗(适合页面初始化状态判断)

async function checkWalletUnlockedSilent() {
  if (!window.ethereum) return false;
  const provider = new BrowserProvider(window.ethereum);
  try {
    const accounts = await provider.send("eth_accounts", []);
    // 只有已解锁且已授权的场景才会返回非空账户列表
    return accounts.length > 0;
  } catch (err) {
    return false;
  }
}

说明

上述实现完全基于公开的EIP标准RPC方法,没有使用任何钱包私有API,稳定性远高于MetaMask私有的window.ethereum._metamask.isUnlocked()实验性方法。
注意:静默检测只能识别「已解锁且已授权当前站点」的状态,如果用户解锁了钱包但从未给当前站点授权,静默检测也会返回false,这种场景需要主动触发一次eth_requestAccounts调用才能确认解锁状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:00:02