使用@bitgo/utxo库在浏览器扩展中发送交易时出现BigInt类型错误
使用@bitgo/utxo库在浏览器扩展中发送交易时出现BigInt类型错误
看起来你遇到的问题是@bitgo/utxo库在浏览器扩展环境下内部自动使用了BigInt类型,而你的代码或打包环境没适配这种类型转换——虽然你自己没直接写BigInt,但库的浏览器版本和Node.js CommonJS版本的实现细节存在差异,导致签名交易时抛出类型错误。
问题核心分析
@bitgo/utxo的Node.js CommonJS版本(.cjs)默认用Number处理金额,但在浏览器环境加载的ES模块版本中,为了支持更大数值会自动切换到BigInt。你的扩展打包流程没有处理这种类型差异,加上浏览器环境对全局变量(比如Buffer)的处理和Node.js不同,最终触发了签名时的类型不匹配错误。
解决方案
1. 显式转换BigInt为安全整数
从错误日志看,涉及的金额(98999980000)远小于JavaScript安全整数上限(2^53-1),可以安全转为Number。修改代码中处理UTXO和交易金额的逻辑:
// 过滤UTXO时显式转换satoshis为Number const relevantUtxos = utxos.filter(utxo => Number(utxo.satoshis) > 0).map(utxo => { const satoshis = Number(utxo.satoshis); // 转换BigInt到Number const valueInVRSC = satoshis / SATS_PER_COIN; console.log(`Converting UTXO value: ${satoshis} (${valueInVRSC} VRSC) to satoshis`); return { ...utxo, originalValue: satoshis, satoshis: satoshis }; });
2. 调整签名逻辑的类型处理
在签名输入时,确保传递给TransactionBuilder的金额是Number类型,避免BigInt类型冲突:
for (let i = 0; i < relevantUtxos.length; i++) { const utxo = relevantUtxos[i]; console.log('Signing input', i, utxo); try { const hashType = bitcoin.Transaction.SIGHASH_ALL; let keyPair = ECPair.fromWIF(privateKeyWIF, NETWORK); if (!keyPair.publicKey) { console.log('Manually deriving publicKey...'); keyPair.publicKey = keyPair.getPublicKeyBuffer(); } console.log('KeyPair publicKey:', keyPair.publicKey?.toString('hex') || 'undefined'); const prevOutScript = bitcoin.address.toOutputScript(fromAddress, NETWORK); console.log('PrevOutScript (hex):', prevOutScript.toString('hex')); // 强制转换金额为Number,避免BigInt传入签名方法 const inputSatoshis = Number(utxo.satoshis); txBuilder.sign( i, keyPair, prevOutScript, hashType, inputSatoshis ); console.log('Successfully signed input', i); } catch (error) { console.error('Error signing input', i, error); throw new Error(`Failed to sign input ${i}: ${error.message}`); } }
3. 正确配置Buffer的全局注入
你当前用global.Buffer = Buffer的方式在浏览器环境下不够规范,建议通过打包工具注入:
如果用Vite,在vite.config.js中添加:
export default { define: { 'global.Buffer': 'Buffer' }, resolve: { alias: { buffer: 'buffer' } } }
如果用Webpack,配置ProvidePlugin自动注入Buffer:
const webpack = require('webpack'); module.exports = { plugins: [ new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'] }) ] }
4. 强制使用库的CommonJS版本
如果ES模块版本的BigInt处理问题无法解决,可以在打包配置中强制使用@bitgo/utxo的CommonJS版本:
// Vite配置示例 export default { resolve: { alias: { '@bitgo/utxo': require.resolve('@bitgo/utxo/dist/cjs/index.js') } } }
备注:内容来源于stack exchange,提问作者artistAhmed
相关产品推荐
相关产品推荐

