> ## Documentation Index
> Fetch the complete documentation index at: https://core.anylayer.org/llms.txt
> Use this file to discover all available pages before exploring further.

# ZK Verification

> Implement zero-knowledge proof verification using ZKScore

## Overview

Implement zero-knowledge proof verification to prove score thresholds or achievements without revealing exact values.

## Basic ZK Verification

### Score Threshold Proof

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { ZKScoreClient } from '@zkscore/sdk';

  const client = new ZKScoreClient({
    apiKey: process.env.ZKSCORE_API_KEY
  });

  class ZKVerification {
    constructor() {
      this.client = client;
    }
    
    async generateScoreProof(userAddress, threshold) {
      try {
        const score = await this.client.getScore(userAddress);
        
        if (score.total < threshold) {
          throw new Error('Score below threshold');
        }
        
        // Generate ZK proof that score >= threshold without revealing exact score
        const proof = await this.client.generateZKProof({
          type: 'score_threshold',
          user: userAddress,
          threshold: threshold,
          actualScore: score.total
        });
        
        return {
          proof,
          threshold,
          isValid: true
        };
      } catch (error) {
        console.error('Error generating proof:', error);
        return { isValid: false, error: error.message };
      }
    }
    
    async verifyScoreProof(proof, threshold) {
      try {
        const isValid = await this.client.verifyZKProof(proof, {
          type: 'score_threshold',
          threshold: threshold
        });
        
        return { isValid, threshold };
      } catch (error) {
        console.error('Error verifying proof:', error);
        return { isValid: false, error: error.message };
      }
    }
  }
  ```
</CodeGroup>

### Achievement Proof

<CodeGroup>
  ```javascript JavaScript theme={null}
  class AchievementProof {
    constructor(client) {
      this.client = client;
    }
    
    async generateAchievementProof(userAddress, achievementId) {
      try {
        const achievements = await this.client.getAchievements(userAddress);
        const hasAchievement = achievements.some(a => a.id === achievementId);
        
        if (!hasAchievement) {
          throw new Error('User does not have this achievement');
        }
        
        const proof = await this.client.generateZKProof({
          type: 'achievement',
          user: userAddress,
          achievementId: achievementId
        });
        
        return {
          proof,
          achievementId,
          isValid: true
        };
      } catch (error) {
        console.error('Error generating achievement proof:', error);
        return { isValid: false, error: error.message };
      }
    }
    
    async verifyAchievementProof(proof, achievementId) {
      try {
        const isValid = await this.client.verifyZKProof(proof, {
          type: 'achievement',
          achievementId: achievementId
        });
        
        return { isValid, achievementId };
      } catch (error) {
        console.error('Error verifying achievement proof:', error);
        return { isValid: false, error: error.message };
      }
    }
  }
  ```
</CodeGroup>

## React ZK Verification Component

### Proof Generation Component

<CodeGroup>
  ```javascript JavaScript theme={null}
  import React, { useState } from 'react';
  import { ZKScoreClient } from '@zkscore/sdk';

  const ZKProofGenerator = ({ userAddress }) => {
    const [threshold, setThreshold] = useState(500);
    const [proof, setProof] = useState(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);
    
    const client = new ZKScoreClient({
      apiKey: process.env.REACT_APP_ZKSCORE_API_KEY
    });
    
    const generateProof = async () => {
      try {
        setLoading(true);
        setError(null);
        
        const result = await client.generateZKProof({
          type: 'score_threshold',
          user: userAddress,
          threshold: threshold
        });
        
        setProof(result);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };
    
    return (
      <div className="zk-proof-generator">
        <h2>Generate ZK Proof</h2>
        
        <div className="form-group">
          <label>Score Threshold:</label>
          <input
            type="number"
            value={threshold}
            onChange={(e) => setThreshold(parseInt(e.target.value))}
            min="0"
            max="1000"
          />
        </div>
        
        <button 
          onClick={generateProof} 
          disabled={loading}
          className="generate-button"
        >
          {loading ? 'Generating...' : 'Generate Proof'}
        </button>
        
        {error && <div className="error">{error}</div>}
        
        {proof && (
          <div className="proof-result">
            <h3>Generated Proof</h3>
            <div className="proof-details">
              <p><strong>Threshold:</strong> {proof.threshold}</p>
              <p><strong>Valid:</strong> {proof.isValid ? 'Yes' : 'No'}</p>
            </div>
            <div className="proof-data">
              <textarea 
                value={JSON.stringify(proof.proof, null, 2)} 
                readOnly 
                rows="10"
              />
            </div>
          </div>
        )}
      </div>
    );
  };
  ```
</CodeGroup>

### Proof Verification Component

<CodeGroup>
  ```javascript JavaScript theme={null}
  const ZKProofVerifier = () => {
    const [proofData, setProofData] = useState('');
    const [threshold, setThreshold] = useState(500);
    const [verificationResult, setVerificationResult] = useState(null);
    const [loading, setLoading] = useState(false);
    
    const client = new ZKScoreClient({
      apiKey: process.env.REACT_APP_ZKSCORE_API_KEY
    });
    
    const verifyProof = async () => {
      try {
        setLoading(true);
        
        const proof = JSON.parse(proofData);
        const result = await client.verifyZKProof(proof, {
          type: 'score_threshold',
          threshold: threshold
        });
        
        setVerificationResult(result);
      } catch (error) {
        setVerificationResult({
          isValid: false,
          error: error.message
        });
      } finally {
        setLoading(false);
      }
    };
    
    return (
      <div className="zk-proof-verifier">
        <h2>Verify ZK Proof</h2>
        
        <div className="form-group">
          <label>Proof Data:</label>
          <textarea
            value={proofData}
            onChange={(e) => setProofData(e.target.value)}
            placeholder="Paste proof JSON here..."
            rows="8"
          />
        </div>
        
        <div className="form-group">
          <label>Expected Threshold:</label>
          <input
            type="number"
            value={threshold}
            onChange={(e) => setThreshold(parseInt(e.target.value))}
            min="0"
            max="1000"
          />
        </div>
        
        <button 
          onClick={verifyProof} 
          disabled={loading || !proofData}
          className="verify-button"
        >
          {loading ? 'Verifying...' : 'Verify Proof'}
        </button>
        
        {verificationResult && (
          <div className={`verification-result ${verificationResult.isValid ? 'valid' : 'invalid'}`}>
            <h3>Verification Result</h3>
            <p><strong>Valid:</strong> {verificationResult.isValid ? 'Yes' : 'No'}</p>
            {verificationResult.error && (
              <p><strong>Error:</strong> {verificationResult.error}</p>
            )}
          </div>
        )}
      </div>
    );
  };
  ```
</CodeGroup>

## Privacy-Preserving Access Control

### ZK Gating System

<CodeGroup>
  ```javascript JavaScript theme={null}
  class ZKGatingSystem {
    constructor(client) {
      this.client = client;
    }
    
    async checkZKAccess(userAddress, requirements) {
      try {
        const proofs = [];
        
        // Generate proofs for each requirement
        for (const requirement of requirements) {
          if (requirement.type === 'score_threshold') {
            const proof = await this.client.generateZKProof({
              type: 'score_threshold',
              user: userAddress,
              threshold: requirement.threshold
            });
            proofs.push(proof);
          } else if (requirement.type === 'achievement') {
            const proof = await this.client.generateZKProof({
              type: 'achievement',
              user: userAddress,
              achievementId: requirement.achievementId
            });
            proofs.push(proof);
          }
        }
        
        return {
          hasAccess: true,
          proofs: proofs
        };
      } catch (error) {
        return {
          hasAccess: false,
          error: error.message
        };
      }
    }
    
    async verifyZKAccess(proofs, requirements) {
      try {
        for (let i = 0; i < proofs.length; i++) {
          const proof = proofs[i];
          const requirement = requirements[i];
          
          const isValid = await this.client.verifyZKProof(proof, requirement);
          if (!isValid) {
            return { hasAccess: false, reason: 'Invalid proof' };
          }
        }
        
        return { hasAccess: true };
      } catch (error) {
        return { hasAccess: false, error: error.message };
      }
    }
  }
  ```
</CodeGroup>

## Advanced ZK Features

### Batch Proof Generation

<CodeGroup>
  ```javascript JavaScript theme={null}
  class BatchZKProofs {
    constructor(client) {
      this.client = client;
    }
    
    async generateBatchProofs(userAddress, requirements) {
      try {
        const proofPromises = requirements.map(async (requirement) => {
          const proof = await this.client.generateZKProof({
            type: requirement.type,
            user: userAddress,
            ...requirement.params
          });
          return { requirement, proof };
        });
        
        const results = await Promise.all(proofPromises);
        return results;
      } catch (error) {
        console.error('Error generating batch proofs:', error);
        return [];
      }
    }
    
    async verifyBatchProofs(proofs, requirements) {
      try {
        const verificationPromises = proofs.map(async (proofData, index) => {
          const requirement = requirements[index];
          const isValid = await this.client.verifyZKProof(
            proofData.proof, 
            requirement
          );
          return { requirement, isValid };
        });
        
        const results = await Promise.all(verificationPromises);
        return results;
      } catch (error) {
        console.error('Error verifying batch proofs:', error);
        return [];
      }
    }
  }
  ```
</CodeGroup>

## Best Practices

1. **Privacy First**: Never reveal exact scores or sensitive data
2. **Proof Validation**: Always verify proofs before granting access
3. **Error Handling**: Handle proof generation failures gracefully
4. **Performance**: Consider proof generation time for UX
5. **Security**: Use secure proof generation and verification

## Related Documentation

* [ZK Proofs](/advanced/zk-proofs)
* [Privacy Features](/advanced/privacy)
* [Score Gating](/sdk/examples/score-gating)
