You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React中用Wagmi实现多链钱包余额展示(仿Opensea)

多链余额展示解决方案(基于Wagmi)

要实现多链余额展示,核心是为每个目标链单独调用useBalance钩子并指定对应链的chainId,让Wagmi通过对应链的RPC节点获取余额数据。以下是具体实现方案:

基础实现:循环调用useBalance

直接遍历支持的链,对每个链实例化useBalance并传入chainId参数:

import { useAccount, useBalance } from 'wagmi';
import { BsThreeDotsVertical } from 'react-icons/bs';
import ChainLogos from './ChainLogos'; // 你的链Logo组件

function MultiChainBalance() {
  const { address, isConnected, connector } = useAccount();
  // 过滤掉Goerli测试链,保留目标链
  const targetChains = connector?.chains.filter(chain => chain.network !== 'goerli') || [];

  if (!isConnected) {
    return <div>请连接钱包</div>;
  }

  return (
    <div className="multi-chain-container">
      {targetChains.map((chain) => {
        // 为当前链单独请求余额
        const { data: balance, isLoading, isError } = useBalance({
          address,
          chainId: chain.id, // 关键:指定当前链的chainId
        });

        return (
          <div key={chain.id} className="chain-item">
            <div className="chain-info">
              <ChainLogos chainId={chain.network} />
              <div>
                <p>{chain.network}</p>
                <span>{chain.name}</span>
              </div>
            </div>

            <div className="balance-info">
              {isLoading ? (
                <p>加载中...</p>
              ) : isError ? (
                <p>获取失败</p>
              ) : (
                <div>
                  <p>{balance?.formatted}</p>
                  <span>{balance?.symbol}</span>
                </div>
              )}
              <BsThreeDotsVertical />
            </div>
          </div>
        );
      })}
    </div>
  );
}

优化方案:批量查询(减少钩子嵌套)

如果目标链数量较多,可使用Wagmi的useQueries钩子批量处理余额请求,提升代码整洁度:

import { useAccount, useQueries, useWagmiClient } from 'wagmi';
import { BsThreeDotsVertical } from 'react-icons/bs';
import ChainLogos from './ChainLogos';

function MultiChainBalance() {
  const { address, isConnected, connector } = useAccount();
  const client = useWagmiClient();
  const targetChains = connector?.chains.filter(chain => chain.network !== 'goerli') || [];

  // 批量构建余额查询配置
  const balanceQueries = targetChains.map(chain => ({
    queryKey: ['multi-chain-balance', address, chain.id],
    queryFn: () => client.getBalance({ address, chainId: chain.id }),
    enabled: isConnected && !!address, // 仅连接后执行查询
  }));

  // 执行批量查询
  const queryResults = useQueries({ queries: balanceQueries });

  if (!isConnected) {
    return <div>请连接钱包</div>;
  }

  return (
    <div className="multi-chain-container">
      {targetChains.map((chain, index) => {
        const { data: balance, isLoading, isError } = queryResults[index];
        return (
          <div key={chain.id} className="chain-item">
            <div className="chain-info">
              <ChainLogos chainId={chain.network} />
              <div>
                <p>{chain.network}</p>
                <span>{chain.name}</span>
              </div>
            </div>

            <div className="balance-info">
              {isLoading ? (
                <p>加载中...</p>
              ) : isError ? (
                <p>获取失败</p>
              ) : (
                <div>
                  <p>{balance?.formatted}</p>
                  <span>{balance?.symbol}</span>
                </div>
              )}
              <BsThreeDotsVertical />
            </div>
          </div>
        );
      })}
    </div>
  );
}

扩展:添加USD估值

如果需要像Opensea一样显示USD价值,可集成第三方价格API(如CoinGecko):

// 在余额渲染部分添加USD估值
{balance && (
  <div>
    <p>{balance.formatted}</p>
    <span>{balance.symbol}</span>
    {/* 新增USD估值 */}
    <USDValue tokenSymbol={balance.symbol} balance={balance.formatted} />
  </div>
)}

// USD估值组件示例
function USDValue({ tokenSymbol, balance }) {
  const { data: price } = useQuery({
    queryKey: ['token-price', tokenSymbol],
    queryFn: async () => {
      const res = await fetch(`https://api.coingecko.com/api/v3/simple/price?ids=${tokenSymbol.toLowerCase()}&vs_currencies=usd`);
      const data = await res.json();
      return data[tokenSymbol.toLowerCase()]?.usd;
    },
    enabled: !!tokenSymbol,
  });

  if (!price) return null;
  const usdValue = (parseFloat(balance) * price).toFixed(2);
  return <span>${usdValue} USD</span>;
}

内容的提问来源于stack exchange,提问作者Kehinde Babalola

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 19:20:29