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

Chrome扩展接入MetaMask:Web端代码无法检测MetaMask的迁移方案咨询

Chrome扩展适配MetaMask身份验证解决方案

核心原因

原有Web代码失效的根本原因是Chrome扩展的JavaScript运行上下文(包括弹窗页、内容脚本)默认与宿主网页上下文隔离,无法直接访问MetaMask注入到宿主页面的window.ethereum对象。

适配方案(支持Manifest V3主流版本)

1. 配置manifest.json

添加必要权限、注入脚本声明和可访问资源配置:

{
  "manifest_version": 3,
  "name": "你的扩展名称",
  "version": "1.0.0",
  "permissions": ["activeTab", "scripting"],
  "host_permissions": ["<all_urls>"],
  "action": {
    "default_popup": "popup.html"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content-script.js"]
    }
  ],
  "web_accessible_resources": [
    {
      "resources": ["inject.js"],
      "matches": ["<all_urls>"]
    }
  ]
}

2. 编写页面注入脚本inject.js

该脚本会被注入到宿主页面执行,可以直接访问window.ethereum对象,负责处理MetaMask交互逻辑:

window.addEventListener('message', async (event) => {
  if (event.source !== window || !event.data.type || event.data.source !== 'custom-extension') return

  if (event.data.type === 'REQUEST_METAMASK_ACCOUNTS') {
    if (!window.ethereum) {
      window.postMessage({
        type: 'METAMASK_ACCOUNTS_RESPONSE',
        source: 'custom-extension',
        error: 'MetaMask not installed'
      }, '*')
      return
    }
    try {
      const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' })
      window.postMessage({
        type: 'METAMASK_ACCOUNTS_RESPONSE',
        source: 'custom-extension',
        data: accounts
      }, '*')
    } catch (e) {
      window.postMessage({
        type: 'METAMASK_ACCOUNTS_RESPONSE',
        source: 'custom-extension',
        error: e.message
      }, '*')
    }
  }
})

3. 编写桥接用内容脚本content-script.js

负责在扩展上下文和宿主页面之间转发消息:

// 向宿主页面注入inject.js
const injectScript = document.createElement('script')
injectScript.src = chrome.runtime.getURL('inject.js')
document.documentElement.appendChild(injectScript)
injectScript.onload = () => injectScript.remove()

// 接收页面返回的MetaMask消息,转发到扩展弹窗
window.addEventListener('message', (event) => {
  if (event.source !== window || !event.data.type || event.data.source !== 'custom-extension') return
  if (event.data.type === 'METAMASK_ACCOUNTS_RESPONSE') {
    chrome.runtime.sendMessage(event.data)
  }
})

// 接收扩展弹窗的请求,转发到页面
chrome.runtime.onMessage.addListener((message) => {
  if (message.type === 'REQUEST_METAMASK_ACCOUNTS' && message.source === 'custom-extension') {
    window.postMessage(message, '*')
  }
})

4. 改造原有弹窗逻辑(popup.js)

替换原有直接访问window.ethereum的逻辑,改为通过消息传递调用MetaMask能力:

function toggleButton() {
  const loginButton = document.getElementById("login-button");
  loginButton.addEventListener("click", loginWithMetaMask);
}

async function loginWithMetaMask() {
  const [currentTab] = await chrome.tabs.query({active: true, currentWindow: true})
  chrome.tabs.sendMessage(currentTab.id, {
    type: 'REQUEST_METAMASK_ACCOUNTS',
    source: 'custom-extension'
  }, (response) => {
    const loginButton = document.getElementById("login-button");
    if (response.error) {
      if (response.error === 'MetaMask not installed') {
        loginButton.innerText = "请先安装MetaMask";
      }
      console.error(response.error)
      return
    }
    const userWallet = document.getElementById("user-wallet");
    userWallet.innerText = response.data[0];
  })
}

window.addEventListener("DOMContentLoaded", toggleButton);

注意事项

  • 调试时请确保当前激活的标签页为普通网页,Chrome内置页面(如chrome://extensions/)无法注入脚本,会导致调用失败
  • 首次请求账号时会弹出MetaMask授权窗口,用户完成授权后即可正常获取钱包地址

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 23:54:03