Web3Modal V2中WalletConnect无法发起ETH交易问题求助
问题根源与解决方案
核心问题分析
从WalletConnect V1切换到V2后交易失败,主要源于三个关键差异:
- V2强制要求配置Project ID(需从WalletConnect控制台申请),未配置会导致连接后无法正常交互;
- 必须明确指定链的RPC地址和chainId,否则WalletConnect无法正确路由交易;
- WalletConnect原生provider的交易签名流程与MetaMask存在差异,需通过统一工具封装兼容。
完整可运行代码
HTML部分
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>WalletConnect V2 ETH交易Demo</title> <!-- 引入Web3Modal V2 --> <script src="https://cdn.jsdelivr.net/npm/web3modal@2.7.1/dist/index.min.js"></script> <!-- 引入Ethers.js统一处理交易 --> <script src="https://cdn.ethers.io/lib/ethers-5.7.2.umd.min.js"></script> </head> <body> <button id="connectBtn">连接钱包</button> <button id="sendTxBtn" disabled>发送测试ETH交易</button> <div id="status"></div> <script src="app.js"></script> </body> </html>
JS部分(app.js)
// 核心配置参数,需替换为自己的信息 const PROJECT_ID = "你的WalletConnect Project ID"; // 从WalletConnect控制台获取 const CHAIN_ID = 11155111; // Sepolia测试网,主网用1 const RPC_URL = "https://eth-sepolia.g.alchemy.com/v2/你的Alchemy API Key"; // 替换为稳定RPC节点 // 初始化Web3Modal const web3Modal = new Web3Modal({ projectId: PROJECT_ID, network: "sepolia", // 对应chainId的网络名称 providerOptions: { walletconnect: { package: true, // Web3Modal内置V2连接器,无需额外引入 options: { rpc: { [CHAIN_ID]: RPC_URL }, chainId: CHAIN_ID } } } }); let provider = null; let signer = null; // 连接钱包逻辑 document.getElementById('connectBtn').addEventListener('click', async () => { try { provider = await web3Modal.connect(); // 监听账户/链变化事件 provider.on('accountsChanged', () => updateSigner()); provider.on('chainChanged', () => window.location.reload()); await updateSigner(); document.getElementById('sendTxBtn').disabled = false; document.getElementById('status').textContent = `已连接账户: ${await signer.getAddress()}`; } catch (err) { document.getElementById('status').textContent = `连接失败: ${err.message}`; } }); // 更新签名器,统一兼容MetaMask/WalletConnect async function updateSigner() { const ethersProvider = new ethers.providers.Web3Provider(provider); signer = ethersProvider.getSigner(); } // 发送交易逻辑 document.getElementById('sendTxBtn').addEventListener('click', async () => { try { document.getElementById('status').textContent = "交易提交中..."; // 构造交易参数(需替换目标地址) const tx = { to: "0x你的接收地址", value: ethers.utils.parseEther("0.0001"), // 发送0.0001 ETH gasLimit: "21000", gasPrice: await provider.getGasPrice() }; // 发送并等待交易确认 const txRes = await signer.sendTransaction(tx); document.getElementById('status').textContent = `交易已提交,哈希: ${txRes.hash}`; await txRes.wait(); document.getElementById('status').textContent = `交易已确认,哈希: ${txRes.hash}`; } catch (err) { document.getElementById('status').textContent = `交易失败: ${err.message}`; } });
关键修改点说明
- 配置Project ID
- 必须前往WalletConnect控制台注册项目获取ID,否则WalletConnect V2无法建立有效连接。
- 完善链信息
- 在
walletconnect.options中指定rpc和chainId,确保WalletConnect节点能正确连接目标链,避免交易路由失败。
- 在
- 统一用Ethers.js处理交易
- 将Web3Modal返回的provider转换为Ethers.js的
Web3Provider,通过getSigner()获取签名器,抹平MetaMask与WalletConnect的签名流程差异。
- 将Web3Modal返回的provider转换为Ethers.js的
- 事件监听处理
- 监听
accountsChanged更新签名器,监听chainChanged刷新页面,避免链切换后出现交互异常。
- 监听
内容的提问来源于stack exchange,提问作者Joshua Vine
相关产品推荐
相关产品推荐

