/** * @file credential-verifier.ts * @notice Credential verification for tokenization workflows */ import { InstitutionalIdentityService, VerifiableCredential } from './institutional-identity'; export interface CredentialVerificationRequest { did: string; requiredCredentials: string[]; requiredTier?: number; } export interface CredentialVerificationResult { verified: boolean; missingCredentials: string[]; tier: number; credentials: VerifiableCredential[]; error?: string; } export class CredentialVerifier { private identityService: InstitutionalIdentityService; constructor(identityService: InstitutionalIdentityService) { this.identityService = identityService; } /** * Verify credentials for tokenization operation */ async verifyForTokenization( request: CredentialVerificationRequest ): Promise { // Get institution credentials const credentials = await this.identityService.getInstitutionCredentials(request.did); // Verify each credential const verifiedCredentials: VerifiableCredential[] = []; const missingCredentials: string[] = []; for (const requiredType of request.requiredCredentials) { const credential = credentials.find((vc: VerifiableCredential) => vc.type.includes(requiredType) ); if (!credential) { missingCredentials.push(requiredType); continue; } // Verify credential const verification = await this.identityService.verifyCredential(credential); if (verification.valid) { verifiedCredentials.push(credential); } else { missingCredentials.push(requiredType); } } // Check tier requirement const eligibility = await this.identityService.checkTokenizationEligibility(request.did); const tierMet = request.requiredTier ? eligibility.tier >= request.requiredTier : true; return { verified: missingCredentials.length === 0 && tierMet, missingCredentials, tier: eligibility.tier, credentials: verifiedCredentials, error: missingCredentials.length > 0 ? `Missing credentials: ${missingCredentials.join(', ')}` : !tierMet ? `Tier requirement not met: required ${request.requiredTier}, has ${eligibility.tier}` : undefined }; } /** * Verify credentials for specific operation type */ async verifyForOperation( did: string, operation: 'mint' | 'transfer' | 'redeem' | 'bridge' ): Promise { const requiredCredentials = this.getRequiredCredentials(operation); const requiredTier = this.getRequiredTier(operation); return this.verifyForTokenization({ did, requiredCredentials, requiredTier }); } /** * Get required credentials for operation */ private getRequiredCredentials(operation: string): string[] { const requirements: Record = { 'mint': ['KYC', 'AML', 'RegulatoryApproval'], 'transfer': ['KYC', 'AML'], 'redeem': ['KYC', 'AML', 'RegulatoryApproval'], 'bridge': ['KYC', 'AML'] }; return requirements[operation] || ['KYC', 'AML']; } /** * Get required tier for operation */ private getRequiredTier(operation: string): number { const tierRequirements: Record = { 'mint': 2, // Tier 2 for minting 'transfer': 1, // Tier 1 for transfers 'redeem': 2, // Tier 2 for redemption 'bridge': 1 // Tier 1 for bridging }; return tierRequirements[operation] || 1; } /** * Check policy-based access control */ async checkPolicyAccess( did: string, operation: string, context: Record ): Promise<{ allowed: boolean; reason?: string }> { const verification = await this.verifyForOperation(did, operation as any); if (!verification.verified) { return { allowed: false, reason: verification.error }; } // Additional policy checks // In production, integrate with SolaceNet policy engine if (context.amount && parseFloat(context.amount) > 1000000) { // Large amounts require Tier 3 if (verification.tier < 3) { return { allowed: false, reason: 'Large amount requires Tier 3 credentials' }; } } return { allowed: true }; } }