> ## 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.

# Viem Integration

> Integrate ZKScore contracts with viem library

## Overview

Complete guide for integrating ZKScore smart contracts using the viem library.

## Installation

```bash theme={null}
npm install viem
# or
yarn add viem
```

## Basic Setup

### Client Configuration

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { createPublicClient, createWalletClient, http } from 'viem';
  import { mainnet, polygon, arbitrum, base } from 'viem/chains';

  // Public client for read operations
  const publicClient = createPublicClient({
    chain: mainnet,
    transport: http('https://eth-mainnet.alchemyapi.io/v2/YOUR_API_KEY')
  });

  // Wallet client for write operations
  const walletClient = createWalletClient({
    chain: mainnet,
    transport: http('https://eth-mainnet.alchemyapi.io/v2/YOUR_API_KEY'),
    account: privateKeyToAccount(PRIVATE_KEY)
  });
  ```
</CodeGroup>

### Contract Configuration

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Contract addresses
  const CONTRACTS = {
    identitySBT: '0x1234567890123456789012345678901234567890',
    scoreCalculator: '0x2345678901234567890123456789012345678901',
    achievementRegistry: '0x3456789012345678901234567890123456789012',
    trustRegistry: '0x4567890123456789012345678901234567890123'
  };

  // Contract ABIs
  import IdentitySBTABI from '@zkscore/contracts/abis/IdentitySBT.json';
  import ScoreCalculatorABI from '@zkscore/contracts/abis/ScoreCalculator.json';
  ```
</CodeGroup>

## Identity Operations

### Check Identity Status

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function getIdentityInfo(userAddress) {
    try {
      const identity = await publicClient.readContract({
        address: CONTRACTS.identitySBT,
        abi: IdentitySBTABI,
        functionName: 'getIdentity',
        args: [userAddress]
      });
      
      const isActivated = await publicClient.readContract({
        address: CONTRACTS.identitySBT,
        abi: IdentitySBTABI,
        functionName: 'isActivated',
        args: [userAddress]
      });
      
      return {
        exists: identity.exists,
        zksId: identity.zksId,
        displayName: identity.displayName,
        avatarUrl: identity.avatarUrl,
        isActivated: isActivated,
        tokenId: identity.tokenId.toString()
      };
    } catch (error) {
      console.error('Error getting identity:', error);
      return null;
    }
  }
  ```
</CodeGroup>

### Mint Identity

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function mintIdentity(zksId, displayName, avatarUrl) {
    try {
      // Get minting fee
      const mintingFee = await publicClient.readContract({
        address: CONTRACTS.identitySBT,
        abi: IdentitySBTABI,
        functionName: 'mintingFee'
      });
      
      console.log('Minting fee:', formatEther(mintingFee), 'ETH');
      
      // Execute transaction
      const hash = await walletClient.writeContract({
        address: CONTRACTS.identitySBT,
        abi: IdentitySBTABI,
        functionName: 'mintIdentity',
        args: [zksId, displayName, avatarUrl],
        value: mintingFee
      });
      
      console.log('Transaction sent:', hash);
      
      // Wait for confirmation
      const receipt = await publicClient.waitForTransactionReceipt({ hash });
      console.log('Transaction confirmed:', receipt.transactionHash);
      
      return receipt;
    } catch (error) {
      console.error('Minting failed:', error);
      throw error;
    }
  }
  ```
</CodeGroup>

## Score Operations

### Get User Score

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function getUserScore(userAddress) {
    try {
      const score = await publicClient.readContract({
        address: CONTRACTS.scoreCalculator,
        abi: ScoreCalculatorABI,
        functionName: 'getScore',
        args: [userAddress]
      });
      
      const breakdown = await publicClient.readContract({
        address: CONTRACTS.scoreCalculator,
        abi: ScoreCalculatorABI,
        functionName: 'getScoreBreakdown',
        args: [userAddress]
      });
      
      return {
        total: score.total.toString(),
        breakdown: {
          defi: breakdown.defi.toString(),
          nft: breakdown.nft.toString(),
          social: breakdown.social.toString(),
          trading: breakdown.trading.toString(),
          governance: breakdown.governance.toString(),
          gaming: breakdown.gaming.toString(),
          identity: breakdown.identity.toString(),
          trust: breakdown.trust.toString()
        },
        lastUpdated: new Date(Number(score.lastUpdated) * 1000)
      };
    } catch (error) {
      console.error('Error getting score:', error);
      return null;
    }
  }
  ```
</CodeGroup>

### Listen to Score Updates

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Set up event listeners
  function setupScoreListeners() {
    publicClient.watchContractEvent({
      address: CONTRACTS.scoreCalculator,
      abi: ScoreCalculatorABI,
      eventName: 'ScoreUpdated',
      onLogs: (logs) => {
        logs.forEach((log) => {
          console.log(`Score updated for ${log.args.user}:`);
          console.log(`Old: ${log.args.oldScore.toString()}, New: ${log.args.newScore.toString()}`);
          console.log(`Category: ${log.args.category}`);
          console.log(`Block: ${log.blockNumber}`);
        });
      }
    });
  }
  ```
</CodeGroup>

## Achievement Operations

### Get User Achievements

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function getUserAchievements(userAddress) {
    try {
      const achievementCount = await publicClient.readContract({
        address: CONTRACTS.achievementRegistry,
        abi: AchievementRegistryABI,
        functionName: 'getUserAchievementCount',
        args: [userAddress]
      });
      
      const achievements = [];
      for (let i = 0; i < Number(achievementCount); i++) {
        const achievement = await publicClient.readContract({
          address: CONTRACTS.achievementRegistry,
          abi: AchievementRegistryABI,
          functionName: 'getUserAchievement',
          args: [userAddress, BigInt(i)]
        });
        
        achievements.push({
          id: achievement.id.toString(),
          name: achievement.name,
          description: achievement.description,
          category: achievement.category,
          rarity: achievement.rarity,
          points: achievement.points.toString(),
          claimedAt: new Date(Number(achievement.claimedAt) * 1000)
        });
      }
      
      return achievements;
    } catch (error) {
      console.error('Error getting achievements:', error);
      return [];
    }
  }
  ```
</CodeGroup>

### Claim Achievement

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function claimAchievement(achievementId) {
    try {
      // Check if user can claim
      const canClaim = await publicClient.readContract({
        address: CONTRACTS.achievementRegistry,
        abi: AchievementRegistryABI,
        functionName: 'canClaimAchievement',
        args: [walletClient.account.address, achievementId]
      });
      
      if (!canClaim) {
        throw new Error('Cannot claim this achievement');
      }
      
      // Execute transaction
      const hash = await walletClient.writeContract({
        address: CONTRACTS.achievementRegistry,
        abi: AchievementRegistryABI,
        functionName: 'claimAchievement',
        args: [achievementId]
      });
      
      console.log('Claim transaction sent:', hash);
      const receipt = await publicClient.waitForTransactionReceipt({ hash });
      console.log('Achievement claimed!', receipt.transactionHash);
      
      return receipt;
    } catch (error) {
      console.error('Claim failed:', error);
      throw error;
    }
  }
  ```
</CodeGroup>

## Trust Registry Operations

### Create Attestation

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function createAttestation(recipient, schemaUID, data, expiration, revocable) {
    try {
      // Encode data
      const encodedData = encodeAbiParameters(
        parseAbiParameters('string, uint256, address'),
        [data.skill, BigInt(data.level), data.verifiedBy]
      );
      
      // Execute transaction
      const hash = await walletClient.writeContract({
        address: CONTRACTS.trustRegistry,
        abi: TrustRegistryABI,
        functionName: 'createAttestation',
        args: [recipient, schemaUID, encodedData, BigInt(expiration), revocable]
      });
      
      console.log('Attestation transaction sent:', hash);
      const receipt = await publicClient.waitForTransactionReceipt({ hash });
      console.log('Attestation created!', receipt.transactionHash);
      
      return receipt;
    } catch (error) {
      console.error('Attestation creation failed:', error);
      throw error;
    }
  }
  ```
</CodeGroup>

## Multi-chain Support

### Chain Configuration

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Multi-chain setup
  const chains = {
    ethereum: mainnet,
    polygon: polygon,
    arbitrum: arbitrum,
    base: base
  };

  function createClient(chainName, rpcUrl) {
    return createPublicClient({
      chain: chains[chainName],
      transport: http(rpcUrl)
    });
  }

  // Usage
  const ethereumClient = createClient('ethereum', ETHEREUM_RPC_URL);
  const polygonClient = createClient('polygon', POLYGON_RPC_URL);
  ```
</CodeGroup>

## Best Practices

1. **Use Type Safety**: Leverage viem's TypeScript support
2. **Handle Errors Gracefully**: Implement comprehensive error handling
3. **Use Event Watchers**: Watch contract events for real-time updates
4. **Batch Operations**: Combine multiple calls when possible
5. **Monitor Gas Prices**: Use appropriate gas prices for network conditions

## Related Documentation

* [Ethers Integration](/contracts/examples/ethers-integration)
* [Wagmi Integration](/contracts/examples/wagmi-integration)
* [Direct Contract Calls](/contracts/examples/direct-contract-calls)
