UNPKG

cdp-wallet-onramp-kit

Version:

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

224 lines (193 loc) 7.09 kB
/** * Hook return type detection and normalization utilities * Handles compatibility between different CDP SDK versions that return different types */ /** * Normalized user data structure */ export interface NormalizedUser { userId: string; email?: string; evmAccounts: string[]; } /** * Hook compatibility warnings */ let hasWarnedAboutObjectReturns = false; /** * Safe extraction of EVM address from CDP hooks * Handles both primitive string returns and object returns * * @param evmAddressResult - Result from useEvmAddress() hook * @returns string | null - The EVM address or null */ export function getEvmAddress(evmAddressResult: any): string | null { // Handle null/undefined if (!evmAddressResult) { return null; } // Handle primitive string return (expected behavior) if (typeof evmAddressResult === 'string') { return evmAddressResult; } // Handle object return (compatibility issue in some environments) if (typeof evmAddressResult === 'object' && evmAddressResult.evmAddress) { // Warn developers about compatibility issue if (!hasWarnedAboutObjectReturns && typeof window !== 'undefined' && console) { console.warn( '[CDP Kit] Detected object return from useEvmAddress(). This may indicate a version compatibility issue.\n' + 'Expected: string | null\n' + 'Received: object with evmAddress property\n' + 'Using defensive extraction. Consider updating CDP SDK versions.' ); hasWarnedAboutObjectReturns = true; } return typeof evmAddressResult.evmAddress === 'string' ? evmAddressResult.evmAddress : null; } // Handle unexpected return types if (typeof window !== 'undefined' && console) { console.error('[CDP Kit] Unexpected return type from useEvmAddress():', typeof evmAddressResult, evmAddressResult); } return null; } /** * Safe extraction of current user from CDP hooks * Handles both primitive object returns and nested object returns * * @param currentUserResult - Result from useCurrentUser() hook * @returns NormalizedUser | null - The normalized user data or null */ export function getCurrentUser(currentUserResult: any): NormalizedUser | null { // Handle null/undefined if (!currentUserResult) { return null; } // Handle direct user object (expected behavior) if (currentUserResult.userId && Array.isArray(currentUserResult.evmAccounts)) { return { userId: currentUserResult.userId, email: currentUserResult.email, evmAccounts: currentUserResult.evmAccounts }; } // Handle nested user object (compatibility fallback) if (currentUserResult.user && currentUserResult.user.userId) { return { userId: currentUserResult.user.userId, email: currentUserResult.user.email, evmAccounts: currentUserResult.user.evmAccounts || [] }; } // Handle unexpected structure if (typeof window !== 'undefined' && console) { console.error('[CDP Kit] Unexpected return type from useCurrentUser():', currentUserResult); } return null; } /** * Safe extraction of initialization status * Handles both boolean returns and object returns * * @param isInitializedResult - Result from useIsInitialized() hook * @returns boolean - The initialization status */ export function getIsInitialized(isInitializedResult: any): boolean { // Handle null/undefined if (isInitializedResult === null || isInitializedResult === undefined) { return false; } // Handle primitive boolean return (expected behavior) if (typeof isInitializedResult === 'boolean') { return isInitializedResult; } // Handle object return with isInitialized property if (typeof isInitializedResult === 'object' && typeof isInitializedResult.isInitialized === 'boolean') { return isInitializedResult.isInitialized; } // Default to false for safety return false; } /** * Safe extraction of action hooks (signOut, signInWithEmail, etc.) * These hooks typically return objects with action functions * * @param hookResult - Result from action hook (useSignOut, useSignInWithEmail, etc.) * @returns object - The action functions or empty object */ export function getHookActions(hookResult: any): Record<string, Function> { // Handle null/undefined if (!hookResult) { return {}; } // Handle object with functions (expected behavior) if (typeof hookResult === 'object') { return hookResult; } // Handle unexpected return types if (typeof window !== 'undefined' && console) { console.error('[CDP Kit] Unexpected return type from action hook:', typeof hookResult, hookResult); } return {}; } /** * Detect CDP SDK environment and version compatibility * Provides diagnostic information for troubleshooting * * @returns object - Environment diagnostic information */ export function detectCDPEnvironment() { const diagnostics = { hasWindow: typeof window !== 'undefined', hasProcess: typeof process !== 'undefined', nodeEnv: typeof process !== 'undefined' ? process.env.NODE_ENV : 'unknown', userAgent: typeof window !== 'undefined' ? window.navigator?.userAgent : 'unknown', recommendations: [] as string[] }; // Check for common setup issues if (typeof window === 'undefined') { diagnostics.recommendations.push('Ensure components using CDP hooks have "use client" directive in Next.js'); } if (typeof process !== 'undefined' && !process.env.NEXT_PUBLIC_CDP_PROJECT_ID) { diagnostics.recommendations.push('Set NEXT_PUBLIC_CDP_PROJECT_ID environment variable'); } return diagnostics; } /** * Validate that CDP hooks are returning expected types * Run this in development to catch compatibility issues early * * @param hookResults - Object containing results from various hooks */ export function validateHookReturns(hookResults: { evmAddress?: any; currentUser?: any; isInitialized?: any; }) { if (typeof window === 'undefined' || process.env.NODE_ENV !== 'development') { return; } const issues = []; // Check evmAddress return type if (hookResults.evmAddress !== undefined && hookResults.evmAddress !== null) { if (typeof hookResults.evmAddress !== 'string') { issues.push(`useEvmAddress() returned ${typeof hookResults.evmAddress}, expected string | null`); } } // Check currentUser return type if (hookResults.currentUser !== undefined && hookResults.currentUser !== null) { if (!hookResults.currentUser.userId) { issues.push(`useCurrentUser() returned object without userId property`); } } // Check isInitialized return type if (hookResults.isInitialized !== undefined) { if (typeof hookResults.isInitialized !== 'boolean') { issues.push(`useIsInitialized() returned ${typeof hookResults.isInitialized}, expected boolean`); } } if (issues.length > 0) { console.warn('[CDP Kit] Hook return type validation issues detected:'); issues.forEach(issue => console.warn(` - ${issue}`)); console.warn('This may indicate CDP SDK version compatibility issues.'); } }