使用Phantom钱包发起Solana交易时遇toString未定义错误求助
Cannot read properties of undefined (reading 'toString')错误 错误信息
Unhandled Runtime Error
WalletSendTransactionError: Cannot read properties of undefined (reading 'toString')调用栈
PhantomWalletAdapter.sendTransaction
node_modules/@solana/wallet-adapter-phantom/lib/esm/adapter.js (138:0)
async eval
node_modules/@solana/wallet-adapter-react/lib/esm/WalletProvider.js (196:0)
核心错误原因
指令密钥属性名拼写错误:在makeTransaction函数中,给转账指令添加参考密钥时,错误使用了pubKey(大写K),而Solana的TransactionInstruction规范要求该属性名为pubkey(小写k)。Phantom钱包解析交易时无法识别错误的属性名,导致尝试调用undefined.toString()时抛出异常。
修复代码
修改cashapp.js中transferInstruction.keys.push的代码:
transferInstruction.keys.push({ pubkey: reference, // 将pubKey改为pubkey isSigner: false, isWritable: false, })
其他优化/修复点
1. 复用已有的Connection实例
makeTransaction中无需重新创建Connection,直接使用useConnection获取的实例即可,避免重复初始化:
// 修改makeTransaction函数,添加connection参数 const makeTransaction = async (fromWallet, toWallet, amount, reference, connection) => { // 移除以下重复初始化代码 // const network = WalletAdapterNetwork.Devnet // const endpoint = clusterApiUrl(network) // const connection = new Connection(endpoint) const { blockhash } = await connection.getLatestBlockhash('finalized') // ... 剩余代码保持不变 } // 在doTransaction中调用时传入connection const transaction = await makeTransaction( fromWallet, toWallet, bnAmount, reference, connection // 新增传入已有的connection )
2. 添加输入验证
在doTransaction中增加基础校验,避免无效输入导致的错误:
async function doTransaction({ amount, receiver, transactionPurpose }) { // 验证钱包已连接 if (!publicKey) { alert('请先连接钱包') return } // 验证金额有效 const bnAmount = new BigNumber(amount) if (bnAmount.isLessThanOrEqualTo(0)) { alert('请输入有效的转账金额') return } // 验证接收地址格式正确 let toWallet try { toWallet = new PublicKey(receiver) } catch (e) { alert('请输入有效的Solana地址') return } const fromWallet = publicKey const reference = Keypair.generate().publicKey const transaction = await makeTransaction( fromWallet, toWallet, bnAmount, reference, connection ) try { const txnHash = await sendTransaction(transaction, connection) console.log('交易哈希:', txnHash) // 可在此处调用addTransaction添加交易记录 addTransaction({ amount, receiver, transactionPurpose, txnHash }) } catch (e) { console.error('交易失败:', e) alert('交易失败,请检查钱包连接或输入信息') } }
3. 修复金额输入框宽度计算问题
修改useCashApp中amount的初始值,并调整输入框宽度逻辑:
// 在useCashApp中修改amount初始值 const [amount, setAmount] = useState('') // 修改NewTransactionModal中的onAmountInput const onAmountInput = (e) => { e.preventDefault() const newAmount = e.target.value setAmount(newAmount) const input = document.querySelector('input#amount') input.style.width = newAmount.length > 0 ? newAmount.length + 'ch' : '2ch' // 处理空值情况 }
内容的提问来源于stack exchange,提问作者claywintringham

