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

如何用Puppeteer或其他工具自动化MetaMask?dAppeteer报错求方案

MetaMask自动化授权问题:dAppeteer报错及替代方案咨询

问题说明

我已用Puppeteer完成网站页面自动化流程,但无法实现MetaMask的授权操作。尝试使用dAppeteer库时出现报错,想了解是否必须依赖该库,以及是否有更优的解决方案。

复现代码

import dotenv from 'dotenv'
dotenv.config()

import dappeteer from '@chainsafe/dappeteer';

console.log('dappeteer: ', dappeteer)

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function main() {

  let browser;
  let metamask;

  browser = await dappeteer.launch({
    headless: false,
    metaMaskVersion: "v11.0.0",
    defaultViewport: null,
    automation: "puppeteer",
  })

  metamask = await dappeteer.setupMetaMask(browser, {
    seed: process.env.SEED,
    password: process.env.PASSWORD
  })
}

main();

报错日志

/home/lucrypto/Documents/code/scroll-automate/node_modules/@chainsafe/dappeteer/dist/puppeteer/page.js:73
        return new elements_1.DPuppeteerElementHandle((await this.page.waitForXPath(xpath, opts)));
                                                                       ^

TypeError: this.page.waitForXPath is not a function
    at DPupeteerPage.waitForXPath (/home/lucrypto/Documents/code/scroll-automate/node_modules/@chainsafe/dappeteer/dist/puppeteer/page.js:73:72)
    at getElementByContent (/home/lucrypto/Documents/code/scroll-automate/node_modules/@chainsafe/dappeteer/dist/helpers/selectors.js:5:71)
    at clickOnElement (/home/lucrypto/Documents/code/scroll-automate/node_modules/@chainsafe/dappeteer/dist/helpers/actions.js:51:45)
    at importAccount (/home/lucrypto/Documents/code/scroll-automate/node_modules/@chainsafe/dappeteer/dist/setup/setupActions.js:41:40)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Object.setupMetaMask (/home/lucrypto/Documents/code/scroll-automate/node_modules/@chainsafe/dappeteer/dist/setup/setupMetaMask.js:33:9)
    at async file:///home/lucrypto/Documents/code/scroll-automate/src/index.js:25:18

系统环境

  • OS:Ubuntu 20.04.6 LTS
  • Node.js版本:v20.10.0
  • dAppeteer版本:5.2.1
  • Puppeteer版本:22.0.0

需求

优先修复dAppeteer的问题,也接受其他可行的MetaMask自动化方案。


解决方案

一、修复dAppeteer报错

报错核心原因是版本不兼容:Puppeteer从v19开始重构页面API,page.waitForXPath被迁移到Frame对象下,而dAppeteer 5.2.1的代码仍在调用旧版API。

解决步骤:

  1. 降级Puppeteer到兼容版本
    安装v18.x版本的Puppeteer,该版本保留了page.waitForXPath方法,与dAppeteer 5.2.1兼容:

    npm install puppeteer@18.2.1
    
  2. 匹配MetaMask版本
    dAppeteer对MetaMask版本有严格依赖,v11.0.0可能与当前dAppeteer版本不匹配。可查看dAppeteer官方文档的版本对应表,替换为推荐的MetaMask版本(比如v10.25.0),修改代码中的metaMaskVersion参数。

二、替代方案:手动用Puppeteer操作MetaMask

如果不想依赖dAppeteer,可直接用Puppeteer模拟手动操作MetaMask,步骤如下:

  1. 准备MetaMask扩展
    下载MetaMask的CRX扩展包,或获取浏览器中已安装的MetaMask扩展ID。

  2. 启动浏览器并加载扩展
    在Puppeteer启动参数中配置扩展加载规则。

  3. 模拟MetaMask初始化流程
    用waitForSelector、click、type等API,模拟导入助记词、设置密码等操作。

  4. 处理dApp授权请求
    当dApp发起连接/交易请求时,切换到MetaMask弹窗页面,点击授权按钮。

示例代码:

import puppeteer from 'puppeteer';
import dotenv from 'dotenv';
dotenv.config();

async function main() {
  // 替换为你的MetaMask扩展路径或ID
  const metamaskExtensionPath = './path/to/metamask/crx';
  const browser = await puppeteer.launch({
    headless: false,
    args: [
      `--disable-extensions-except=${metamaskExtensionPath}`,
      `--load-extension=${metamaskExtensionPath}`,
      '--no-sandbox',
    ],
    defaultViewport: null,
  });

  // 获取MetaMask页面
  let metamaskPage;
  const pages = await browser.pages();
  for (const page of pages) {
    if (page.url().startsWith('chrome-extension://')) {
      metamaskPage = page;
      break;
    }
  }
  if (!metamaskPage) {
    metamaskPage = await browser.newPage();
    // 替换为你的MetaMask扩展ID对应的主页地址
    await metamaskPage.goto('chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/home.html');
  }

  // 模拟导入账户流程
  await metamaskPage.waitForSelector('[data-testid="onboarding-terms-checkbox"]');
  await metamaskPage.click('[data-testid="onboarding-terms-checkbox"]');
  await metamaskPage.click('[data-testid="onboarding-accept-terms"]');
  await metamaskPage.click('[data-testid="import-wallet"]');
  await metamaskPage.click('[data-testid="metametrics-i-agree"]');
  
  // 输入助记词
  const seedWords = process.env.SEED.split(' ');
  for (let i = 0; i < 12; i++) {
    await metamaskPage.type(`[data-testid="import-srp__srp-word-${i}"]`, seedWords[i]);
  }
  
  // 设置密码
  await metamaskPage.type('[data-testid="create-password"]', process.env.PASSWORD);
  await metamaskPage.type('[data-testid="confirm-password"]', process.env.PASSWORD);
  await metamaskPage.click('[data-testid="create-password-terms"]');
  await metamaskPage.click('[data-testid="import-srp-confirm"]');
  
  // 完成初始化
  await metamaskPage.waitForSelector('[data-testid="onboarding-complete-done"]');
  await metamaskPage.click('[data-testid="onboarding-complete-done"]');
  await metamaskPage.click('[data-testid="pin-extension-next"]');
  await metamaskPage.click('[data-testid="pin-extension-done"]');

  // 操作dApp并处理授权
  const dappPage = await browser.newPage();
  await dappPage.goto('https://your-dapp-url.com');
  
  // 点击连接钱包按钮
  await dappPage.click('#connect-wallet-button');
  
  // 切换到MetaMask授权弹窗
  const popupPages = await browser.pages();
  const authPopup = popupPages.find(page => page.url().includes('request') && page.url().startsWith('chrome-extension://'));
  await authPopup.waitForSelector('[data-testid="connect-approve-button"]');
  await authPopup.click('[data-testid="connect-approve-button"]');
}

main();

注意:MetaMask的页面选择器会随版本更新变化,需根据你使用的MetaMask版本调整对应的选择器。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:43:16