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

MetaMask调用eth_getEncryptionPublicKey获取公钥为空报错解决

问题根因

报错Missing publicKey parameter是异步执行时序问题导致的:

  • ethereum.request()是异步API,返回Promise对象,你写的.then()回调会在RPC请求返回后才执行,但你在发起请求后立刻同步执行了读取encryptionPublicKey、调用加密函数的逻辑,此时回调还没触发,encryptionPublicKey还是初始的undefined,自然会报公钥缺失错误。
  • 额外问题:window.ethereum.enable()是已废弃的旧版连接API,eth_requestAccounts已经完全覆盖其功能,不需要重复调用。
修复代码

推荐用async/await写法,逻辑更清晰,不会出现时序问题:

// 依赖说明:ethereumjs-util处理buffer转hex,@metamask/eth-sig-util是MetaMask官方维护的加密工具包,替代已废弃的旧版eth-sig-util
import { bufferToHex } from 'ethereumjs-util';
import { encrypt } from '@metamask/eth-sig-util';

// 1. 请求连接钱包,获取用户地址
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
const userAddress = accounts[0];

// 2. 等待用户授权后获取加密公钥,必须加await等待请求返回
const encryptionPublicKey = await window.ethereum.request({
  method: 'eth_getEncryptionPublicKey',
  params: [userAddress],
});

// 3. 公钥拿到后再执行加密逻辑
const encryptedMessage = bufferToHex(
  Buffer.from(
    JSON.stringify(
      encrypt({
        publicKey: encryptionPublicKey,
        data: 'hello world!',
        version: 'x25519-xsalsa20-poly1305',
      })
    ),
    'utf8'
  )
);

// 后续可以把encryptedMessage上传到链上存储
console.log('加密完成:', encryptedMessage);

如果习惯用Promise链式写法,必须把所有依赖公钥的加密逻辑放到.then()回调内部,保证公钥返回后再执行:

const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });

window.ethereum
.request({
    method: 'eth_getEncryptionPublicKey',
    params: [accounts[0]],
})
.then((encryptionPublicKey) => {
    // 加密逻辑必须写在then回调内
    const encryptedMessage = ethUtil.bufferToHex(
      Buffer.from(
        JSON.stringify(
          sigUtil.encrypt({
            publicKey: encryptionPublicKey,
            data: 'hello world!',
            version: 'x25519-xsalsa20-poly1305',
          })
        ),
        'utf8'
      )
    );
    console.log('加密完成:', encryptedMessage);
})
.catch((error) => {
    if (error.code === 4001) {
      // 用户拒绝授权的场景
      console.log("用户拒绝授权获取加密公钥,无法继续操作");
    } else {
      console.error('加密流程出错:', error);
    }
});
补充说明
  • 调用eth_getEncryptionPublicKey时MetaMask会弹出独立的授权窗口,必须用户手动确认后才能拿到公钥,必须做好拒绝授权的异常兼容。
  • 该方案全程不需要接触用户私钥,后续解密时只需要调用eth_decryptRPC方法,MetaMask会自动调起用户签名确认解密,符合钱包安全规范。
  • 旧版eth-sig-util已经停止维护,建议替换为@metamask/eth-sig-util避免版本兼容问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 08:46:08