UNPKG

cdp-wallet-onramp-kit

Version:

Complete toolkit for Coinbase Developer Platform (CDP) Embedded Wallets and Onramp integration with reusable components, utilities, and documentation

283 lines (245 loc) 8 kB
/** * Environment validation utilities for CDP Wallet & Onramp integration * Helps developers debug configuration issues */ export interface ValidationResult { isValid: boolean; errors: string[]; warnings: string[]; suggestions: string[]; } export interface EnvironmentStatus { projectId: ValidationResult; apiKey: ValidationResult; apiKeyName: ValidationResult; structure: ValidationResult; overall: ValidationResult; } /** * Validate CDP project ID */ export function validateProjectId(): ValidationResult { const projectId = process.env.NEXT_PUBLIC_CDP_PROJECT_ID; if (!projectId) { return { isValid: false, errors: ['NEXT_PUBLIC_CDP_PROJECT_ID is not set'], warnings: [], suggestions: [ 'Add NEXT_PUBLIC_CDP_PROJECT_ID=your-project-id to your .env.local file', 'Get your project ID from https://portal.cdp.coinbase.com' ] }; } // Check format (UUID-like) const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; if (!uuidPattern.test(projectId)) { return { isValid: false, errors: ['Project ID format appears invalid'], warnings: [], suggestions: [ 'Project ID should be a UUID format like: 12345678-1234-1234-1234-123456789012', 'Double-check your project ID in CDP Portal' ] }; } return { isValid: true, errors: [], warnings: [], suggestions: [] }; } /** * Validate CDP API credentials for server-side operations */ export function validateApiCredentials(): ValidationResult { const apiKeyName = process.env.CDP_API_KEY_NAME; const privateKey = process.env.CDP_API_KEY_PRIVATE_KEY; const errors: string[] = []; const warnings: string[] = []; const suggestions: string[] = []; if (!apiKeyName) { errors.push('CDP_API_KEY_NAME is not set'); suggestions.push('Add CDP_API_KEY_NAME=your-api-key-name to your .env.local file'); } if (!privateKey) { errors.push('CDP_API_KEY_PRIVATE_KEY is not set'); suggestions.push('Add CDP_API_KEY_PRIVATE_KEY=your-private-key to your .env.local file'); } if (privateKey && privateKey.length < 50) { warnings.push('Private key appears too short - may be incomplete'); suggestions.push('Ensure you copied the complete private key from CDP Portal'); } if (errors.length === 0 && warnings.length === 0) { return { isValid: true, errors: [], warnings: [], suggestions: ['API credentials look good! 🎉'] }; } return { isValid: errors.length === 0, errors, warnings, suggestions: [ ...suggestions, 'Create API credentials at: https://portal.cdp.coinbase.com → API Keys → Secret API Keys' ] }; } /** * Validate project structure for Next.js compatibility */ export function validateProjectStructure(): ValidationResult { const hasApp = require('fs').existsSync('app'); const hasSrcApp = require('fs').existsSync('src/app'); const hasPages = require('fs').existsSync('pages'); const hasSrcPages = require('fs').existsSync('src/pages'); const errors: string[] = []; const warnings: string[] = []; const suggestions: string[] = []; if (!hasApp && !hasSrcApp && !hasPages && !hasSrcPages) { errors.push('No Next.js structure detected (no app/ or pages/ directory found)'); suggestions.push('Ensure you are in a Next.js project directory'); suggestions.push('Run this command from your Next.js project root'); } else if (hasPages || hasSrcPages) { warnings.push('Pages Router detected - CDP components designed for App Router'); suggestions.push('Consider migrating to Next.js App Router for best compatibility'); suggestions.push('Or check component compatibility with Pages Router'); } else if (hasApp || hasSrcApp) { suggestions.push('App Router detected - perfect for CDP components! 🎉'); } return { isValid: errors.length === 0, errors, warnings, suggestions }; } /** * Run comprehensive environment validation */ export function validateCDPEnvironment(): EnvironmentStatus { const projectId = validateProjectId(); const apiKey = validateApiCredentials(); const apiKeyName = { ...apiKey }; // Same validation for now const structure = validateProjectStructure(); const allErrors = [ ...projectId.errors, ...apiKey.errors, ...structure.errors ]; const allWarnings = [ ...projectId.warnings, ...apiKey.warnings, ...structure.warnings ]; const allSuggestions = [ ...projectId.suggestions, ...apiKey.suggestions, ...structure.suggestions ]; const overall: ValidationResult = { isValid: allErrors.length === 0, errors: allErrors, warnings: allWarnings, suggestions: allSuggestions }; return { projectId, apiKey, apiKeyName, structure, overall }; } /** * Format validation results for console output */ export function formatValidationResults(status: EnvironmentStatus): string { const sections: string[] = []; sections.push('🔍 CDP Environment Validation Results'); sections.push('='.repeat(50)); // Overall status if (status.overall.isValid) { sections.push('✅ Overall Status: READY TO GO! 🎉'); } else { sections.push('❌ Overall Status: Issues found that need attention'); } sections.push(''); // Project ID sections.push('📋 Project ID:'); if (status.projectId.isValid) { sections.push(' ✅ Valid'); } else { status.projectId.errors.forEach(error => sections.push(` ❌ ${error}`)); } // API Credentials sections.push('🔑 API Credentials:'); if (status.apiKey.isValid) { sections.push(' ✅ Valid'); } else { status.apiKey.errors.forEach(error => sections.push(` ❌ ${error}`)); } status.apiKey.warnings.forEach(warning => sections.push(` ⚠️ ${warning}`)); // Project Structure sections.push('📁 Project Structure:'); if (status.structure.isValid) { sections.push(' ✅ Compatible'); } else { status.structure.errors.forEach(error => sections.push(` ❌ ${error}`)); } status.structure.warnings.forEach(warning => sections.push(` ⚠️ ${warning}`)); // Suggestions if (status.overall.suggestions.length > 0) { sections.push(''); sections.push('💡 Suggestions:'); status.overall.suggestions.forEach(suggestion => sections.push(` • ${suggestion}`)); } sections.push(''); sections.push('Need help? Check: https://docs.cdp.coinbase.com/'); return sections.join('\n'); } /** * Quick validation check - returns true if environment is ready */ export function isEnvironmentReady(): boolean { const status = validateCDPEnvironment(); return status.overall.isValid; } /** * Test CDP API connectivity (async validation) */ export async function testCDPConnectivity(): Promise<ValidationResult> { try { // This would require the actual CDP SDK to test connectivity // For now, just validate that credentials are present const apiValidation = validateApiCredentials(); const projectValidation = validateProjectId(); if (!apiValidation.isValid || !projectValidation.isValid) { return { isValid: false, errors: ['Cannot test connectivity - missing credentials'], warnings: [], suggestions: ['Fix credential issues first, then test connectivity'] }; } // TODO: Add actual CDP API connectivity test return { isValid: true, errors: [], warnings: ['Connectivity test not implemented yet'], suggestions: ['Credentials look good - try using CDP components to test'] }; } catch (error) { return { isValid: false, errors: [`Connectivity test failed: ${error instanceof Error ? error.message : 'Unknown error'}`], warnings: [], suggestions: ['Check your internet connection and CDP credentials'] }; } }