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>;
}
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>
);
}