Skip to main content

useScore

Get the reputation score for an Ethereum address.
import { useScore } from '@zkscore/react';

function ScoreDisplay({ address }: { address: string }) {
  const { score, loading, error, refetch } = useScore(address);

  if (loading) return <div>Loading score...</div>;
  if (error) return <div>Error: {error.message}</div>;
  if (!score) return <div>No score available</div>;

  return (
    <div className="score-card">
      <h2>{score.overall}/1000</h2>
      <p>Rank: #{score.rank}</p>
      <p>Top {score.percentile}%</p>
      <button onClick={() => refetch()}>Refresh</button>
    </div>
  );
}

Parameters

address
string
required
Ethereum address to query
options
object
Query options

Returns

score
Score | null
Score object with overall score and breakdown
loading
boolean
Loading state
error
Error | null
Error object if request failed
refetch
function
Manually refetch score

useScoreBreakdown

Get detailed score breakdown.
import { useScoreBreakdown } from '@zkscore/react';

function ScoreBreakdown({ address }: { address: string }) {
  const { breakdown, loading } = useScoreBreakdown(address);

  if (loading) return <div>Loading...</div>;

  return (
    <div className="breakdown">
      {Object.entries(breakdown || {}).map(([category, score]) => (
        <div key={category} className="breakdown-item">
          <span>{category}</span>
          <progress value={score} max={100} />
          <span>{score}/100</span>
        </div>
      ))}
    </div>
  );
}

useScoreHistory

Get historical score data.
import { useScoreHistory } from '@zkscore/react';
import { LineChart, Line, XAxis, YAxis } from 'recharts';

function ScoreChart({ address }: { address: string }) {
  const { history, loading } = useScoreHistory(address, {
    days: 30,
  });

  if (loading) return <div>Loading chart...</div>;

  return (
    <LineChart width={600} height={300} data={history?.dataPoints}>
      <XAxis dataKey="date" />
      <YAxis />
      <Line type="monotone" dataKey="score" stroke="#7C3AED" />
    </LineChart>
  );
}

useLeaderboard

Get the score leaderboard.
import { useLeaderboard } from '@zkscore/react';

function Leaderboard() {
  const { leaders, loading, userRank } = useLeaderboard({
    limit: 100,
  });

  if (loading) return <div>Loading leaderboard...</div>;

  return (
    <div>
      {userRank && (
        <div className="user-rank">
          Your Rank: #{userRank.rank}
        </div>
      )}
      <table>
        <thead>
          <tr>
            <th>Rank</th>
            <th>User</th>
            <th>Score</th>
          </tr>
        </thead>
        <tbody>
          {leaders?.map((leader) => (
            <tr key={leader.address}>
              <td>{leader.rank}</td>
              <td>{leader.username || leader.address}</td>
              <td>{leader.score}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

Advanced Examples

Live Score with Auto-Refresh

import { useScore } from '@zkscore/react';

function LiveScore({ address }: { address: string }) {
  const { score, loading } = useScore(address, {
    refreshInterval: 30000, // Update every 30 seconds
  });

  return (
    <div className="live-score">
      <span className="pulse-dot" />
      <h2>{score?.overall || 0}</h2>
      {loading && <span className="updating">Updating...</span>}
    </div>
  );
}

Score Gating

import { useScore } from '@zkscore/react';

function GatedContent({ address, minScore = 700 }: Props) {
  const { score, loading } = useScore(address);

  if (loading) return <div>Verifying access...</div>;

  if (!score || score.overall < minScore) {
    return (
      <div className="access-denied">
        <p>Score of {minScore} required</p>
        <p>Your score: {score?.overall || 0}</p>
      </div>
    );
  }

  return <div className="premium-content">Access granted!</div>;
}

Score Progress Bar

import { useScore } from '@zkscore/react';

function ScoreProgress({ address }: { address: string }) {
  const { score } = useScore(address);

  const getNextMilestone = (current: number) => {
    if (current < 500) return 500;
    if (current < 700) return 700;
    if (current < 850) return 850;
    return 1000;
  };

  if (!score) return null;

  const nextMilestone = getNextMilestone(score.overall);
  const progress = (score.overall / nextMilestone) * 100;

  return (
    <div className="score-progress">
      <div className="progress-bar">
        <div className="fill" style={{ width: `${progress}%` }} />
      </div>
      <p>
        {score.overall} / {nextMilestone} to next milestone
      </p>
    </div>
  );
}

Comparison View

import { useScore } from '@zkscore/react';

function CompareScores({ address1, address2 }: Props) {
  const { score: score1 } = useScore(address1);
  const { score: score2 } = useScore(address2);

  if (!score1 || !score2) return <div>Loading...</div>;

  return (
    <div className="comparison">
      <div className="player">
        <h3>Player 1</h3>
        <p>{score1.overall}</p>
      </div>
      <div className="vs">VS</div>
      <div className="player">
        <h3>Player 2</h3>
        <p>{score2.overall}</p>
      </div>
    </div>
  );
}

TypeScript Types

interface Score {
  overall: number;
  rank: number;
  percentile: number;
  breakdown: {
    walletAge: number;
    transactions: number;
    defi: number;
    nfts: number;
    social: number;
  };
  lastUpdated: string;
}

interface ScoreHistory {
  dataPoints: Array<{
    date: string;
    score: number;
  }>;
  trend: 'up' | 'down' | 'stable';
  change30d: number;
}

interface LeaderboardEntry {
  rank: number;
  address: string;
  username?: string;
  score: number;
  change24h: number;
}

Next Steps