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

# Trust Registry Events

> Complete reference for all Trust Registry contract events

## Overview

The ZKScore Trust Registry contract emits events for all attestation lifecycle activities, schema registration, and trust score updates. These events enable real-time monitoring and off-chain indexing of the trust graph.

<Tip>
  Events provide a complete audit trail of all trust-related activities and are essential for building trust analytics and reputation systems.
</Tip>

## Attestation Events

### Attested

Emitted when a new attestation is created.

```solidity theme={null}
event Attested(
    address indexed recipient,
    address indexed attester,
    bytes32 uid,
    bytes32 indexed schema
);
```

**Parameters:**

* `recipient` (address indexed): Attestation recipient
* `attester` (address indexed): Who created the attestation
* `uid` (bytes32): Unique attestation identifier
* `schema` (bytes32 indexed): Schema used

**When Emitted:**

* When `attest()` is successfully called
* During batch attestation operations

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Listen for attestations
  contract.on('Attested', (recipient, attester, uid, schema, event) => {
    console.log('New Attestation:');
    console.log(`  Recipient: ${recipient}`);
    console.log(`  Attester: ${attester}`);
    console.log(`  UID: ${uid}`);
    console.log(`  Schema: ${schema}`);
    console.log(`  Block: ${event.blockNumber}`);
  });

  // Filter for specific recipient
  const recipientFilter = contract.filters.Attested('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb');
  contract.on(recipientFilter, (recipient, attester, uid, schema) => {
    console.log(`Alice received attestation: ${uid}`);
  });

  // Get attestation history
  async function getAttestationHistory(recipient) {
    const filter = contract.filters.Attested(recipient);
    const events = await contract.queryFilter(filter);
    
    return events.map(e => ({
      recipient: e.args.recipient,
      attester: e.args.attester,
      uid: e.args.uid,
      schema: e.args.schema,
      blockNumber: e.blockNumber,
      timestamp: e.args.timestamp
    }));
  }
  ```

  ```python Python theme={null}
  # Listen for attestations
  def handle_attested(event):
      recipient = event['args']['recipient']
      attester = event['args']['attester']
      uid = event['args']['uid']
      schema = event['args']['schema']
      
      print('New Attestation:')
      print(f"  Recipient: {recipient}")
      print(f"  Attester: {attester}")
      print(f"  UID: {uid.hex()}")
      print(f"  Schema: {schema.hex()}")
      print(f"  Block: {event['blockNumber']}")

  contract.events.Attested().on('data', handle_attested)

  # Filter for specific recipient
  recipient_filter = contract.events.Attested.createFilter(
      argument_filters={'recipient': '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb'}
  )

  # Get attestation history
  def get_attestation_history(recipient):
      filter = contract.events.Attested.createFilter(
          fromBlock=0,
          argument_filters={'recipient': recipient}
      )
      events = filter.get_all_entries()
      
      return [{
          'recipient': e['args']['recipient'],
          'attester': e['args']['attester'],
          'uid': e['args']['uid'].hex(),
          'schema': e['args']['schema'].hex(),
          'blockNumber': e['blockNumber']
      } for e in events]
  ```
</CodeGroup>

### Revoked

Emitted when an attestation is revoked.

```solidity theme={null}
event Revoked(
    address indexed recipient,
    address indexed attester,
    bytes32 uid,
    bytes32 indexed schema
);
```

**Parameters:**

* `recipient` (address indexed): Original attestation recipient
* `attester` (address indexed): Who revoked the attestation
* `uid` (bytes32): Attestation identifier
* `schema` (bytes32 indexed): Schema used

**When Emitted:**

* When `revoke()` is successfully called
* During batch revocation operations

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Monitor revocations
  contract.on('Revoked', (recipient, attester, uid, schema, event) => {
    console.log(`Attestation ${uid} revoked by ${attester}`);
  });

  // Track revocations for specific schema
  const schemaFilter = contract.filters.Revoked(null, null, null, schemaUID);
  contract.on(schemaFilter, (recipient, attester, uid, schema) => {
    console.log(`Schema ${schema} attestation revoked: ${uid}`);
  });
  ```

  ```python Python theme={null}
  def handle_revoked(event):
      recipient = event['args']['recipient']
      attester = event['args']['attester']
      uid = event['args']['uid']
      
      print(f"Attestation {uid.hex()} revoked by {attester}")

  contract.events.Revoked().on('data', handle_revoked)
  ```
</CodeGroup>

## Schema Events

### SchemaRegistered

Emitted when a new schema is registered.

```solidity theme={null}
event SchemaRegistered(
    bytes32 indexed uid,
    address indexed registerer
);
```

**Parameters:**

* `uid` (bytes32 indexed): Schema unique identifier
* `registerer` (address indexed): Who registered the schema

**When Emitted:**

* When `registerSchema()` is successfully called

**Example Usage:**

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Monitor schema registrations
  contract.on('SchemaRegistered', async (uid, registerer, event) => {
    console.log('New Schema Registered:');
    console.log(`  UID: ${uid}`);
    console.log(`  Registerer: ${registerer}`);
    
    // Get schema details
    const schema = await contract.getSchema(uid);
    console.log(`  Definition: ${schema.schema}`);
    console.log(`  Revocable: ${schema.revocable}`);
  });

  // Get all registered schemas
  async function getAllSchemas() {
    const filter = contract.filters.SchemaRegistered();
    const events = await contract.queryFilter(filter);
    
    const schemas = await Promise.all(
      events.map(async e => {
        const schema = await contract.getSchema(e.args.uid);
        return {
          uid: e.args.uid,
          registerer: e.args.registerer,
          definition: schema.schema,
          revocable: schema.revocable,
          blockNumber: e.blockNumber
        };
      })
    );
    
    return schemas;
  }
  ```

  ```python Python theme={null}
  def handle_schema_registered(event):
      uid = event['args']['uid']
      registerer = event['args']['registerer']
      
      print('New Schema Registered:')
      print(f"  UID: {uid.hex()}")
      print(f"  Registerer: {registerer}")
      
      # Get schema details
      schema = contract.functions.getSchema(uid).call()
      print(f"  Definition: {schema[2]}")
      print(f"  Revocable: {schema[1]}")

  contract.events.SchemaRegistered().on('data', handle_schema_registered)
  ```
</CodeGroup>

## Trust Module Events

### TrustModuleRegistered

Emitted when a trust evaluation module is registered.

```solidity theme={null}
event TrustModuleRegistered(
    address indexed module,
    string name
);
```

**Parameters:**

* `module` (address indexed): Module contract address
* `name` (string): Module name

**When Emitted:**

* When a new trust module is registered

### TrustScoreUpdated

Emitted when a user's trust score changes.

```solidity theme={null}
event TrustScoreUpdated(
    address indexed subject,
    uint256 oldScore,
    uint256 newScore
);
```

**Parameters:**

* `subject` (address indexed): User whose score changed
* `oldScore` (uint256): Previous trust score
* `newScore` (uint256): New trust score

**When Emitted:**

* When trust score is recalculated
* After attestation creation/revocation

## Event Monitoring

### Comprehensive Trust Monitor

<CodeGroup>
  ```javascript JavaScript theme={null}
  class TrustEventMonitor {
    constructor(contract) {
      this.contract = contract;
      this.attestations = new Map();
      this.schemas = new Map();
      this.trustScores = new Map();
      this.setupListeners();
    }
    
    setupListeners() {
      // Monitor attestations
      this.contract.on('Attested', (recipient, attester, uid, schema, event) => {
        this.handleAttested(recipient, attester, uid, schema, event);
      });
      
      // Monitor revocations
      this.contract.on('Revoked', (recipient, attester, uid, schema, event) => {
        this.handleRevoked(recipient, attester, uid, schema, event);
      });
      
      // Monitor schemas
      this.contract.on('SchemaRegistered', (uid, registerer, event) => {
        this.handleSchemaRegistered(uid, registerer, event);
      });
      
      // Monitor trust scores
      this.contract.on('TrustScoreUpdated', (subject, oldScore, newScore, event) => {
        this.handleTrustScoreUpdated(subject, oldScore, newScore, event);
      });
    }
    
    handleAttested(recipient, attester, uid, schema, event) {
      const attestation = {
        recipient,
        attester,
        uid,
        schema,
        blockNumber: event.blockNumber,
        timestamp: event.args.timestamp
      };
      
      // Store attestation
      this.attestations.set(uid, attestation);
      
      // Update recipient's attestation list
      if (!this.recipientAttestations.has(recipient)) {
        this.recipientAttestations.set(recipient, []);
      }
      this.recipientAttestations.get(recipient).push(uid);
      
      console.log(`✅ New attestation: ${uid.slice(0, 10)}... for ${recipient.slice(0, 10)}...`);
      
      // Trigger analytics update
      this.updateAnalytics(recipient);
    }
    
    handleRevoked(recipient, attester, uid, schema, event) {
      const attestation = this.attestations.get(uid);
      if (attestation) {
        attestation.revoked = true;
        attestation.revokedAt = event.blockNumber;
      }
      
      console.log(`❌ Attestation revoked: ${uid.slice(0, 10)}...`);
      
      // Update analytics
      this.updateAnalytics(recipient);
    }
    
    handleSchemaRegistered(uid, registerer, event) {
      this.schemas.set(uid, {
        uid,
        registerer,
        blockNumber: event.blockNumber
      });
      
      console.log(`📋 New schema registered: ${uid.slice(0, 10)}...`);
    }
    
    handleTrustScoreUpdated(subject, oldScore, newScore, event) {
      this.trustScores.set(subject, {
        score: newScore.toString(),
        previousScore: oldScore.toString(),
        updatedAt: event.blockNumber
      });
      
      const change = newScore.sub(oldScore);
      const direction = change.isNegative() ? '📉' : '📈';
      
      console.log(`${direction} Trust score updated for ${subject.slice(0, 10)}...`);
      console.log(`  Old: ${oldScore.toString()}, New: ${newScore.toString()}`);
    }
    
    updateAnalytics(address) {
      // Calculate analytics
      const attestations = this.recipientAttestations.get(address) || [];
      const activeAttestations = attestations.filter(uid => {
        const att = this.attestations.get(uid);
        return att && !att.revoked;
      });
      
      console.log(`📊 ${address.slice(0, 10)}... has ${activeAttestations.length} active attestations`);
    }
    
    getStats() {
      return {
        totalAttestations: this.attestations.size,
        totalSchemas: this.schemas.size,
        trackedUsers: this.trustScores.size
      };
    }
    
    getRecipientStats(address) {
      const attestations = this.recipientAttestations.get(address) || [];
      const active = attestations.filter(uid => {
        const att = this.attestations.get(uid);
        return att && !att.revoked;
      });
      
      return {
        total: attestations.length,
        active: active.length,
        revoked: attestations.length - active.length,
        trustScore: this.trustScores.get(address)?.score || '0'
      };
    }
  }

  // Usage
  const monitor = new TrustEventMonitor(contract);

  // Get overall stats
  console.log('Trust Registry Stats:', monitor.getStats());

  // Get stats for specific user
  const userStats = monitor.getRecipientStats('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb');
  console.log('User Stats:', userStats);
  ```

  ```python Python theme={null}
  class TrustEventMonitor:
      def __init__(self, contract):
          self.contract = contract
          self.attestations = {}
          self.schemas = {}
          self.trust_scores = {}
          self.recipient_attestations = {}
          self.setup_listeners()
      
      def setup_listeners(self):
          self.contract.events.Attested().on('data', self.handle_attested)
          self.contract.events.Revoked().on('data', self.handle_revoked)
          self.contract.events.SchemaRegistered().on('data', self.handle_schema_registered)
          self.contract.events.TrustScoreUpdated().on('data', self.handle_trust_score_updated)
      
      def handle_attested(self, event):
          recipient = event['args']['recipient']
          attester = event['args']['attester']
          uid = event['args']['uid'].hex()
          schema = event['args']['schema'].hex()
          
          attestation = {
              'recipient': recipient,
              'attester': attester,
              'uid': uid,
              'schema': schema,
              'blockNumber': event['blockNumber']
          }
          
          self.attestations[uid] = attestation
          
          if recipient not in self.recipient_attestations:
              self.recipient_attestations[recipient] = []
          self.recipient_attestations[recipient].append(uid)
          
          print(f"✅ New attestation: {uid[:10]}... for {recipient[:10]}...")
          self.update_analytics(recipient)
      
      def handle_revoked(self, event):
          uid = event['args']['uid'].hex()
          recipient = event['args']['recipient']
          
          if uid in self.attestations:
              self.attestations[uid]['revoked'] = True
              self.attestations[uid]['revokedAt'] = event['blockNumber']
          
          print(f"❌ Attestation revoked: {uid[:10]}...")
          self.update_analytics(recipient)
      
      def handle_schema_registered(self, event):
          uid = event['args']['uid'].hex()
          registerer = event['args']['registerer']
          
          self.schemas[uid] = {
              'uid': uid,
              'registerer': registerer,
              'blockNumber': event['blockNumber']
          }
          
          print(f"📋 New schema registered: {uid[:10]}...")
      
      def handle_trust_score_updated(self, event):
          subject = event['args']['subject']
          old_score = event['args']['oldScore']
          new_score = event['args']['newScore']
          
          self.trust_scores[subject] = {
              'score': new_score,
              'previousScore': old_score,
              'updatedAt': event['blockNumber']
          }
          
          direction = '📉' if new_score < old_score else '📈'
          print(f"{direction} Trust score updated for {subject[:10]}...")
          print(f"  Old: {old_score}, New: {new_score}")
      
      def update_analytics(self, address):
          attestations = self.recipient_attestations.get(address, [])
          active = [uid for uid in attestations 
                   if uid in self.attestations and not self.attestations[uid].get('revoked')]
          
          print(f"📊 {address[:10]}... has {len(active)} active attestations")
      
      def get_stats(self):
          return {
              'totalAttestations': len(self.attestations),
              'totalSchemas': len(self.schemas),
              'trackedUsers': len(self.trust_scores)
          }
      
      def get_recipient_stats(self, address):
          attestations = self.recipient_attestations.get(address, [])
          active = [uid for uid in attestations 
                   if uid in self.attestations and not self.attestations[uid].get('revoked')]
          
          return {
              'total': len(attestations),
              'active': len(active),
              'revoked': len(attestations) - len(active),
              'trustScore': self.trust_scores.get(address, {}).get('score', 0)
          }

  # Usage
  monitor = TrustEventMonitor(contract)

  # Get overall stats
  print('Trust Registry Stats:', monitor.get_stats())

  # Get stats for specific user
  user_stats = monitor.get_recipient_stats('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb')
  print('User Stats:', user_stats)
  ```
</CodeGroup>

## Event Analytics

### Trust Graph Analysis

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function analyzeTrustGraph() {
    const currentBlock = await provider.getBlockNumber();
    const startBlock = currentBlock - 100000;
    
    // Get all attestations
    const attestedFilter = contract.filters.Attested();
    const attestedEvents = await contract.queryFilter(attestedFilter, startBlock);
    
    // Get all revocations
    const revokedFilter = contract.filters.Revoked();
    const revokedEvents = await contract.queryFilter(revokedFilter, startBlock);
    
    const analytics = {
      totalAttestations: attestedEvents.length,
      totalRevocations: revokedEvents.length,
      uniqueAttesters: new Set(attestedEvents.map(e => e.args.attester)).size,
      uniqueRecipients: new Set(attestedEvents.map(e => e.args.recipient)).size,
      topAttesters: getTopAttesters(attestedEvents),
      mostAttestedUsers: getMostAttestedUsers(attestedEvents, revokedEvents),
      schemaDistribution: getSchemaDistribution(attestedEvents)
    };
    
    return analytics;
  }

  function getTopAttesters(events) {
    const counts = {};
    events.forEach(e => {
      counts[e.args.attester] = (counts[e.args.attester] || 0) + 1;
    });
    
    return Object.entries(counts)
      .sort(([,a], [,b]) => b - a)
      .slice(0, 10)
      .map(([attester, count]) => ({ attester, count }));
  }

  function getMostAttestedUsers(attestedEvents, revokedEvents) {
    const counts = {};
    
    attestedEvents.forEach(e => {
      counts[e.args.recipient] = (counts[e.args.recipient] || 0) + 1;
    });
    
    revokedEvents.forEach(e => {
      counts[e.args.recipient] = (counts[e.args.recipient] || 0) - 1;
    });
    
    return Object.entries(counts)
      .sort(([,a], [,b]) => b - a)
      .slice(0, 10)
      .map(([recipient, count]) => ({ recipient, activeAttestations: count }));
  }

  function getSchemaDistribution(events) {
    const counts = {};
    events.forEach(e => {
      counts[e.args.schema] = (counts[e.args.schema] || 0) + 1;
    });
    
    return Object.entries(counts)
      .map(([schema, count]) => ({ schema, count }))
      .sort((a, b) => b.count - a.count);
  }
  ```
</CodeGroup>

## Best Practices

### Event Handling

1. **Use Indexed Parameters**: Filter efficiently using indexed fields
2. **Store Event Data**: Cache important events off-chain
3. **Monitor Continuously**: Set up real-time listeners
4. **Handle Reorgs**: Account for blockchain reorganizations
5. **Rate Limiting**: Don't overwhelm with event processing

### Performance

1. **Limit Block Ranges**: Query smaller ranges to avoid timeouts
2. **Pagination**: Implement pagination for large datasets
3. **Batch Processing**: Process events in batches
4. **Caching**: Cache frequently accessed event data
5. **Indexing**: Use subgraphs or custom indexers

## Related Documentation

* [Contract Overview](/contracts/trust-registry/overview) - Contract architecture
* [Functions Reference](/contracts/trust-registry/functions) - Function documentation
* [Integration Guide](/contracts/trust-registry/integration) - Integration examples
* [Trust Modules](/contracts/trust-registry/modules) - Module development
