Skip to main content

Overview

The ZKScore React SDK provides a comprehensive set of hooks for integrating ZKScore functionality into your React applications. All hooks support both ZKS IDs and wallet addresses with automatic resolution.
All hooks automatically handle ZKS ID resolution, so you can use either ZKS IDs (like alice.zks) or wallet addresses in your components. The SDK will resolve them to the appropriate format.

Core Hooks

useScore

Get current score data for an identity.
import { useScore } from '@zkscore/sdk-react';

function ScoreDisplay({ identity }) {
  const { 
    data: score, 
    loading, 
    error, 
    refetch 
  } = useScore(identity, {
    chainId: 1,
    includeBreakdown: true,
    realTime: true,
    enabled: true
  });

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

  return (
    <div>
      <h3>Score: {score?.total || 0}</h3>
      {score?.breakdown && (
        <div>
          <p>DeFi: {score.breakdown.defi}</p>
          <p>NFT: {score.breakdown.nft}</p>
          <p>Social: {score.breakdown.social}</p>
        </div>
      )}
    </div>
  );
}
Options:
  • chainId (number): Blockchain network ID
  • includeBreakdown (boolean): Include detailed breakdown
  • realTime (boolean): Enable real-time updates
  • enabled (boolean): Enable/disable the hook
Returns:
  • data: Score data object
  • loading: Loading state
  • error: Error object
  • refetch: Function to refetch data

useIdentity

Get identity information for a ZKS ID or wallet address.
import { useIdentity } from '@zkscore/sdk-react';

function IdentityCard({ identity }) {
  const { 
    data: identityData, 
    loading, 
    error 
  } = useIdentity(identity, {
    chainId: 1,
    includeMetadata: true
  });

  if (loading) return <div>Loading identity...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div className="identity-card">
      <h3>{identityData?.name || identity}</h3>
      <p>Address: {identityData?.address}</p>
      <p>Token ID: {identityData?.tokenId}</p>
      <p>Activated: {identityData?.isActivated ? 'Yes' : 'No'}</p>
    </div>
  );
}
Options:
  • chainId (number): Blockchain network ID
  • includeMetadata (boolean): Include metadata
Returns:
  • data: Identity data object
  • loading: Loading state
  • error: Error object

useAchievements

Get achievements for an identity.
import { useAchievements } from '@zkscore/sdk-react';

function AchievementsList({ identity }) {
  const { 
    data: achievements, 
    loading, 
    error 
  } = useAchievements(identity, {
    category: 'defi',
    status: 'earned',
    limit: 10,
    offset: 0
  });

  if (loading) return <div>Loading achievements...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h3>Achievements ({achievements?.earned?.length || 0})</h3>
      {achievements?.earned?.map(achievement => (
        <div key={achievement.id} className="achievement">
          <h4>{achievement.name}</h4>
          <p>{achievement.description}</p>
          <p>Points: {achievement.points}</p>
        </div>
      ))}
    </div>
  );
}
Options:
  • category (string): Filter by category
  • status (string): Filter by status
  • limit (number): Number of results
  • offset (number): Pagination offset
Returns:
  • data: Achievements data object
  • loading: Loading state
  • error: Error object

useScoreHistory

Get historical score data for an identity.
import { useScoreHistory } from '@zkscore/sdk-react';

function ScoreChart({ identity }) {
  const { 
    data: history, 
    loading, 
    error 
  } = useScoreHistory(identity, {
    timeframe: '30d',
    interval: 'daily',
    chainId: 1,
    includeBreakdown: false
  });

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

  return (
    <div>
      <h3>Score History (30 days)</h3>
      <div className="chart">
        {history?.map((point, index) => (
          <div 
            key={index} 
            className="chart-bar"
            style={{ height: `${(point.total / 1000) * 100}%` }}
            title={`${point.total} on ${point.timestamp}`}
          />
        ))}
      </div>
    </div>
  );
}
Options:
  • timeframe (string): Time period (1d, 7d, 30d, 90d, 1y, all)
  • interval (string): Data interval (hourly, daily, weekly, monthly)
  • chainId (number): Blockchain network ID
  • includeBreakdown (boolean): Include breakdown data
Returns:
  • data: Array of historical score points
  • loading: Loading state
  • error: Error object

useTrustScore

Get trust score data for an identity.
import { useTrustScore } from '@zkscore/sdk-react';

function TrustScoreDisplay({ identity }) {
  const { 
    data: trustScore, 
    loading, 
    error 
  } = useTrustScore(identity, {
    realTime: true,
    includeAttestations: true
  });

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

  return (
    <div>
      <h3>Trust Score: {trustScore?.total || 0}</h3>
      <p>Attestations: {trustScore?.attestations || 0}</p>
      <p>Verifiers: {trustScore?.verifiers || 0}</p>
    </div>
  );
}
Options:
  • realTime (boolean): Enable real-time updates
  • includeAttestations (boolean): Include attestation data
Returns:
  • data: Trust score data object
  • loading: Loading state
  • error: Error object

Advanced Hooks

useScoreBreakdown

Get detailed score breakdown for an identity.
import { useScoreBreakdown } from '@zkscore/sdk-react';

function ScoreBreakdown({ identity }) {
  const { 
    data: breakdown, 
    loading, 
    error 
  } = useScoreBreakdown(identity, {
    chainId: 1,
    includeHistory: true
  });

  if (loading) return <div>Loading breakdown...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h3>Score Breakdown</h3>
      <div className="breakdown">
        <div>DeFi: {breakdown?.defi || 0}</div>
        <div>NFT: {breakdown?.nft || 0}</div>
        <div>Social: {breakdown?.social || 0}</div>
        <div>Trading: {breakdown?.trading || 0}</div>
        <div>Governance: {breakdown?.governance || 0}</div>
        <div>Gaming: {breakdown?.gaming || 0}</div>
        <div>Identity: {breakdown?.identity || 0}</div>
        <div>Trust: {breakdown?.trust || 0}</div>
      </div>
    </div>
  );
}

useAchievementProgress

Get progress for a specific achievement.
import { useAchievementProgress } from '@zkscore/sdk-react';

function AchievementProgress({ identity, achievementId }) {
  const { 
    data: progress, 
    loading, 
    error 
  } = useAchievementProgress(identity, achievementId, {
    realTime: true
  });

  if (loading) return <div>Loading progress...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h3>Achievement Progress</h3>
      <div className="progress-bar">
        <div 
          className="progress-fill"
          style={{ width: `${progress?.percentage || 0}%` }}
        />
      </div>
      <p>{progress?.current || 0} / {progress?.required || 0}</p>
      <p>{progress?.percentage || 0}% complete</p>
    </div>
  );
}

useLeaderboard

Get leaderboard data.
import { useLeaderboard } from '@zkscore/sdk-react';

function Leaderboard({ category, metric }) {
  const { 
    data: leaderboard, 
    loading, 
    error 
  } = useLeaderboard({
    category,
    metric,
    limit: 10,
    offset: 0,
    timeframe: '30d'
  });

  if (loading) return <div>Loading leaderboard...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h3>Leaderboard</h3>
      <ol>
        {leaderboard?.rankings?.map((entry, index) => (
          <li key={entry.identity}>
            {index + 1}. {entry.identity}: {entry.score}
          </li>
        ))}
      </ol>
    </div>
  );
}

Utility Hooks

useZKScoreContext

Access the ZKScore context and configuration.
import { useZKScoreContext } from '@zkscore/sdk-react';

function ZKScoreStatus() {
  const { 
    isConnected, 
    connectionError, 
    config,
    cache,
    realTime 
  } = useZKScoreContext();

  return (
    <div>
      <p>Connected: {isConnected ? 'Yes' : 'No'}</p>
      {connectionError && <p>Error: {connectionError}</p>}
      <p>Cache enabled: {config.cache?.enabled ? 'Yes' : 'No'}</p>
      <p>Real-time enabled: {config.realTime?.enabled ? 'Yes' : 'No'}</p>
    </div>
  );
}

useZKScoreSDK

Access the underlying SDK instance.
import { useZKScoreSDK } from '@zkscore/sdk-react';

function CustomSDKUsage({ identity }) {
  const sdk = useZKScoreSDK();
  const [customData, setCustomData] = useState(null);

  useEffect(() => {
    const fetchCustomData = async () => {
      try {
        const data = await sdk.scores.getScore(identity);
        setCustomData(data);
      } catch (error) {
        console.error('Custom SDK usage error:', error);
      }
    };

    fetchCustomData();
  }, [sdk, identity]);

  return (
    <div>
      <h3>Custom SDK Usage</h3>
      <p>Score: {customData?.total || 0}</p>
    </div>
  );
}

Hook Options

Common Options

All hooks support these common options:
interface CommonHookOptions {
  enabled?: boolean;           // Enable/disable the hook
  realTime?: boolean;          // Enable real-time updates
  chainId?: number;            // Blockchain network ID
  refetchInterval?: number;    // Auto-refetch interval (ms)
  staleTime?: number;          // Data stale time (ms)
  cacheTime?: number;          // Cache time (ms)
}

Real-time Options

interface RealTimeOptions {
  realTime?: boolean;          // Enable real-time updates
  reconnectInterval?: number;  // Reconnection interval (ms)
  maxReconnectAttempts?: number; // Max reconnection attempts
}

Caching Options

interface CachingOptions {
  cache?: boolean;             // Enable caching
  ttl?: number;               // Cache TTL (ms)
  maxSize?: number;            // Max cache size
  storage?: 'memory' | 'localStorage'; // Cache storage
}

Error Handling

Error Types

interface ZKScoreError {
  code: string;
  message: string;
  details?: any;
  timestamp: string;
}

Common Error Codes

  • NETWORK_ERROR: Network connection failed
  • RATE_LIMIT_EXCEEDED: Rate limit exceeded
  • INVALID_API_KEY: Invalid API key
  • IDENTITY_NOT_FOUND: Identity not found
  • SCORE_NOT_FOUND: Score not found
  • ACHIEVEMENT_NOT_FOUND: Achievement not found

Error Handling Example

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

function ErrorHandlingExample({ identity }) {
  const { data: score, loading, error, refetch } = useScore(identity);

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

  if (error) {
    const handleError = () => {
      switch (error.code) {
        case 'NETWORK_ERROR':
          return 'Network connection failed. Please check your internet connection.';
        case 'RATE_LIMIT_EXCEEDED':
          return 'Rate limit exceeded. Please wait before making more requests.';
        case 'IDENTITY_NOT_FOUND':
          return 'Identity not found. Please check the ZKS ID or wallet address.';
        default:
          return `Error: ${error.message}`;
      }
    };

    return (
      <div className="error">
        <p>{handleError()}</p>
        <button onClick={() => refetch()}>Retry</button>
      </div>
    );
  }

  return <div>Score: {score?.total || 0}</div>;
}

Performance Optimization

1. Conditional Rendering

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

function ConditionalScore({ identity, showScore }) {
  const { data: score, loading } = useScore(identity, {
    enabled: showScore
  });

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

  return <div>Score: {score?.total || 0}</div>;
}

2. Memoization

import { useMemo } from 'react';
import { useScore } from '@zkscore/sdk-react';

function MemoizedScore({ identity }) {
  const { data: score, loading } = useScore(identity);

  const scoreDisplay = useMemo(() => {
    if (loading) return 'Loading...';
    return `Score: ${score?.total || 0}`;
  }, [score, loading]);

  return <div>{scoreDisplay}</div>;
}

3. Debounced Updates

import { useState, useEffect } from 'react';
import { useScore } from '@zkscore/sdk-react';

function DebouncedScore({ identity }) {
  const [debouncedIdentity, setDebouncedIdentity] = useState(identity);
  const { data: score, loading } = useScore(debouncedIdentity);

  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedIdentity(identity);
    }, 300);

    return () => clearTimeout(timer);
  }, [identity]);

  return (
    <div>
      {loading ? 'Loading...' : `Score: ${score?.total || 0}`}
    </div>
  );
}

TypeScript Support

Type Definitions

import { 
  useScore, 
  useIdentity, 
  useAchievements,
  ScoreData,
  Identity,
  Achievement,
  UseScoreOptions,
  UseScoreReturn
} from '@zkscore/sdk-react';

// Custom hook with types
function useTypedScore(identity: string, options?: UseScoreOptions): UseScoreReturn {
  return useScore(identity, options);
}

// Component with types
interface ScoreDisplayProps {
  identity: string;
  showBreakdown?: boolean;
}

function ScoreDisplay({ identity, showBreakdown = false }: ScoreDisplayProps) {
  const { data: score, loading, error } = useScore(identity, {
    includeBreakdown: showBreakdown
  });

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

  return (
    <div>
      <h3>Score: {score?.total || 0}</h3>
      {showBreakdown && score?.breakdown && (
        <div>
          <p>DeFi: {score.breakdown.defi}</p>
          <p>NFT: {score.breakdown.nft}</p>
        </div>
      )}
    </div>
  );
}

Best Practices

1. Hook Composition

import { useScore, useIdentity, useAchievements } from '@zkscore/sdk-react';

function UserProfile({ identity }) {
  const { data: score, loading: scoreLoading } = useScore(identity);
  const { data: identityData, loading: identityLoading } = useIdentity(identity);
  const { data: achievements, loading: achievementsLoading } = useAchievements(identity);

  const loading = scoreLoading || identityLoading || achievementsLoading;

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

  return (
    <div>
      <h2>{identityData?.name || identity}</h2>
      <p>Score: {score?.total || 0}</p>
      <p>Achievements: {achievements?.earned?.length || 0}</p>
    </div>
  );
}

2. Error Boundaries

import { ErrorBoundary } from 'react-error-boundary';
import { useScore } from '@zkscore/sdk-react';

function ScoreDisplay({ identity }) {
  const { data: score, loading, error } = useScore(identity);

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

  return <div>Score: {score?.total || 0}</div>;
}

function App() {
  return (
    <ErrorBoundary fallback={<div>Something went wrong</div>}>
      <ScoreDisplay identity="alice.zks" />
    </ErrorBoundary>
  );
}

3. Custom Hooks

import { useScore, useIdentity } from '@zkscore/sdk-react';

function useUserProfile(identity) {
  const { data: score, loading: scoreLoading, error: scoreError } = useScore(identity);
  const { data: identityData, loading: identityLoading, error: identityError } = useIdentity(identity);

  return {
    score,
    identity: identityData,
    loading: scoreLoading || identityLoading,
    error: scoreError || identityError
  };
}

function UserProfile({ identity }) {
  const { score, identity: identityData, loading, error } = useUserProfile(identity);

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

  return (
    <div>
      <h2>{identityData?.name || identity}</h2>
      <p>Score: {score?.total || 0}</p>
    </div>
  );
}