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

# Achievement Registry Events

> Complete reference for all Achievement Registry contract events

## Overview

The ZKScore Achievement Registry contract emits events for all significant actions including achievement creation, claiming, progress updates, and badge minting. These events are essential for tracking achievement lifecycle and building real-time applications.

<Tip>
  Events are indexed on the blockchain and can be efficiently queried. They provide a complete audit trail for all achievement-related activities.
</Tip>

## Achievement Events

### AchievementCreated

Emitted when a new achievement is created.

```solidity theme={null}
event AchievementCreated(
    uint256 indexed achievementId,
    string name,
    uint8 category,
    Rarity rarity
);
```

**Parameters:**

* `achievementId` (uint256 indexed): The unique achievement ID
* `name` (string): Achievement name
* `category` (uint8): Category index (0-7)
* `rarity` (Rarity): Rarity level (0-4)

**When Emitted:**

* When `createAchievement()` is successfully called
* During batch achievement creation

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Listen for achievement creation events
  contract.on('AchievementCreated', (achievementId, name, category, rarity, event) => {
    const categories = ['DeFi', 'NFT', 'Social', 'Trading', 'Governance', 'Gaming', 'Identity', 'Trust'];
    const rarities = ['Common', 'Uncommon', 'Rare', 'Epic', 'Legendary'];
    
    console.log(`New Achievement Created:`);
    console.log(`  ID: ${achievementId.toString()}`);
    console.log(`  Name: ${name}`);
    console.log(`  Category: ${categories[category]}`);
    console.log(`  Rarity: ${rarities[rarity]}`);
    console.log(`  Block: ${event.blockNumber}`);
  });

  // Get all created achievements
  async function getAllCreatedAchievements() {
    const filter = contract.filters.AchievementCreated();
    const events = await contract.queryFilter(filter);
    
    return events.map(event => ({
      achievementId: event.args.achievementId.toString(),
      name: event.args.name,
      category: event.args.category,
      rarity: event.args.rarity,
      blockNumber: event.blockNumber,
      transactionHash: event.transactionHash
    }));
  }
  ```

  ```python Python theme={null}
  # Listen for achievement creation events
  def handle_achievement_created(event):
      categories = ['DeFi', 'NFT', 'Social', 'Trading', 'Governance', 'Gaming', 'Identity', 'Trust']
      rarities = ['Common', 'Uncommon', 'Rare', 'Epic', 'Legendary']
      
      achievement_id = event['args']['achievementId']
      name = event['args']['name']
      category = event['args']['category']
      rarity = event['args']['rarity']
      
      print(f"New Achievement Created:")
      print(f"  ID: {achievement_id}")
      print(f"  Name: {name}")
      print(f"  Category: {categories[category]}")
      print(f"  Rarity: {rarities[rarity]}")
      print(f"  Block: {event['blockNumber']}")

  # Set up event listener
  contract.events.AchievementCreated().on('data', handle_achievement_created)

  # Get all created achievements
  def get_all_created_achievements():
      filter = contract.events.AchievementCreated.createFilter(fromBlock=0)
      events = filter.get_all_entries()
      
      return [{
          'achievementId': event['args']['achievementId'],
          'name': event['args']['name'],
          'category': event['args']['category'],
          'rarity': event['args']['rarity'],
          'blockNumber': event['blockNumber'],
          'transactionHash': event['transactionHash'].hex()
      } for event in events]
  ```
</CodeGroup>

### AchievementClaimed

Emitted when a user claims an achievement.

```solidity theme={null}
event AchievementClaimed(
    address indexed user,
    uint256 indexed achievementId,
    uint256 timestamp
);
```

**Parameters:**

* `user` (address indexed): User who claimed the achievement
* `achievementId` (uint256 indexed): The claimed achievement ID
* `timestamp` (uint256): Claim timestamp

**When Emitted:**

* When `claimAchievement()` is successfully executed
* During batch achievement claims

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Listen for achievement claims
  contract.on('AchievementClaimed', (user, achievementId, timestamp, event) => {
    console.log(`Achievement Claimed:`);
    console.log(`  User: ${user}`);
    console.log(`  Achievement ID: ${achievementId.toString()}`);
    console.log(`  Timestamp: ${new Date(timestamp.toNumber() * 1000).toISOString()}`);
    console.log(`  Transaction: ${event.transactionHash}`);
  });

  // Track specific user's claims
  const userFilter = contract.filters.AchievementClaimed('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb');
  contract.on(userFilter, (user, achievementId, timestamp, event) => {
    console.log(`Alice claimed achievement ${achievementId.toString()}`);
  });

  // Get user's claim history
  async function getUserClaimHistory(userAddress) {
    const filter = contract.filters.AchievementClaimed(userAddress);
    const events = await contract.queryFilter(filter);
    
    return events.map(event => ({
      achievementId: event.args.achievementId.toString(),
      timestamp: event.args.timestamp.toNumber(),
      blockNumber: event.blockNumber,
      transactionHash: event.transactionHash
    }));
  }
  ```

  ```python Python theme={null}
  # Listen for achievement claims
  def handle_achievement_claimed(event):
      user = event['args']['user']
      achievement_id = event['args']['achievementId']
      timestamp = event['args']['timestamp']
      
      print(f"Achievement Claimed:")
      print(f"  User: {user}")
      print(f"  Achievement ID: {achievement_id}")
      print(f"  Timestamp: {timestamp}")
      print(f"  Transaction: {event['transactionHash'].hex()}")

  # Set up event listener
  contract.events.AchievementClaimed().on('data', handle_achievement_claimed)

  # Track specific user's claims
  user_filter = contract.events.AchievementClaimed.createFilter(
      fromBlock='latest',
      argument_filters={'user': '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb'}
  )

  # Get user's claim history
  def get_user_claim_history(user_address):
      filter = contract.events.AchievementClaimed.createFilter(
          fromBlock=0,
          argument_filters={'user': user_address}
      )
      events = filter.get_all_entries()
      
      return [{
          'achievementId': event['args']['achievementId'],
          'timestamp': event['args']['timestamp'],
          'blockNumber': event['blockNumber'],
          'transactionHash': event['transactionHash'].hex()
      } for event in events]
  ```
</CodeGroup>

### AchievementUpdated

Emitted when an achievement's configuration is updated.

```solidity theme={null}
event AchievementUpdated(
    uint256 indexed achievementId,
    bytes updateData
);
```

**Parameters:**

* `achievementId` (uint256 indexed): The updated achievement ID
* `updateData` (bytes): Encoded update data

**When Emitted:**

* When `updateAchievement()` is called
* When achievement parameters are modified

### AchievementDeactivated

Emitted when an achievement is deactivated.

```solidity theme={null}
event AchievementDeactivated(
    uint256 indexed achievementId,
    uint256 timestamp
);
```

**Parameters:**

* `achievementId` (uint256 indexed): The deactivated achievement ID
* `timestamp` (uint256): Deactivation timestamp

**When Emitted:**

* When `deactivateAchievement()` is called
* When achievement is permanently disabled

## Progress Events

### ProgressUpdated

Emitted when a user's progress toward an achievement is updated.

```solidity theme={null}
event ProgressUpdated(
    address indexed user,
    uint256 indexed achievementId,
    uint256 progress
);
```

**Parameters:**

* `user` (address indexed): User whose progress was updated
* `achievementId` (uint256 indexed): The achievement ID
* `progress` (uint256): New progress value

**When Emitted:**

* When `updateProgress()` is called
* When automatic progress tracking updates
* During batch progress updates

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Monitor progress updates
  contract.on('ProgressUpdated', (user, achievementId, progress, event) => {
    console.log(`Progress Update:`);
    console.log(`  User: ${user}`);
    console.log(`  Achievement: ${achievementId.toString()}`);
    console.log(`  Progress: ${progress.toString()}`);
  });

  // Track specific achievement progress across all users
  const achievementFilter = contract.filters.ProgressUpdated(null, 123);
  contract.on(achievementFilter, (user, achievementId, progress, event) => {
    console.log(`User ${user} made progress on achievement 123: ${progress.toString()}`);
  });

  // Get progress history for a user
  async function getProgressHistory(userAddress, achievementId) {
    const filter = contract.filters.ProgressUpdated(userAddress, achievementId);
    const events = await contract.queryFilter(filter);
    
    return events.map(event => ({
      progress: event.args.progress.toString(),
      blockNumber: event.blockNumber,
      timestamp: event.args.timestamp
    }));
  }
  ```

  ```python Python theme={null}
  # Monitor progress updates
  def handle_progress_updated(event):
      user = event['args']['user']
      achievement_id = event['args']['achievementId']
      progress = event['args']['progress']
      
      print(f"Progress Update:")
      print(f"  User: {user}")
      print(f"  Achievement: {achievement_id}")
      print(f"  Progress: {progress}")

  # Set up event listener
  contract.events.ProgressUpdated().on('data', handle_progress_updated)

  # Track specific achievement progress
  achievement_filter = contract.events.ProgressUpdated.createFilter(
      fromBlock='latest',
      argument_filters={'achievementId': 123}
  )

  # Get progress history
  def get_progress_history(user_address, achievement_id):
      filter = contract.events.ProgressUpdated.createFilter(
          fromBlock=0,
          argument_filters={'user': user_address, 'achievementId': achievement_id}
      )
      events = filter.get_all_entries()
      
      return [{
          'progress': event['args']['progress'],
          'blockNumber': event['blockNumber']
      } for event in events]
  ```
</CodeGroup>

## Badge Events

### BadgeMinted

Emitted when an NFT badge is minted for a claimed achievement.

```solidity theme={null}
event BadgeMinted(
    address indexed user,
    uint256 indexed achievementId,
    uint256 tokenId
);
```

**Parameters:**

* `user` (address indexed): Badge recipient
* `achievementId` (uint256 indexed): Associated achievement ID
* `tokenId` (uint256): Minted badge token ID

**When Emitted:**

* When achievement is successfully claimed
* Immediately after `AchievementClaimed` event

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Listen for badge minting
  contract.on('BadgeMinted', (user, achievementId, tokenId, event) => {
    console.log(`Badge Minted:`);
    console.log(`  User: ${user}`);
    console.log(`  Achievement: ${achievementId.toString()}`);
    console.log(`  Token ID: ${tokenId.toString()}`);
    console.log(`  Transaction: ${event.transactionHash}`);
  });

  // Get all badges for a user
  async function getUserBadges(userAddress) {
    const filter = contract.filters.BadgeMinted(userAddress);
    const events = await contract.queryFilter(filter);
    
    return events.map(event => ({
      achievementId: event.args.achievementId.toString(),
      tokenId: event.args.tokenId.toString(),
      blockNumber: event.blockNumber,
      transactionHash: event.transactionHash
    }));
  }
  ```

  ```python Python theme={null}
  # Listen for badge minting
  def handle_badge_minted(event):
      user = event['args']['user']
      achievement_id = event['args']['achievementId']
      token_id = event['args']['tokenId']
      
      print(f"Badge Minted:")
      print(f"  User: {user}")
      print(f"  Achievement: {achievement_id}")
      print(f"  Token ID: {token_id}")
      print(f"  Transaction: {event['transactionHash'].hex()}")

  # Set up event listener
  contract.events.BadgeMinted().on('data', handle_badge_minted)

  # Get all badges for a user
  def get_user_badges(user_address):
      filter = contract.events.BadgeMinted.createFilter(
          fromBlock=0,
          argument_filters={'user': user_address}
      )
      events = filter.get_all_entries()
      
      return [{
          'achievementId': event['args']['achievementId'],
          'tokenId': event['args']['tokenId'],
          'blockNumber': event['blockNumber'],
          'transactionHash': event['transactionHash'].hex()
      } for event in events]
  ```
</CodeGroup>

## Event Monitoring

### Real-time Achievement Tracker

<CodeGroup>
  ```javascript JavaScript theme={null}
  class AchievementEventMonitor {
    constructor(contract) {
      this.contract = contract;
      this.userProgress = new Map();
      this.claimHistory = [];
      this.setupListeners();
    }
    
    setupListeners() {
      // Monitor all achievement events
      this.contract.on('AchievementCreated', (id, name, category, rarity, event) => {
        this.handleAchievementCreated(id, name, category, rarity, event);
      });
      
      this.contract.on('AchievementClaimed', (user, achievementId, timestamp, event) => {
        this.handleAchievementClaimed(user, achievementId, timestamp, event);
      });
      
      this.contract.on('ProgressUpdated', (user, achievementId, progress, event) => {
        this.handleProgressUpdated(user, achievementId, progress, event);
      });
      
      this.contract.on('BadgeMinted', (user, achievementId, tokenId, event) => {
        this.handleBadgeMinted(user, achievementId, tokenId, event);
      });
    }
    
    handleAchievementCreated(id, name, category, rarity, event) {
      console.log(`New Achievement: ${name} (ID: ${id.toString()})`);
      
      // Trigger notification
      this.notifyNewAchievement(id, name, category, rarity);
    }
    
    handleAchievementClaimed(user, achievementId, timestamp, event) {
      const claim = {
        user,
        achievementId: achievementId.toString(),
        timestamp: timestamp.toNumber(),
        blockNumber: event.blockNumber,
        transactionHash: event.transactionHash
      };
      
      this.claimHistory.push(claim);
      console.log(`Achievement ${achievementId.toString()} claimed by ${user}`);
      
      // Trigger celebration
      this.celebrateClaim(user, achievementId);
    }
    
    handleProgressUpdated(user, achievementId, progress, event) {
      const key = `${user}-${achievementId.toString()}`;
      
      if (!this.userProgress.has(key)) {
        this.userProgress.set(key, []);
      }
      
      this.userProgress.get(key).push({
        progress: progress.toString(),
        blockNumber: event.blockNumber
      });
      
      console.log(`Progress update: ${user} - Achievement ${achievementId.toString()}: ${progress.toString()}`);
    }
    
    handleBadgeMinted(user, achievementId, tokenId, event) {
      console.log(`Badge #${tokenId.toString()} minted for ${user}`);
      
      // Update UI with new badge
      this.displayBadge(user, achievementId, tokenId);
    }
    
    getUserProgress(user, achievementId) {
      const key = `${user}-${achievementId}`;
      return this.userProgress.get(key) || [];
    }
    
    getRecentClaims(limit = 10) {
      return this.claimHistory.slice(-limit);
    }
    
    notifyNewAchievement(id, name, category, rarity) {
      // Implement notification logic
      console.log(`📢 New achievement available: ${name}`);
    }
    
    celebrateClaim(user, achievementId) {
      // Implement celebration logic
      console.log(`🎉 Achievement unlocked!`);
    }
    
    displayBadge(user, achievementId, tokenId) {
      // Implement badge display logic
      console.log(`🏆 Badge earned: #${tokenId.toString()}`);
    }
  }

  // Usage
  const monitor = new AchievementEventMonitor(contract);
  ```

  ```python Python theme={null}
  class AchievementEventMonitor:
      def __init__(self, contract):
          self.contract = contract
          self.user_progress = {}
          self.claim_history = []
          self.setup_listeners()
      
      def setup_listeners(self):
          # Monitor all achievement events
          self.contract.events.AchievementCreated().on('data', self.handle_achievement_created)
          self.contract.events.AchievementClaimed().on('data', self.handle_achievement_claimed)
          self.contract.events.ProgressUpdated().on('data', self.handle_progress_updated)
          self.contract.events.BadgeMinted().on('data', self.handle_badge_minted)
      
      def handle_achievement_created(self, event):
          achievement_id = event['args']['achievementId']
          name = event['args']['name']
          category = event['args']['category']
          rarity = event['args']['rarity']
          
          print(f"New Achievement: {name} (ID: {achievement_id})")
          self.notify_new_achievement(achievement_id, name, category, rarity)
      
      def handle_achievement_claimed(self, event):
          user = event['args']['user']
          achievement_id = event['args']['achievementId']
          timestamp = event['args']['timestamp']
          
          claim = {
              'user': user,
              'achievementId': achievement_id,
              'timestamp': timestamp,
              'blockNumber': event['blockNumber'],
              'transactionHash': event['transactionHash'].hex()
          }
          
          self.claim_history.append(claim)
          print(f"Achievement {achievement_id} claimed by {user}")
          self.celebrate_claim(user, achievement_id)
      
      def handle_progress_updated(self, event):
          user = event['args']['user']
          achievement_id = event['args']['achievementId']
          progress = event['args']['progress']
          
          key = f"{user}-{achievement_id}"
          
          if key not in self.user_progress:
              self.user_progress[key] = []
          
          self.user_progress[key].append({
              'progress': progress,
              'blockNumber': event['blockNumber']
          })
          
          print(f"Progress update: {user} - Achievement {achievement_id}: {progress}")
      
      def handle_badge_minted(self, event):
          user = event['args']['user']
          achievement_id = event['args']['achievementId']
          token_id = event['args']['tokenId']
          
          print(f"Badge #{token_id} minted for {user}")
          self.display_badge(user, achievement_id, token_id)
      
      def get_user_progress(self, user, achievement_id):
          key = f"{user}-{achievement_id}"
          return self.user_progress.get(key, [])
      
      def get_recent_claims(self, limit=10):
          return self.claim_history[-limit:]
      
      def notify_new_achievement(self, achievement_id, name, category, rarity):
          print(f"📢 New achievement available: {name}")
      
      def celebrate_claim(self, user, achievement_id):
          print(f"🎉 Achievement unlocked!")
      
      def display_badge(self, user, achievement_id, token_id):
          print(f"🏆 Badge earned: #{token_id}")

  # Usage
  monitor = AchievementEventMonitor(contract)
  ```
</CodeGroup>

### Event Analytics

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Analyze achievement statistics
  async function analyzeAchievementStats() {
    const currentBlock = await provider.getBlockNumber();
    const startBlock = currentBlock - 100000;
    
    // Get all claims
    const claimFilter = contract.filters.AchievementClaimed();
    const claimEvents = await contract.queryFilter(claimFilter, startBlock, currentBlock);
    
    const stats = {
      totalClaims: claimEvents.length,
      uniqueClaimers: new Set(claimEvents.map(e => e.args.user)).size,
      mostClaimedAchievement: null,
      claimsByCategory: {},
      claimsByRarity: {},
      recentActivity: []
    };
    
    // Analyze claims by achievement
    const claimCounts = {};
    for (const event of claimEvents) {
      const id = event.args.achievementId.toString();
      claimCounts[id] = (claimCounts[id] || 0) + 1;
    }
    
    // Find most claimed
    const mostClaimed = Object.entries(claimCounts)
      .sort(([,a], [,b]) => b - a)[0];
    
    if (mostClaimed) {
      stats.mostClaimedAchievement = {
        id: mostClaimed[0],
        claims: mostClaimed[1]
      };
    }
    
    // Get recent activity (last 10 claims)
    stats.recentActivity = claimEvents
      .slice(-10)
      .map(e => ({
        user: e.args.user,
        achievementId: e.args.achievementId.toString(),
        timestamp: e.args.timestamp.toNumber(),
        blockNumber: e.blockNumber
      }));
    
    return stats;
  }
  ```

  ```python Python theme={null}
  # Analyze achievement statistics
  def analyze_achievement_stats():
      current_block = w3.eth.block_number
      start_block = current_block - 100000
      
      # Get all claims
      claim_filter = contract.events.AchievementClaimed.createFilter(
          fromBlock=start_block,
          toBlock=current_block
      )
      claim_events = claim_filter.get_all_entries()
      
      stats = {
          'totalClaims': len(claim_events),
          'uniqueClaimers': len(set(e['args']['user'] for e in claim_events)),
          'mostClaimedAchievement': None,
          'claimsByCategory': {},
          'claimsByRarity': {},
          'recentActivity': []
      }
      
      # Analyze claims by achievement
      claim_counts = {}
      for event in claim_events:
          achievement_id = str(event['args']['achievementId'])
          claim_counts[achievement_id] = claim_counts.get(achievement_id, 0) + 1
      
      # Find most claimed
      if claim_counts:
          most_claimed = max(claim_counts.items(), key=lambda x: x[1])
          stats['mostClaimedAchievement'] = {
              'id': most_claimed[0],
              'claims': most_claimed[1]
          }
      
      # Get recent activity
      stats['recentActivity'] = [{
          'user': event['args']['user'],
          'achievementId': str(event['args']['achievementId']),
          'timestamp': event['args']['timestamp'],
          'blockNumber': event['blockNumber']
      } for event in claim_events[-10:]]
      
      return stats
  ```
</CodeGroup>

## Best Practices

### Event Handling

1. **Use Indexed Parameters**: Filter events efficiently using indexed parameters
2. **Handle Missing Events**: Implement retry logic for missed events
3. **Store Event Data**: Cache important event data locally
4. **Monitor Gas Costs**: Be aware of gas costs for event queries
5. **Error Recovery**: Implement error handling for event listeners

### Performance Optimization

1. **Limit Block Ranges**: Query smaller block ranges to avoid timeouts
2. **Use Filters**: Apply filters to reduce data processing
3. **Batch Processing**: Process multiple events in batches
4. **Cache Results**: Cache frequently accessed event data
5. **Pagination**: Implement pagination for large event sets

## Related Documentation

* [Contract Overview](/contracts/achievement-registry/overview) - Contract architecture and features
* [Functions Reference](/contracts/achievement-registry/functions) - Complete function documentation
* [Integration Guide](/contracts/achievement-registry/integration) - Integration examples
* [Custom Achievements](/contracts/achievement-registry/custom-achievements) - Creating custom achievements
