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

> Complete guide to managing ZKS identities with the JavaScript SDK

## Overview

The ZKScore JavaScript SDK provides comprehensive identity management capabilities, including minting, activating, and resolving ZKS identities. The SDK handles both ZKS IDs (like `alice.zks`) and wallet addresses seamlessly.

<Tip>
  All identity operations support both ZKS IDs and wallet addresses. The SDK automatically resolves ZKS IDs to their corresponding wallet addresses when needed.
</Tip>

## Identity Operations

### 1. Check Name Availability

```javascript theme={null}
// Check if a ZKS ID is available
async function checkAvailability() {
  try {
    const result = await sdk.identity.checkAvailability('alice.zks');
    
    if (result.available) {
      console.log('✅ Name is available');
    } else {
      console.log('❌ Name is taken');
      console.log('Suggestions:', result.suggestions);
    }
    
    return result;
  } catch (error) {
    console.error('Error checking availability:', error.message);
    throw error;
  }
}

// Usage
const availability = await checkAvailability();
```

### 2. Mint New Identity

```javascript theme={null}
// Mint a new ZKS identity
async function mintIdentity() {
  try {
    const identity = await sdk.identity.mint({
      name: 'alice.zks',
      walletAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
      metadata: {
        bio: 'Web3 developer and DeFi enthusiast',
        avatar: 'https://example.com/avatar.png',
        social: {
          twitter: '@alice',
          github: 'alice-dev'
        }
      }
    });
    
    console.log('✅ Identity minted successfully');
    console.log('Token ID:', identity.tokenId);
    console.log('Name:', identity.name);
    console.log('Owner:', identity.ownerAddress);
    
    return identity;
  } catch (error) {
    if (error.code === 'NAME_TAKEN') {
      console.error('❌ Name is already taken');
    } else if (error.code === 'INVALID_NAME') {
      console.error('❌ Invalid name format');
    } else {
      console.error('❌ Error minting identity:', error.message);
    }
    throw error;
  }
}

// Usage
const newIdentity = await mintIdentity();
```

### 3. Activate Identity

```javascript theme={null}
// Activate an identity (make it soulbound)
async function activateIdentity(tokenId, signature) {
  try {
    const result = await sdk.identity.activate(tokenId, {
      signature: signature,
      metadata: {
        activationReason: 'Making identity soulbound',
        timestamp: new Date().toISOString()
      }
    });
    
    console.log('✅ Identity activated successfully');
    console.log('Activated at:', result.activatedAt);
    console.log('Is soulbound:', result.isSoulbound);
    
    return result;
  } catch (error) {
    if (error.code === 'ALREADY_ACTIVATED') {
      console.error('❌ Identity is already activated');
    } else if (error.code === 'INVALID_SIGNATURE') {
      console.error('❌ Invalid signature');
    } else {
      console.error('❌ Error activating identity:', error.message);
    }
    throw error;
  }
}

// Usage with wallet signature
const signature = await wallet.signMessage('Activate identity: alice.zks');
const activation = await activateIdentity(newIdentity.tokenId, signature);
```

### 4. Get Identity Information

```javascript theme={null}
// Get identity by ZKS ID or wallet address
async function getIdentity(identity) {
  try {
    const identityData = await sdk.identity.getIdentity(identity);
    
    console.log('Identity found:');
    console.log('- Name:', identityData.name);
    console.log('- Address:', identityData.address);
    console.log('- Token ID:', identityData.tokenId);
    console.log('- Is activated:', identityData.isActivated);
    console.log('- Created at:', identityData.createdAt);
    console.log('- Metadata:', identityData.metadata);
    
    return identityData;
  } catch (error) {
    if (error.code === 'IDENTITY_NOT_FOUND') {
      console.error('❌ Identity not found');
    } else {
      console.error('❌ Error fetching identity:', error.message);
    }
    throw error;
  }
}

// Usage with ZKS ID
const identityByZksId = await getIdentity('alice.zks');

// Usage with wallet address
const identityByAddress = await getIdentity('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb');
```

### 5. Resolve Identity

```javascript theme={null}
// Resolve ZKS ID to wallet address or vice versa
async function resolveIdentity(input) {
  try {
    const resolved = await sdk.identity.resolve(input);
    
    console.log('Resolved identity:');
    console.log('- Input:', input);
    console.log('- ZKS ID:', resolved.zksId);
    console.log('- Address:', resolved.address);
    console.log('- Is primary:', resolved.isPrimary);
    
    return resolved;
  } catch (error) {
    console.error('❌ Error resolving identity:', error.message);
    throw error;
  }
}

// Usage
const resolved = await resolveIdentity('alice.zks');
// Output: { zksId: 'alice.zks', address: '0x742d35Cc...', isPrimary: true }
```

## Advanced Identity Operations

### 1. Batch Identity Operations

```javascript theme={null}
// Check multiple names at once
async function checkMultipleNames(names) {
  try {
    const results = await Promise.all(
      names.map(name => sdk.identity.checkAvailability(name))
    );
    
    const available = results
      .filter(result => result.available)
      .map(result => result.name);
    
    const taken = results
      .filter(result => !result.available)
      .map(result => result.name);
    
    console.log('Available names:', available);
    console.log('Taken names:', taken);
    
    return { available, taken };
  } catch (error) {
    console.error('❌ Error checking multiple names:', error.message);
    throw error;
  }
}

// Usage
const names = ['alice.zks', 'bob.zks', 'charlie.zks'];
const batchResults = await checkMultipleNames(names);
```

### 2. Identity Search

```javascript theme={null}
// Search for identities by criteria
async function searchIdentities(criteria) {
  try {
    const results = await sdk.identity.search({
      query: criteria.query,
      limit: criteria.limit || 10,
      offset: criteria.offset || 0,
      filters: {
        isActivated: criteria.isActivated,
        createdAfter: criteria.createdAfter,
        createdBefore: criteria.createdBefore
      }
    });
    
    console.log(`Found ${results.total} identities`);
    console.log('Results:', results.identities);
    
    return results;
  } catch (error) {
    console.error('❌ Error searching identities:', error.message);
    throw error;
  }
}

// Usage
const searchResults = await searchIdentities({
  query: 'alice',
  limit: 5,
  isActivated: true
});
```

### 3. Identity Metadata Management

```javascript theme={null}
// Update identity metadata
async function updateMetadata(identity, metadata) {
  try {
    const result = await sdk.identity.updateMetadata(identity, {
      metadata: metadata,
      signature: await wallet.signMessage('Update metadata')
    });
    
    console.log('✅ Metadata updated successfully');
    console.log('New metadata:', result.metadata);
    
    return result;
  } catch (error) {
    console.error('❌ Error updating metadata:', error.message);
    throw error;
  }
}

// Usage
const updatedIdentity = await updateMetadata('alice.zks', {
  bio: 'Updated bio',
  avatar: 'https://new-avatar.com/image.png',
  social: {
    twitter: '@new_alice',
    github: 'new-alice-dev'
  }
});
```

## Identity Validation

### 1. Name Validation

```javascript theme={null}
// Validate ZKS ID format
function validateZksId(name) {
  const zksIdRegex = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?\.zks$/;
  
  if (!zksIdRegex.test(name)) {
    throw new Error('Invalid ZKS ID format. Must be lowercase letters, numbers, and hyphens, ending with .zks');
  }
  
  if (name.length < 3 || name.length > 63) {
    throw new Error('ZKS ID must be between 3 and 63 characters');
  }
  
  return true;
}

// Usage
try {
  validateZksId('alice.zks'); // ✅ Valid
  validateZksId('alice-123.zks'); // ✅ Valid
  validateZksId('Alice.zks'); // ❌ Invalid (uppercase)
  validateZksId('alice'); // ❌ Invalid (no .zks)
} catch (error) {
  console.error('Validation error:', error.message);
}
```

### 2. Address Validation

```javascript theme={null}
// Validate Ethereum address
function validateAddress(address) {
  const addressRegex = /^0x[a-fA-F0-9]{40}$/;
  
  if (!addressRegex.test(address)) {
    throw new Error('Invalid Ethereum address format');
  }
  
  return true;
}

// Usage
try {
  validateAddress('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb'); // ✅ Valid
  validateAddress('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb'); // ✅ Valid
  validateAddress('742d35Cc6634C0532925a3b844Bc9e7595f0bEb'); // ❌ Invalid (no 0x)
} catch (error) {
  console.error('Validation error:', error.message);
}
```

## Error Handling

### 1. Common Error Codes

```javascript theme={null}
// Handle identity-specific errors
function handleIdentityError(error) {
  switch (error.code) {
    case 'IDENTITY_NOT_FOUND':
      return 'Identity not found. Please check the ZKS ID or wallet address.';
    
    case 'NAME_TAKEN':
      return 'This name is already taken. Please try a different name.';
    
    case 'INVALID_NAME':
      return 'Invalid name format. Names must be 3-63 characters, lowercase letters, numbers, and hyphens only.';
    
    case 'ALREADY_ACTIVATED':
      return 'This identity is already activated.';
    
    case 'INVALID_SIGNATURE':
      return 'Invalid signature. Please ensure you are signing with the correct wallet.';
    
    case 'INSUFFICIENT_FUNDS':
      return 'Insufficient funds to complete the transaction.';
    
    case 'NETWORK_ERROR':
      return 'Network error. Please check your connection and try again.';
    
    default:
      return `Unexpected error: ${error.message}`;
  }
}

// Usage
try {
  const identity = await sdk.identity.getIdentity('alice.zks');
} catch (error) {
  const message = handleIdentityError(error);
  console.error(message);
}
```

### 2. Retry Logic

```javascript theme={null}
// Retry identity operations with exponential backoff
async function retryIdentityOperation(operation, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await operation();
    } catch (error) {
      if (attempt === maxRetries) {
        throw error;
      }
      
      if (error.code === 'NETWORK_ERROR' || error.code === 'TIMEOUT') {
        const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
        console.log(`Retrying in ${delay}ms... (attempt ${attempt}/${maxRetries})`);
        await new Promise(resolve => setTimeout(resolve, delay));
      } else {
        throw error; // Don't retry for non-retryable errors
      }
    }
  }
}

// Usage
const identity = await retryIdentityOperation(
  () => sdk.identity.getIdentity('alice.zks')
);
```

## Real-time Updates

### 1. Subscribe to Identity Changes

```javascript theme={null}
// Subscribe to identity updates
async function subscribeToIdentityUpdates(identity) {
  try {
    const unsubscribe = sdk.identity.subscribeToUpdates(identity, (update) => {
      console.log('Identity updated:', update);
      
      switch (update.type) {
        case 'metadata_updated':
          console.log('Metadata changed:', update.metadata);
          break;
        case 'activated':
          console.log('Identity activated');
          break;
        case 'deactivated':
          console.log('Identity deactivated');
          break;
      }
    });
    
    console.log('✅ Subscribed to identity updates');
    return unsubscribe;
  } catch (error) {
    console.error('❌ Error subscribing to updates:', error.message);
    throw error;
  }
}

// Usage
const unsubscribe = await subscribeToIdentityUpdates('alice.zks');

// Clean up subscription
setTimeout(() => {
  unsubscribe();
  console.log('Unsubscribed from updates');
}, 300000); // 5 minutes
```

### 2. Identity Events

```javascript theme={null}
// Listen to specific identity events
class IdentityEventListener {
  constructor(sdk) {
    this.sdk = sdk;
    this.listeners = new Map();
  }
  
  on(event, callback) {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, []);
    }
    this.listeners.get(event).push(callback);
  }
  
  emit(event, data) {
    const callbacks = this.listeners.get(event) || [];
    callbacks.forEach(callback => callback(data));
  }
  
  async startListening(identity) {
    const unsubscribe = await this.sdk.identity.subscribeToUpdates(identity, (update) => {
      this.emit(update.type, update);
    });
    
    return unsubscribe;
  }
}

// Usage
const eventListener = new IdentityEventListener(sdk);

eventListener.on('metadata_updated', (data) => {
  console.log('Metadata updated:', data);
});

eventListener.on('activated', (data) => {
  console.log('Identity activated:', data);
});

const unsubscribe = await eventListener.startListening('alice.zks');
```

## Best Practices

### 1. Identity Caching

```javascript theme={null}
// Cache identity data to reduce API calls
class IdentityCache {
  constructor(ttl = 300000) { // 5 minutes
    this.cache = new Map();
    this.ttl = ttl;
  }
  
  async get(identity) {
    const key = identity.toLowerCase();
    const cached = this.cache.get(key);
    
    if (cached && Date.now() - cached.timestamp < this.ttl) {
      return cached.data;
    }
    
    const data = await sdk.identity.getIdentity(identity);
    this.cache.set(key, {
      data,
      timestamp: Date.now()
    });
    
    return data;
  }
  
  clear() {
    this.cache.clear();
  }
}

// Usage
const identityCache = new IdentityCache();
const identity = await identityCache.get('alice.zks');
```

### 2. Batch Operations

```javascript theme={null}
// Batch multiple identity operations
async function batchIdentityOperations(operations) {
  const results = [];
  const errors = [];
  
  for (const operation of operations) {
    try {
      const result = await operation();
      results.push(result);
    } catch (error) {
      errors.push({ operation, error });
    }
  }
  
  return { results, errors };
}

// Usage
const operations = [
  () => sdk.identity.getIdentity('alice.zks'),
  () => sdk.identity.getIdentity('bob.zks'),
  () => sdk.identity.getIdentity('charlie.zks')
];

const { results, errors } = await batchIdentityOperations(operations);
console.log('Successful operations:', results.length);
console.log('Failed operations:', errors.length);
```

### 3. Identity Validation Service

```javascript theme={null}
// Comprehensive identity validation
class IdentityValidationService {
  static async validateIdentity(identity) {
    const validation = {
      isValid: true,
      errors: [],
      warnings: []
    };
    
    try {
      // Check if identity exists
      const identityData = await sdk.identity.getIdentity(identity);
      
      if (!identityData.isActivated) {
        validation.warnings.push('Identity is not activated');
      }
      
      if (!identityData.metadata) {
        validation.warnings.push('Identity has no metadata');
      }
      
    } catch (error) {
      if (error.code === 'IDENTITY_NOT_FOUND') {
        validation.isValid = false;
        validation.errors.push('Identity not found');
      } else {
        validation.isValid = false;
        validation.errors.push(`Validation error: ${error.message}`);
      }
    }
    
    return validation;
  }
}

// Usage
const validation = await IdentityValidationService.validateIdentity('alice.zks');
if (!validation.isValid) {
  console.error('Validation failed:', validation.errors);
} else {
  console.log('Identity is valid');
  if (validation.warnings.length > 0) {
    console.warn('Warnings:', validation.warnings);
  }
}
```

## Related Documentation

* [Getting Started](/sdk/javascript/getting-started) - SDK setup and configuration
* [Score Queries](/sdk/javascript/score-queries) - Score and analytics
* [Achievements](/sdk/javascript/achievements) - Achievement system
* [API Reference](/api-reference/identity) - Identity API endpoints
