Metamask消息加密报错:无法读取undefined的bufferToHex属性
报错根因
该报错与@metamask/eth-sig-util采用TypeScript编写无关,核心是依赖包导入方式错误,导致ethUtil实际为undefined,调用bufferToHex方法时触发类型错误:
- 新版
ethereumjs-util(v7及以上版本)为纯ES Module包,无默认导出,使用import ethUtil from 'ethereumjs-util'写法无法获取到完整工具对象 - 新版
@metamask/eth-sig-util同样无默认导出,旧的全量导入写法也会失效
修复方案
方案1:修正导入写法(推荐,无需降级依赖)
调整导入为命名导入形式,同时移除不必要的ethereumjs-util依赖,直接用原生能力完成格式转换,修正后完整代码如下:
// 改为命名导入encrypt方法 import { encrypt } from '@metamask/eth-sig-util'; const encryptString = (encryptionKey, text) => { console.log('encryptString.encryptionKey: ' + encryptionKey); console.log('encryptString.text: ' + text); const encryptedData = encrypt({ publicKey: encryptionKey, data: text, version: 'x25519-xsalsa20-poly1305', }); // 原生Buffer转十六进制,无需额外依赖 const encryptedMessage = Buffer.from( JSON.stringify(encryptedData), 'utf-8' ).toString('hex'); // 拼接0x前缀符合以太坊数据格式规范 return `0x${encryptedMessage}`; };
若运行环境无全局Buffer对象,可使用纯JS实现十六进制转换,替换对应逻辑即可:
const bufferToHex = (buffer) => { return Array.from(new Uint8Array(buffer)) .map(byte => byte.toString(16).padStart(2, '0')) .join(''); }; const encryptedMessage = bufferToHex(new TextEncoder().encode(JSON.stringify(encryptedData)));
方案2:降级依赖版本(仅适配老项目,不推荐)
如果不想修改现有业务代码,可将两个依赖降至支持默认导出的旧版本:
npm install ethereumjs-util@6.2.1 @metamask/eth-sig-util@4.0.1
降级后原有代码可直接运行,但旧版本存在已知安全风险,不建议长期使用。
额外注意点
- 调用
eth_getEncryptionPublicKey获取公钥前,需确认用户已完成站点连接、钱包处于解锁状态,否则公钥获取失败也会导致后续加密逻辑报错 - 上述代码生成的加密结果符合Metamask格式要求,后续可直接传入
eth_decrypt方法完成解密操作
内容的提问来源于stack exchange,提问作者johnDoe
相关产品推荐
相关产品推荐

