如何通过集成Phantom钱包用Vanilla JS和JSON-RPC获取Solana账户信息及SOL余额
原生JavaScript对接Phantom钱包错误修复方案
问题背景
以下原生JavaScript示例可实现Phantom钱包与Solana区块链的连接、断开功能。当前示例可正常完成钱包连接并获取公钥地址,但调用JSON-RPC请求获取钱包余额、账户信息时会执行失败,返回-32603错误,错误信息如下:
RPC Error: JsonRpcEngine: Response has no error or result for request:
修复后的方案可给偏好使用原生JS开发的开发者提供可参考的基础实现。
错误原因
- 调用对象错误:
getBalance、getAccountInfo属于Solana链RPC接口方法,不属于Phantom钱包提供的可调用方法,不能通过phantom.request发起请求 - 异步调用未处理:
phantom.request本身是异步Promise方法,未加await的情况下无法直接拿到返回结果
修复后完整实现
连接钱包函数
// 可根据需求切换为devnet/testnet的RPC地址 const SOLANA_RPC_URL = "https://api.mainnet-beta.solana.com"; // Connect Phantom async function phantom_connect() { // Check for Solana & Phantom const getProvider = () => { if ("solana" in window) { const provider = window.solana; if (provider.isPhantom) { return provider; } } alert("请先安装Phantom钱包"); return false; }; const phantom = getProvider(); if (!phantom) return; console.log("Phantom Wallet Found, Connecting.."); try { // 连接钱包,异步方法加await await phantom.connect(); // 连接成功后执行 phantom.on("connect", async () => { console.log("Phantom Connected: " + phantom.isConnected); // 获取钱包地址 const walletAddress = phantom.publicKey.toString(); console.log("Solana Wallet Address: " + walletAddress); // 获取账户信息,调用Solana RPC节点 const accountRes = await fetch(SOLANA_RPC_URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ "jsonrpc": "2.0", "id": 1, "method": "getAccountInfo", "params": [walletAddress, {"encoding": "jsonParsed"}] }) }); const accountInfo = await accountRes.json(); console.log("Solana Account Info:", accountInfo.result); // 获取钱包余额,调用Solana RPC节点 const balanceRes = await fetch(SOLANA_RPC_URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ "jsonrpc": "2.0", "id": 1, "method": "getBalance", "params": [walletAddress] }) }); const balanceData = await balanceRes.json(); // 余额单位转换:lamport转SOL,1 SOL = 1e9 lamport const solBalance = balanceData.result.value / 10**9; console.log("Solana Wallet Balance:", solBalance, "SOL"); }); } catch (err) { console.log("连接已取消或失败:", err.message); } }
断开钱包连接函数
// Disconnect Phantom async function phantom_disconnect() { if (!window.solana?.isConnected) { console.log("当前没有已连接的Phantom钱包"); return; } await window.solana.request({ method: "disconnect" }); window.solana.on('disconnect', () => { console.log("Phantom Disconnected!"); }); }
注意事项
- 可根据开发场景切换
SOLANA_RPC_URL为Solana测试网、开发网的RPC节点地址 - 生产环境建议使用自己部署的RPC节点,避免公共节点限流
内容的提问来源于stack exchange,提问作者Dapper
相关产品推荐
相关产品推荐

