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

# Identity SBT Integration

> Complete integration guide for the Identity SBT contract

## Overview

This guide provides comprehensive examples for integrating with the ZKScore Identity SBT contract. It covers Web3 integration, error handling, best practices, and real-world use cases.

<Tip>
  Always test your integration on testnet before deploying to mainnet. Use the testnet contract addresses provided in the [Contract Overview](/contracts/identity-sbt/overview) section.
</Tip>

## Web3 Integration

### Basic Setup

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { ethers } from 'ethers';

  // Contract configuration
  const CONTRACT_ADDRESS = '0x1234567890123456789012345678901234567890';
  const CONTRACT_ABI = [
    // ... ABI definitions
  ];

  // Initialize provider and contract
  const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
  const contract = new ethers.Contract(CONTRACT_ADDRESS, CONTRACT_ABI, provider);

  // Initialize with signer for transactions
  const signer = provider.getSigner();
  const contractWithSigner = contract.connect(signer);
  ```

  ```python Python theme={null}
  from web3 import Web3

  # Contract configuration
  CONTRACT_ADDRESS = '0x1234567890123456789012345678901234567890'
  CONTRACT_ABI = [
      # ... ABI definitions
  ]

  # Initialize provider and contract
  w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY'))
  contract = w3.eth.contract(address=CONTRACT_ADDRESS, abi=CONTRACT_ABI)

  # Initialize with account for transactions
  account = w3.eth.account.from_key('YOUR_PRIVATE_KEY')
  ```
</CodeGroup>

### Contract Interaction Class

<CodeGroup>
  ```javascript JavaScript theme={null}
  class IdentitySBTIntegration {
    constructor(provider, contractAddress, abi) {
      this.provider = provider;
      this.contract = new ethers.Contract(contractAddress, abi, provider);
      this.contractWithSigner = null;
    }
    
    // Set signer for transactions
    setSigner(signer) {
      this.contractWithSigner = this.contract.connect(signer);
    }
    
    // Mint new identity
    async mintIdentity(to, name, metadataURI) {
      if (!this.contractWithSigner) {
        throw new Error('Signer not set');
      }
      
      try {
        const tx = await this.contractWithSigner.mint(to, name, metadataURI);
        const receipt = await tx.wait();
        
        // Get token ID from event
        const event = receipt.events.find(e => e.event === 'IdentityMinted');
        const tokenId = event.args.tokenId;
        
        return {
          success: true,
          tokenId: tokenId.toString(),
          transactionHash: receipt.transactionHash,
          blockNumber: receipt.blockNumber
        };
      } catch (error) {
        return {
          success: false,
          error: error.message
        };
      }
    }
    
    // Activate identity
    async activateIdentity(tokenId) {
      if (!this.contractWithSigner) {
        throw new Error('Signer not set');
      }
      
      try {
        const tx = await this.contractWithSigner.activate(tokenId);
        const receipt = await tx.wait();
        
        return {
          success: true,
          transactionHash: receipt.transactionHash,
          blockNumber: receipt.blockNumber
        };
      } catch (error) {
        return {
          success: false,
          error: error.message
        };
      }
    }
    
    // Get identity information
    async getIdentityInfo(tokenId) {
      try {
        const [owner, isActivated, tokenURI] = await Promise.all([
          this.contract.ownerOf(tokenId),
          this.contract.isActivated(tokenId),
          this.contract.tokenURI(tokenId)
        ]);
        
        return {
          tokenId: tokenId.toString(),
          owner,
          isActivated,
          tokenURI
        };
      } catch (error) {
        return {
          error: error.message
        };
      }
    }
    
    // Get user's identities
    async getUserIdentities(address) {
      try {
        const balance = await this.contract.balanceOf(address);
        const identities = [];
        
        for (let i = 0; i < balance.toNumber(); i++) {
          const tokenId = await this.contract.tokenOfOwnerByIndex(address, i);
          const info = await this.getIdentityInfo(tokenId);
          identities.push(info);
        }
        
        return identities;
      } catch (error) {
        return {
          error: error.message
        };
      }
    }
  }

  // Usage
  const integration = new IdentitySBTIntegration(
    provider,
    '0x1234567890123456789012345678901234567890',
    IDENTITY_SBT_ABI
  );

  integration.setSigner(signer);
  ```

  ```python Python theme={null}
  class IdentitySBTIntegration:
      def __init__(self, w3, contract_address, abi):
          self.w3 = w3
          self.contract = w3.eth.contract(address=contract_address, abi=abi)
          self.account = None
      
      # Set account for transactions
      def set_account(self, private_key):
          self.account = self.w3.eth.account.from_key(private_key)
      
      # Mint new identity
      def mint_identity(self, to, name, metadata_uri):
          if not self.account:
              raise ValueError('Account not set')
          
          try:
              tx = self.contract.functions.mint(to, name, metadata_uri).buildTransaction({
                  'from': self.account.address,
                  'gas': 200000,
                  'gasPrice': self.w3.eth.gas_price,
                  'nonce': self.w3.eth.get_transaction_count(self.account.address)
              })
              
              signed_tx = self.w3.eth.account.sign_transaction(tx, self.account.key)
              tx_hash = self.w3.eth.send_raw_transaction(signed_tx.rawTransaction)
              
              receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
              
              # Get token ID from event
              event = self.contract.events.IdentityMinted().processReceipt(receipt)[0]
              token_id = event['args']['tokenId']
              
              return {
                  'success': True,
                  'tokenId': str(token_id),
                  'transactionHash': receipt.transactionHash.hex(),
                  'blockNumber': receipt.blockNumber
              }
          except Exception as error:
              return {
                  'success': False,
                  'error': str(error)
              }
      
      # Activate identity
      def activate_identity(self, token_id):
          if not self.account:
              raise ValueError('Account not set')
          
          try:
              tx = self.contract.functions.activate(token_id).buildTransaction({
                  'from': self.account.address,
                  'gas': 100000,
                  'gasPrice': self.w3.eth.gas_price,
                  'nonce': self.w3.eth.get_transaction_count(self.account.address)
              })
              
              signed_tx = self.w3.eth.account.sign_transaction(tx, self.account.key)
              tx_hash = self.w3.eth.send_raw_transaction(signed_tx.rawTransaction)
              
              receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
              
              return {
                  'success': True,
                  'transactionHash': receipt.transactionHash.hex(),
                  'blockNumber': receipt.blockNumber
              }
          except Exception as error:
              return {
                  'success': False,
                  'error': str(error)
              }
      
      # Get identity information
      def get_identity_info(self, token_id):
          try:
              owner = self.contract.functions.ownerOf(token_id).call()
              is_activated = self.contract.functions.isActivated(token_id).call()
              token_uri = self.contract.functions.tokenURI(token_id).call()
              
              return {
                  'tokenId': str(token_id),
                  'owner': owner,
                  'isActivated': is_activated,
                  'tokenURI': token_uri
              }
          except Exception as error:
              return {
                  'error': str(error)
              }
      
      # Get user's identities
      def get_user_identities(self, address):
          try:
              balance = self.contract.functions.balanceOf(address).call()
              identities = []
              
              for i in range(balance):
                  token_id = self.contract.functions.tokenOfOwnerByIndex(address, i).call()
                  info = self.get_identity_info(token_id)
                  identities.append(info)
              
              return identities
          except Exception as error:
              return {
                  'error': str(error)
              }

  # Usage
  integration = IdentitySBTIntegration(
      w3,
      '0x1234567890123456789012345678901234567890',
      IDENTITY_SBT_ABI
  )

  integration.set_account('YOUR_PRIVATE_KEY')
  ```
</CodeGroup>

## Error Handling

### Comprehensive Error Handling

<CodeGroup>
  ```javascript JavaScript theme={null}
  class IdentitySBTErrorHandler {
    static handleError(error) {
      const errorMessage = error.message || error.toString();
      
      // Common error patterns
      if (errorMessage.includes('AccessControl')) {
        return {
          type: 'PERMISSION_ERROR',
          message: 'Insufficient permissions to perform this action',
          code: 'ACCESS_DENIED'
        };
      }
      
      if (errorMessage.includes('Token is soulbound')) {
        return {
          type: 'SOULBOUND_ERROR',
          message: 'Token is soulbound and cannot be transferred',
          code: 'TOKEN_SOULBOUND'
        };
      }
      
      if (errorMessage.includes('Token does not exist')) {
        return {
          type: 'NOT_FOUND_ERROR',
          message: 'Token does not exist',
          code: 'TOKEN_NOT_FOUND'
        };
      }
      
      if (errorMessage.includes('Already activated')) {
        return {
          type: 'ALREADY_ACTIVATED_ERROR',
          message: 'Token is already activated',
          code: 'ALREADY_ACTIVATED'
        };
      }
      
      if (errorMessage.includes('Not token owner')) {
        return {
          type: 'OWNERSHIP_ERROR',
          message: 'Caller is not the owner of the token',
          code: 'NOT_OWNER'
        };
      }
      
      if (errorMessage.includes('name already exists')) {
        return {
          type: 'DUPLICATE_ERROR',
          message: 'Name is already taken',
          code: 'NAME_EXISTS'
        };
      }
      
      if (errorMessage.includes('insufficient funds')) {
        return {
          type: 'INSUFFICIENT_FUNDS_ERROR',
          message: 'Insufficient funds for transaction',
          code: 'INSUFFICIENT_FUNDS'
        };
      }
      
      if (errorMessage.includes('gas limit exceeded')) {
        return {
          type: 'GAS_ERROR',
          message: 'Transaction gas limit exceeded',
          code: 'GAS_LIMIT_EXCEEDED'
        };
      }
      
      // Default error
      return {
        type: 'UNKNOWN_ERROR',
        message: errorMessage,
        code: 'UNKNOWN'
      };
    }
    
    static async safeExecute(operation, retries = 3) {
      for (let attempt = 1; attempt <= retries; attempt++) {
        try {
          return await operation();
        } catch (error) {
          const errorInfo = this.handleError(error);
          
          if (attempt === retries) {
            throw errorInfo;
          }
          
          // Wait before retry
          await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
        }
      }
    }
  }

  // Usage
  try {
    const result = await IdentitySBTErrorHandler.safeExecute(async () => {
      return await contract.mint(to, name, metadataURI);
    });
    console.log('Success:', result);
  } catch (error) {
    console.error('Error:', error.message);
    console.error('Code:', error.code);
  }
  ```

  ```python Python theme={null}
  class IdentitySBTErrorHandler:
      @staticmethod
      def handle_error(error):
          error_message = str(error)
          
          # Common error patterns
          if 'AccessControl' in error_message:
              return {
                  'type': 'PERMISSION_ERROR',
                  'message': 'Insufficient permissions to perform this action',
                  'code': 'ACCESS_DENIED'
              }
          
          if 'Token is soulbound' in error_message:
              return {
                  'type': 'SOULBOUND_ERROR',
                  'message': 'Token is soulbound and cannot be transferred',
                  'code': 'TOKEN_SOULBOUND'
              }
          
          if 'Token does not exist' in error_message:
              return {
                  'type': 'NOT_FOUND_ERROR',
                  'message': 'Token does not exist',
                  'code': 'TOKEN_NOT_FOUND'
              }
          
          if 'Already activated' in error_message:
              return {
                  'type': 'ALREADY_ACTIVATED_ERROR',
                  'message': 'Token is already activated',
                  'code': 'ALREADY_ACTIVATED'
              }
          
          if 'Not token owner' in error_message:
              return {
                  'type': 'OWNERSHIP_ERROR',
                  'message': 'Caller is not the owner of the token',
                  'code': 'NOT_OWNER'
              }
          
          if 'name already exists' in error_message:
              return {
                  'type': 'DUPLICATE_ERROR',
                  'message': 'Name is already taken',
                  'code': 'NAME_EXISTS'
              }
          
          if 'insufficient funds' in error_message:
              return {
                  'type': 'INSUFFICIENT_FUNDS_ERROR',
                  'message': 'Insufficient funds for transaction',
                  'code': 'INSUFFICIENT_FUNDS'
              }
          
          if 'gas limit exceeded' in error_message:
              return {
                  'type': 'GAS_ERROR',
                  'message': 'Transaction gas limit exceeded',
                  'code': 'GAS_LIMIT_EXCEEDED'
              }
          
          # Default error
          return {
              'type': 'UNKNOWN_ERROR',
              'message': error_message,
              'code': 'UNKNOWN'
          }
      
      @staticmethod
      async def safe_execute(operation, retries=3):
          for attempt in range(1, retries + 1):
              try:
                  return await operation()
              except Exception as error:
                  error_info = IdentitySBTErrorHandler.handle_error(error)
                  
                  if attempt == retries:
                      raise error_info
                  
                  # Wait before retry
                  await asyncio.sleep(1 * attempt)

  # Usage
  try:
      result = await IdentitySBTErrorHandler.safe_execute(
          lambda: contract.functions.mint(to, name, metadata_uri).transact()
      )
      print('Success:', result)
  except Exception as error:
      print('Error:', error['message'])
      print('Code:', error['code'])
  ```
</CodeGroup>

## Event Integration

### Event Listener Setup

<CodeGroup>
  ```javascript JavaScript theme={null}
  class IdentityEventManager {
    constructor(contract) {
      this.contract = contract;
      this.listeners = new Map();
      this.isListening = false;
    }
    
    startListening() {
      if (this.isListening) return;
      
      this.contract.on('IdentityMinted', (to, tokenId, name, event) => {
        this.handleEvent('IdentityMinted', {
          to,
          tokenId: tokenId.toString(),
          name,
          blockNumber: event.blockNumber,
          transactionHash: event.transactionHash
        });
      });
      
      this.contract.on('IdentityActivated', (tokenId, owner, event) => {
        this.handleEvent('IdentityActivated', {
          tokenId: tokenId.toString(),
          owner,
          blockNumber: event.blockNumber,
          transactionHash: event.transactionHash
        });
      });
      
      this.contract.on('Transfer', (from, to, tokenId, event) => {
        this.handleEvent('Transfer', {
          from,
          to,
          tokenId: tokenId.toString(),
          blockNumber: event.blockNumber,
          transactionHash: event.transactionHash
        });
      });
      
      this.isListening = true;
    }
    
    stopListening() {
      this.contract.removeAllListeners();
      this.isListening = false;
    }
    
    handleEvent(eventType, data) {
      console.log(`Event: ${eventType}`, data);
      
      if (this.listeners.has(eventType)) {
        this.listeners.get(eventType).forEach(callback => {
          try {
            callback(data);
          } catch (error) {
            console.error(`Error in event listener for ${eventType}:`, error);
          }
        });
      }
    }
    
    on(eventType, callback) {
      if (!this.listeners.has(eventType)) {
        this.listeners.set(eventType, []);
      }
      this.listeners.get(eventType).push(callback);
    }
    
    off(eventType, callback) {
      if (this.listeners.has(eventType)) {
        const callbacks = this.listeners.get(eventType);
        const index = callbacks.indexOf(callback);
        if (index > -1) {
          callbacks.splice(index, 1);
        }
      }
    }
  }

  // Usage
  const eventManager = new IdentityEventManager(contract);
  eventManager.startListening();

  eventManager.on('IdentityMinted', (data) => {
    console.log('New identity minted:', data);
    // Update UI, send notifications, etc.
  });

  eventManager.on('IdentityActivated', (data) => {
    console.log('Identity activated:', data);
    // Update UI, send notifications, etc.
  });
  ```

  ```python Python theme={null}
  class IdentityEventManager:
      def __init__(self, contract):
          self.contract = contract
          self.listeners = {}
          self.is_listening = False
      
      def start_listening(self):
          if self.is_listening:
              return
          
          self.contract.events.IdentityMinted().on('data', self.handle_identity_minted)
          self.contract.events.IdentityActivated().on('data', self.handle_identity_activated)
          self.contract.events.Transfer().on('data', self.handle_transfer)
          
          self.is_listening = True
      
      def stop_listening(self):
          self.contract.events.IdentityMinted().uninstall_filter()
          self.contract.events.IdentityActivated().uninstall_filter()
          self.contract.events.Transfer().uninstall_filter()
          self.is_listening = False
      
      def handle_identity_minted(self, event):
          data = {
              'to': event['args']['to'],
              'tokenId': str(event['args']['tokenId']),
              'name': event['args']['name'],
              'blockNumber': event['blockNumber'],
              'transactionHash': event['transactionHash'].hex()
          }
          self.handle_event('IdentityMinted', data)
      
      def handle_identity_activated(self, event):
          data = {
              'tokenId': str(event['args']['tokenId']),
              'owner': event['args']['owner'],
              'blockNumber': event['blockNumber'],
              'transactionHash': event['transactionHash'].hex()
          }
          self.handle_event('IdentityActivated', data)
      
      def handle_transfer(self, event):
          data = {
              'from': event['args']['from'],
              'to': event['args']['to'],
              'tokenId': str(event['args']['tokenId']),
              'blockNumber': event['blockNumber'],
              'transactionHash': event['transactionHash'].hex()
          }
          self.handle_event('Transfer', data)
      
      def handle_event(self, event_type, data):
          print(f"Event: {event_type}", data)
          
          if event_type in self.listeners:
              for callback in self.listeners[event_type]:
                  try:
                      callback(data)
                  except Exception as error:
                      print(f"Error in event listener for {event_type}: {error}")
      
      def on(self, event_type, callback):
          if event_type not in self.listeners:
              self.listeners[event_type] = []
          self.listeners[event_type].append(callback)
      
      def off(self, event_type, callback):
          if event_type in self.listeners:
              if callback in self.listeners[event_type]:
                  self.listeners[event_type].remove(callback)

  # Usage
  event_manager = IdentityEventManager(contract)
  event_manager.start_listening()

  def on_identity_minted(data):
      print('New identity minted:', data)
      # Update UI, send notifications, etc.

  def on_identity_activated(data):
      print('Identity activated:', data)
      # Update UI, send notifications, etc.

  event_manager.on('IdentityMinted', on_identity_minted)
  event_manager.on('IdentityActivated', on_identity_activated)
  ```
</CodeGroup>

## Real-world Integration Examples

### Complete Identity Management System

<CodeGroup>
  ```javascript JavaScript theme={null}
  class IdentityManagementSystem {
    constructor(provider, contractAddress, abi) {
      this.provider = provider;
      this.contract = new ethers.Contract(contractAddress, abi, provider);
      this.contractWithSigner = null;
      this.eventManager = new IdentityEventManager(this.contract);
    }
    
    setSigner(signer) {
      this.contractWithSigner = this.contract.connect(signer);
    }
    
    // Complete identity creation flow
    async createIdentity(name, metadataURI, autoActivate = false) {
      try {
        // Step 1: Mint identity
        const mintResult = await this.mintIdentity(name, metadataURI);
        if (!mintResult.success) {
          return mintResult;
        }
        
        const tokenId = mintResult.tokenId;
        
        // Step 2: Auto-activate if requested
        if (autoActivate) {
          const activateResult = await this.activateIdentity(tokenId);
          if (!activateResult.success) {
            return {
              success: false,
              error: `Identity minted but activation failed: ${activateResult.error}`,
              tokenId
            };
          }
        }
        
        return {
          success: true,
          tokenId,
          isActivated: autoActivate,
          transactionHash: mintResult.transactionHash
        };
      } catch (error) {
        return {
          success: false,
          error: error.message
        };
      }
    }
    
    // Get comprehensive identity data
    async getIdentityData(tokenId) {
      try {
        const [owner, isActivated, tokenURI, balance] = await Promise.all([
          this.contract.ownerOf(tokenId),
          this.contract.isActivated(tokenId),
          this.contract.tokenURI(tokenId),
          this.contract.balanceOf(await this.contract.ownerOf(tokenId))
        ]);
        
        return {
          tokenId: tokenId.toString(),
          owner,
          isActivated,
          tokenURI,
          ownerBalance: balance.toString(),
          isSoulbound: isActivated
        };
      } catch (error) {
        return {
          error: error.message
        };
      }
    }
    
    // Batch operations
    async batchMintIdentities(identities) {
      const results = [];
      
      for (const identity of identities) {
        try {
          const result = await this.mintIdentity(identity.name, identity.metadataURI);
          results.push({
            name: identity.name,
            success: result.success,
            tokenId: result.tokenId,
            error: result.error
          });
        } catch (error) {
          results.push({
            name: identity.name,
            success: false,
            error: error.message
          });
        }
      }
      
      return results;
    }
    
    // Start event monitoring
    startEventMonitoring() {
      this.eventManager.startListening();
    }
    
    // Stop event monitoring
    stopEventMonitoring() {
      this.eventManager.stopListening();
    }
  }

  // Usage
  const identitySystem = new IdentityManagementSystem(
    provider,
    '0x1234567890123456789012345678901234567890',
    IDENTITY_SBT_ABI
  );

  identitySystem.setSigner(signer);
  identitySystem.startEventMonitoring();

  // Create identity
  const result = await identitySystem.createIdentity(
    'alice.zks',
    'https://api.onzks.com/metadata/alice.zks',
    true // Auto-activate
  );

  if (result.success) {
    console.log('Identity created:', result.tokenId);
  } else {
    console.error('Failed to create identity:', result.error);
  }
  ```

  ```python Python theme={null}
  class IdentityManagementSystem:
      def __init__(self, w3, contract_address, abi):
          self.w3 = w3
          self.contract = w3.eth.contract(address=contract_address, abi=abi)
          self.account = None
          self.event_manager = IdentityEventManager(self.contract)
      
      def set_account(self, private_key):
          self.account = self.w3.eth.account.from_key(private_key)
      
      # Complete identity creation flow
      def create_identity(self, name, metadata_uri, auto_activate=False):
          try:
              # Step 1: Mint identity
              mint_result = self.mint_identity(name, metadata_uri)
              if not mint_result['success']:
                  return mint_result
              
              token_id = mint_result['tokenId']
              
              # Step 2: Auto-activate if requested
              if auto_activate:
                  activate_result = self.activate_identity(token_id)
                  if not activate_result['success']:
                      return {
                          'success': False,
                          'error': f"Identity minted but activation failed: {activate_result['error']}",
                          'tokenId': token_id
                      }
              
              return {
                  'success': True,
                  'tokenId': token_id,
                  'isActivated': auto_activate,
                  'transactionHash': mint_result['transactionHash']
              }
          except Exception as error:
              return {
                  'success': False,
                  'error': str(error)
              }
      
      # Get comprehensive identity data
      def get_identity_data(self, token_id):
          try:
              owner = self.contract.functions.ownerOf(token_id).call()
              is_activated = self.contract.functions.isActivated(token_id).call()
              token_uri = self.contract.functions.tokenURI(token_id).call()
              balance = self.contract.functions.balanceOf(owner).call()
              
              return {
                  'tokenId': str(token_id),
                  'owner': owner,
                  'isActivated': is_activated,
                  'tokenURI': token_uri,
                  'ownerBalance': str(balance),
                  'isSoulbound': is_activated
              }
          except Exception as error:
              return {
                  'error': str(error)
              }
      
      # Batch operations
      def batch_mint_identities(self, identities):
          results = []
          
          for identity in identities:
              try:
                  result = self.mint_identity(identity['name'], identity['metadataURI'])
                  results.append({
                      'name': identity['name'],
                      'success': result['success'],
                      'tokenId': result['tokenId'],
                      'error': result['error']
                  })
              except Exception as error:
                  results.append({
                      'name': identity['name'],
                      'success': False,
                      'error': str(error)
                  })
          
          return results
      
      # Start event monitoring
      def start_event_monitoring(self):
          self.event_manager.start_listening()
      
      # Stop event monitoring
      def stop_event_monitoring(self):
          self.event_manager.stop_listening()

  # Usage
  identity_system = IdentityManagementSystem(
      w3,
      '0x1234567890123456789012345678901234567890',
      IDENTITY_SBT_ABI
  )

  identity_system.set_account('YOUR_PRIVATE_KEY')
  identity_system.start_event_monitoring()

  # Create identity
  result = identity_system.create_identity(
      'alice.zks',
      'https://api.onzks.com/metadata/alice.zks',
      True  # Auto-activate
  )

  if result['success']:
      print('Identity created:', result['tokenId'])
  else:
      print('Failed to create identity:', result['error'])
  ```
</CodeGroup>

## Best Practices

### Security Considerations

1. **Private Key Management**: Never hardcode private keys in your application
2. **Input Validation**: Always validate inputs before sending transactions
3. **Gas Estimation**: Estimate gas before sending transactions
4. **Error Handling**: Implement comprehensive error handling
5. **Event Monitoring**: Monitor events for state changes

### Performance Optimization

1. **Batch Operations**: Group multiple operations when possible
2. **Caching**: Cache frequently accessed data
3. **Event Filtering**: Use event filters to reduce data processing
4. **Gas Optimization**: Use appropriate gas limits
5. **Connection Pooling**: Reuse connections when possible

### Testing

1. **Unit Tests**: Test individual functions
2. **Integration Tests**: Test complete workflows
3. **Error Testing**: Test error conditions
4. **Performance Testing**: Test under load
5. **Security Testing**: Test for vulnerabilities

## Related Documentation

* [Contract Overview](/contracts/identity-sbt/overview) - Contract architecture and features
* [Functions Reference](/contracts/identity-sbt/functions) - Complete function documentation
* [Events Reference](/contracts/identity-sbt/events) - Event documentation
* [Security Guide](/contracts/identity-sbt/security) - Security considerations
* [Deployment Guide](/contracts/identity-sbt/deployment) - Deployment instructions
