如何在React应用中获取Phantom钱包的相关数据?
获取Solana钱包余额与NFT持有量(React + Phantom)
1. 安装依赖
先安装Solana和Metaplex的官方JS库,用于和链上数据交互:
npm install @solana/web3.js @metaplex-foundation/js
2. 获取SOL余额
连接钱包后你已经拿到了用户的PublicKey,接下来通过Solana RPC节点查询余额:
- 创建
Connection实例,指定RPC节点(主网用https://api.mainnet-beta.solana.com,测试网用https://api.devnet.solana.com) - 调用
getBalance方法获取余额(单位是lamports,1 SOL = 10^9 lamports)
示例代码:
import { Connection, PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js'; // 初始化链连接 const connection = new Connection('https://api.devnet.solana.com', 'confirmed'); // 获取SOL余额 async function getSolBalance(publicKeyStr) { if (!publicKeyStr) return 0; const balanceLamports = await connection.getBalance(new PublicKey(publicKeyStr)); return balanceLamports / LAMPORTS_PER_SOL; }
3. 获取NFT持有量
NFT基于Metaplex标准,用Metaplex JS库查询用户持有的NFT:
- 初始化Metaplex实例并关联已创建的
Connection - 调用
findAllByOwner方法获取用户的NFT资产列表
示例代码:
import { Metaplex } from '@metaplex-foundation/js'; // 初始化Metaplex const metaplex = Metaplex.make(connection); // 获取用户NFT列表 async function getWalletNfts(publicKeyStr) { if (!publicKeyStr) return []; const nfts = await metaplex.nfts().findAllByOwner({ owner: new PublicKey(publicKeyStr) }); // 提取NFT关键信息返回 return nfts.map(nft => ({ name: nft.name, image: nft.json?.image || '', mintAddress: nft.mint.address.toBase58() })); }
4. 在React组件中整合实现
把上述逻辑和Phantom钱包连接状态结合,实现完整的展示组件:
import { useState, useEffect } from 'react'; import { Connection, PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js'; import { Metaplex } from '@metaplex-foundation/js'; const WalletDashboard = () => { const [publicKey, setPublicKey] = useState(null); const [solBalance, setSolBalance] = useState(0); const [nfts, setNfts] = useState([]); const connection = new Connection('https://api.devnet.solana.com', 'confirmed'); const metaplex = Metaplex.make(connection); // 检查钱包连接状态 useEffect(() => { const checkConnected = async () => { if (window.solana?.isPhantom) { try { const res = await window.solana.connect({ onlyIfTrusted: true }); setPublicKey(res.publicKey.toBase58()); } catch (err) { // 用户拒绝连接或钱包未授权 } } }; checkConnected(); }, []); // 钱包地址变化时拉取数据 useEffect(() => { if (!publicKey) return; const fetchData = async () => { // 获取余额 const balance = await getSolBalance(publicKey); setSolBalance(balance.toFixed(2)); // 获取NFT const walletNfts = await getWalletNfts(publicKey); setNfts(walletNfts); }; fetchData(); }, [publicKey]); // 复用余额查询函数 async function getSolBalance(key) { const balanceLamports = await connection.getBalance(new PublicKey(key)); return balanceLamports / LAMPORTS_PER_SOL; } // 复用NFT查询函数 async function getWalletNfts(key) { const nfts = await metaplex.nfts().findAllByOwner({ owner: new PublicKey(key) }); return nfts.map(nft => ({ name: nft.name, image: nft.json?.image || '', mintAddress: nft.mint.address.toBase58() })); } return ( <div className="dashboard"> {publicKey ? ( <div> <h3>已连接钱包: {publicKey}</h3> <p>SOL余额: {solBalance} SOL</p> <h4>持有NFT ({nfts.length}个)</h4> <div className="nft-list"> {nfts.map((nft, idx) => ( <div key={idx} className="nft-card"> <img src={nft.image} alt={nft.name} width="120" /> <p>{nft.name}</p> <small>{nft.mintAddress.slice(0, 10)}...</small> </div> ))} </div> </div> ) : ( <button onClick={() => window.solana.connect()}>连接Phantom钱包</button> )} </div> ); }; export default WalletDashboard;
注意事项
- RPC节点选择:生产环境建议使用付费RPC节点(如QuickNode),避免官方节点的速率限制
- 错误处理:要给异步请求添加
try/catch,处理网络异常、钱包断开等情况 - NFT过滤:如果需要筛选特定类型的NFT(如压缩NFT),可调整Metaplex查询参数或额外过滤资产属性
内容的提问来源于stack exchange,提问作者tom83310
相关产品推荐
相关产品推荐

