zopassport 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +407 -0
  3. package/app/.env.example +15 -0
  4. package/app/README.md +28 -0
  5. package/app/package.json +24 -0
  6. package/app/reanimated-mock.js +102 -0
  7. package/app/reanimated-mock.jsx +97 -0
  8. package/app/src/App.tsx +331 -0
  9. package/app/src/components/FounderBadge.tsx +26 -0
  10. package/app/src/components/OTPInput.tsx +149 -0
  11. package/app/src/components/PhoneInput.tsx +109 -0
  12. package/app/src/components/ZoAuth.tsx +320 -0
  13. package/app/src/components/ZoAvatar.tsx +87 -0
  14. package/app/src/components/ZoLanding.tsx +231 -0
  15. package/app/src/components/ZoOnboarding.tsx +524 -0
  16. package/app/src/components/ZoPassportCard.tsx +183 -0
  17. package/app/src/components/ZoProgressRing.tsx +57 -0
  18. package/app/src/components/index.ts +16 -0
  19. package/app/src/components/wallet/MovingShine.tsx +43 -0
  20. package/app/src/components/wallet/TransactionItem.tsx +84 -0
  21. package/app/src/components/wallet/TransactionList.tsx +65 -0
  22. package/app/src/components/wallet/WalletCard.tsx +152 -0
  23. package/app/src/components/wallet/WalletScreen.tsx +190 -0
  24. package/app/src/components/wallet/ZoToken.tsx +69 -0
  25. package/app/src/components/wallet/index.ts +8 -0
  26. package/app/src/components/wallet/styles/index.ts +4 -0
  27. package/app/src/components/wallet/styles/walletStyles.ts +210 -0
  28. package/app/src/sdk/ZoPassportSDK.ts +277 -0
  29. package/app/src/sdk/lib/api/auth.ts +223 -0
  30. package/app/src/sdk/lib/api/avatar.ts +155 -0
  31. package/app/src/sdk/lib/api/client.ts +135 -0
  32. package/app/src/sdk/lib/api/index.ts +8 -0
  33. package/app/src/sdk/lib/api/profile.ts +80 -0
  34. package/app/src/sdk/lib/api/wallet.ts +59 -0
  35. package/app/src/sdk/lib/types/auth.ts +78 -0
  36. package/app/src/sdk/lib/types/avatar.ts +22 -0
  37. package/app/src/sdk/lib/types/index.ts +8 -0
  38. package/app/src/sdk/lib/types/profile.ts +18 -0
  39. package/app/src/sdk/lib/types/wallet.ts +103 -0
  40. package/app/src/sdk/lib/types.ts +205 -0
  41. package/app/src/sdk/lib/utils/index.ts +6 -0
  42. package/app/src/sdk/lib/utils/phone.ts +71 -0
  43. package/app/src/sdk/lib/utils/storage.ts +116 -0
  44. package/app/src/sdk/lib/utils/wallet.ts +73 -0
  45. package/app/src/sdk/types.ts +205 -0
  46. package/app/src/styles.css +154 -0
  47. package/app/svg-mock.js +125 -0
  48. package/app/svg-mock.jsx +120 -0
  49. package/app/vite.config.ts +70 -0
  50. package/assets/ASSETS_MANIFEST.md +124 -0
  51. package/assets/bae.png +0 -0
  52. package/assets/bro.png +0 -0
  53. package/assets/cultural-stickers/Business.png +0 -0
  54. package/assets/cultural-stickers/Default (2).jpg +0 -0
  55. package/assets/cultural-stickers/Design.png +0 -0
  56. package/assets/cultural-stickers/FollowYourHeart.png +0 -0
  57. package/assets/cultural-stickers/Food.png +0 -0
  58. package/assets/cultural-stickers/Game.png +0 -0
  59. package/assets/cultural-stickers/Health&Fitness.png +0 -0
  60. package/assets/cultural-stickers/Home&Lifestyle.png +0 -0
  61. package/assets/cultural-stickers/Law.png +0 -0
  62. package/assets/cultural-stickers/Literature&Stories.png +0 -0
  63. package/assets/cultural-stickers/Music&Entertainment.png +0 -0
  64. package/assets/cultural-stickers/Nature&Wildlife.png +0 -0
  65. package/assets/cultural-stickers/Photography.png +0 -0
  66. package/assets/cultural-stickers/Science&Technology.png +0 -0
  67. package/assets/cultural-stickers/Spiritual.png +0 -0
  68. package/assets/cultural-stickers/Sport.png +0 -0
  69. package/assets/cultural-stickers/Stories&Journal.png +0 -0
  70. package/assets/cultural-stickers/Television&Cinema.png +0 -0
  71. package/assets/cultural-stickers/Travel&Adventure.png +0 -0
  72. package/assets/cultural-stickers/z.jpg (1).jpg +0 -0
  73. package/assets/figma-assets/landing-zo-logo.png +0 -0
  74. package/assets/images/rank1.jpeg +0 -0
  75. package/assets/index.ts +76 -0
  76. package/assets/lotties/loader.json +1216 -0
  77. package/assets/lotties/spinner.json +1 -0
  78. package/assets/videos/loading-screen-background.mp4 +0 -0
  79. package/assets/videos/opening-disks.mp4 +0 -0
  80. package/assets/wallet/constants.ts +38 -0
  81. package/assets/zo-coin.gif +0 -0
  82. package/assets/zo-fallback.png +0 -0
  83. package/dist/assets/index.d.mts +136 -0
  84. package/dist/assets/index.d.ts +136 -0
  85. package/dist/assets/index.js +133 -0
  86. package/dist/assets/index.js.map +1 -0
  87. package/dist/assets/index.mjs +100 -0
  88. package/dist/assets/index.mjs.map +1 -0
  89. package/dist/index.d.mts +789 -0
  90. package/dist/index.d.ts +789 -0
  91. package/dist/index.js +1118 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/index.mjs +1060 -0
  94. package/dist/index.mjs.map +1 -0
  95. package/dist/react-native.d.mts +537 -0
  96. package/dist/react-native.d.ts +537 -0
  97. package/dist/react-native.js +1617 -0
  98. package/dist/react-native.js.map +1 -0
  99. package/dist/react-native.mjs +1588 -0
  100. package/dist/react-native.mjs.map +1 -0
  101. package/dist/react.d.mts +824 -0
  102. package/dist/react.d.ts +824 -0
  103. package/dist/react.js +3856 -0
  104. package/dist/react.js.map +1 -0
  105. package/dist/react.mjs +3801 -0
  106. package/dist/react.mjs.map +1 -0
  107. package/package.json +112 -0
  108. package/scripts/init.js +196 -0
  109. package/scripts/postinstall.js +174 -0
  110. package/scripts/verify-build.js +121 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react.tsx","../src/lib/api/client.ts","../src/lib/utils/logger.ts","../src/lib/utils/storage.ts","../src/lib/api/auth.ts","../src/lib/api/profile.ts","../src/lib/api/avatar.ts","../src/lib/api/wallet.ts","../src/ZoPassportSDK.ts","../src/components/ZoProgressRing.tsx","../src/components/FounderBadge.tsx","../src/components/ZoAvatar.tsx","../src/components/ZoPassportCard.tsx","../src/components/ZoPassportPage.tsx","../src/components/wallet/WalletCardWeb.tsx","../src/lib/utils/wallet.ts","../src/lib/utils/styles.ts","../src/components/wallet/WalletFullPage.tsx","../assets/wallet/constants.ts","../assets/index.ts","../src/lib/utils/phone.ts","../src/components/PhoneInput.tsx","../src/components/OTPInput.tsx","../src/components/ZoAuth.tsx","../src/components/ZoLanding.tsx","../src/components/ZoOnboarding.tsx","../src/hooks/useAuth.ts","../src/hooks/useProfile.ts","../src/hooks/useAvatar.ts","../src/hooks/useWallet.ts","../src/hooks/useWalletBalance.ts","../src/hooks/useTransactions.ts"],"sourcesContent":["// zopassport/react\n// React-specific exports for the Zo Passport SDK\n\nimport React, { createContext, useContext, useEffect, useState, ReactNode } from 'react';\nimport { ZoPassportSDK, ZoPassportSDKConfig } from './ZoPassportSDK';\nimport type { ZoUser } from './lib/types';\n\n// Re-export components\nexport * from './components';\n\n// Re-export hooks\nexport * from './hooks';\n\n// Re-export types\nexport * from './lib/types';\n\n// =====================\n// Context\n// =====================\n\ninterface ZoPassportContextValue {\n sdk: ZoPassportSDK | null;\n user: ZoUser | null;\n isAuthenticated: boolean;\n isLoading: boolean;\n sendOTP: (countryCode: string, phoneNumber: string) => Promise<{ success: boolean; message: string }>;\n verifyOTP: (countryCode: string, phoneNumber: string, otp: string) => Promise<{ success: boolean; error?: string }>;\n logout: () => Promise<void>;\n refreshProfile: () => Promise<void>;\n}\n\nconst ZoPassportContext = createContext<ZoPassportContextValue | null>(null);\n\n// =====================\n// Provider\n// =====================\n\nexport interface ZoPassportProviderProps {\n children: ReactNode;\n clientKey: string;\n baseUrl?: string;\n autoRefresh?: boolean;\n}\n\nexport function ZoPassportProvider({\n children,\n clientKey,\n baseUrl,\n autoRefresh = true,\n}: ZoPassportProviderProps) {\n const [sdk, setSdk] = useState<ZoPassportSDK | null>(null);\n const [user, setUser] = useState<ZoUser | null>(null);\n const [isAuthenticated, setIsAuthenticated] = useState(false);\n const [isLoading, setIsLoading] = useState(true);\n\n // Initialize SDK\n useEffect(() => {\n const passportSdk = new ZoPassportSDK({\n clientKey,\n baseUrl,\n autoRefresh,\n });\n\n setSdk(passportSdk);\n\n // Load existing session - must await ready() first to ensure session is loaded from storage\n const loadSession = async () => {\n setIsLoading(true);\n try {\n // Wait for SDK to finish loading session from storage\n await passportSdk.ready();\n \n if (passportSdk.isAuthenticated) {\n const profile = await passportSdk.getProfile();\n if (profile) {\n setUser(profile);\n setIsAuthenticated(true);\n }\n }\n } catch (error) {\n console.error('[ZoPassport] Failed to load session:', error);\n } finally {\n setIsLoading(false);\n }\n };\n\n loadSession();\n\n return () => {\n passportSdk.destroy();\n };\n }, [clientKey, baseUrl, autoRefresh]);\n\n // Send OTP\n const sendOTP = async (countryCode: string, phoneNumber: string) => {\n if (!sdk) return { success: false, message: 'SDK not initialized' };\n return sdk.auth.sendOTP(countryCode, phoneNumber);\n };\n\n // Verify OTP\n const verifyOTP = async (countryCode: string, phoneNumber: string, otp: string) => {\n if (!sdk) return { success: false, error: 'SDK not initialized' };\n \n const result = await sdk.loginWithPhone(countryCode, phoneNumber, otp);\n if (result.success && result.user) {\n setUser(result.user);\n setIsAuthenticated(true);\n }\n return result;\n };\n\n // Logout\n const logout = async () => {\n if (!sdk) return;\n await sdk.logout();\n setUser(null);\n setIsAuthenticated(false);\n };\n\n // Refresh profile\n const refreshProfile = async () => {\n if (!sdk) return;\n const profile = await sdk.getProfile();\n if (profile) {\n setUser(profile);\n }\n };\n\n const value: ZoPassportContextValue = {\n sdk,\n user,\n isAuthenticated,\n isLoading,\n sendOTP,\n verifyOTP,\n logout,\n refreshProfile,\n };\n\n return (\n <ZoPassportContext.Provider value={value}>\n {children}\n </ZoPassportContext.Provider>\n );\n}\n\n// =====================\n// Hook\n// =====================\n\nexport function useZoPassport(): ZoPassportContextValue {\n const context = useContext(ZoPassportContext);\n if (!context) {\n throw new Error('useZoPassport must be used within a ZoPassportProvider');\n }\n return context;\n}\n\n// =====================\n// Re-export SDK\n// =====================\n\nexport { ZoPassportSDK } from './ZoPassportSDK';\n\n","// src/lib/api/client.ts\n// ZO API HTTP client configuration\n\nimport axios, { AxiosInstance } from 'axios';\nimport { StorageAdapter, STORAGE_KEYS, LocalStorageAdapter } from '../utils/storage';\n\nexport interface ZoPassportConfig {\n /** Your ZO client key (required) */\n clientKey: string;\n /** API base URL (default: https://api.io.zo.xyz) */\n baseUrl?: string;\n /** Request timeout in ms (default: 10000) */\n timeout?: number;\n /** Storage adapter for tokens (default: LocalStorageAdapter) */\n storageAdapter?: StorageAdapter;\n}\n\n/**\n * Generate new device credentials\n */\nfunction generateDeviceCredentials(): { deviceId: string; deviceSecret: string } {\n const deviceId = `web-${Date.now()}-${Math.random().toString(36).substring(7)}`;\n const deviceSecret = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);\n return { deviceId, deviceSecret };\n}\n\nexport class ZoApiClient {\n private client: AxiosInstance;\n private config: ZoPassportConfig;\n private storage: StorageAdapter;\n\n constructor(config: ZoPassportConfig) {\n this.config = config;\n this.storage = config.storageAdapter || new LocalStorageAdapter();\n\n this.client = axios.create({\n baseURL: config.baseUrl || 'https://api.io.zo.xyz',\n timeout: config.timeout || 10000,\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n },\n });\n\n this.setupInterceptors();\n }\n\n private async setupInterceptors() {\n // Request interceptor: Add required headers\n this.client.interceptors.request.use(async (config) => {\n // Always add client key\n config.headers['client-key'] = this.config.clientKey;\n\n // Get or generate device credentials\n const credentials = await this.getOrCreateDeviceCredentials();\n config.headers['client-device-id'] = credentials.deviceId;\n config.headers['client-device-secret'] = credentials.deviceSecret;\n\n // Add auth token if available\n const token = await this.storage.getItem(STORAGE_KEYS.ACCESS_TOKEN);\n if (token) {\n config.headers['Authorization'] = `Bearer ${token}`;\n }\n\n return config;\n });\n\n // Response interceptor: Handle token refresh on 401\n this.client.interceptors.response.use(\n (response) => response,\n async (error) => {\n const originalRequest = error.config;\n\n // If 401 and we haven't retried yet\n if (error.response?.status === 401 && !originalRequest._retry) {\n originalRequest._retry = true;\n\n const refreshToken = await this.storage.getItem(STORAGE_KEYS.REFRESH_TOKEN);\n if (refreshToken) {\n try {\n const response = await this.client.post('/api/v1/auth/token/refresh/', {\n refresh_token: refreshToken,\n });\n\n if (response.data?.access) {\n await this.storage.setItem(STORAGE_KEYS.ACCESS_TOKEN, response.data.access);\n if (response.data.refresh) {\n await this.storage.setItem(STORAGE_KEYS.REFRESH_TOKEN, response.data.refresh);\n }\n\n // Retry original request with new token\n originalRequest.headers['Authorization'] = `Bearer ${response.data.access}`;\n return this.client(originalRequest);\n }\n } catch (refreshError) {\n // Refresh failed - clear session\n await this.storage.removeItem(STORAGE_KEYS.ACCESS_TOKEN);\n await this.storage.removeItem(STORAGE_KEYS.REFRESH_TOKEN);\n }\n }\n }\n\n return Promise.reject(error);\n }\n );\n }\n\n private async getOrCreateDeviceCredentials(): Promise<{ deviceId: string; deviceSecret: string }> {\n // Try to get from storage\n const storedId = await this.storage.getItem(STORAGE_KEYS.CLIENT_DEVICE_ID);\n const storedSecret = await this.storage.getItem(STORAGE_KEYS.CLIENT_DEVICE_SECRET);\n\n if (storedId && storedSecret) {\n return { deviceId: storedId, deviceSecret: storedSecret };\n }\n\n // Generate new credentials\n const credentials = generateDeviceCredentials();\n\n // Save to storage\n await this.storage.setItem(STORAGE_KEYS.CLIENT_DEVICE_ID, credentials.deviceId);\n await this.storage.setItem(STORAGE_KEYS.CLIENT_DEVICE_SECRET, credentials.deviceSecret);\n\n return credentials;\n }\n\n get axiosInstance(): AxiosInstance {\n return this.client;\n }\n\n getStorage(): StorageAdapter {\n return this.storage;\n }\n}\n\n","// src/lib/utils/logger.ts\n// Configurable logger for SDK debugging\n\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';\n\ninterface LoggerConfig {\n enabled: boolean;\n level: LogLevel;\n prefix: string;\n}\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n none: 4,\n};\n\nclass Logger {\n private config: LoggerConfig = {\n enabled: false,\n level: 'warn',\n prefix: '[ZoPassport]',\n };\n\n /**\n * Configure the logger\n * @param options - Logger configuration\n */\n configure(options: Partial<LoggerConfig>): void {\n this.config = { ...this.config, ...options };\n }\n\n /**\n * Enable debug logging\n */\n enable(): void {\n this.config.enabled = true;\n }\n\n /**\n * Disable all logging\n */\n disable(): void {\n this.config.enabled = false;\n }\n\n /**\n * Set log level\n */\n setLevel(level: LogLevel): void {\n this.config.level = level;\n }\n\n private shouldLog(level: LogLevel): boolean {\n if (!this.config.enabled) return false;\n return LOG_LEVELS[level] >= LOG_LEVELS[this.config.level];\n }\n\n debug(...args: unknown[]): void {\n if (this.shouldLog('debug')) {\n console.log(this.config.prefix, ...args);\n }\n }\n\n info(...args: unknown[]): void {\n if (this.shouldLog('info')) {\n console.info(this.config.prefix, ...args);\n }\n }\n\n warn(...args: unknown[]): void {\n if (this.shouldLog('warn')) {\n console.warn(this.config.prefix, ...args);\n }\n }\n\n error(...args: unknown[]): void {\n if (this.shouldLog('error')) {\n console.error(this.config.prefix, ...args);\n }\n }\n}\n\n// Singleton instance\nexport const logger = new Logger();\n\n// Export for testing/advanced usage\nexport { Logger };\nexport type { LogLevel, LoggerConfig };\n\n","// src/lib/utils/storage.ts\n// Storage adapters for token persistence\n\nimport { logger } from './logger';\n\n/**\n * Storage adapter interface\n * Implement this to provide custom storage (e.g., AsyncStorage for React Native)\n */\nexport interface StorageAdapter {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n}\n\n/**\n * Storage keys used by the SDK\n */\nexport const STORAGE_KEYS = {\n ACCESS_TOKEN: 'zo_access_token',\n REFRESH_TOKEN: 'zo_refresh_token',\n TOKEN_EXPIRY: 'zo_token_expiry',\n REFRESH_EXPIRY: 'zo_refresh_expiry',\n USER: 'zo_user',\n CLIENT_DEVICE_ID: 'zo_device_id',\n CLIENT_DEVICE_SECRET: 'zo_device_secret',\n AVATAR_URL: 'zo_avatar_url',\n NICKNAME: 'zo_nickname',\n CITY: 'zo_city',\n BODY_TYPE: 'zo_body_type',\n} as const;\n\n/**\n * LocalStorage adapter for web browsers\n */\nexport class LocalStorageAdapter implements StorageAdapter {\n async getItem(key: string): Promise<string | null> {\n if (typeof window === 'undefined') return null;\n try {\n return localStorage.getItem(key);\n } catch (error) {\n logger.warn(`LocalStorage.getItem failed for key \"${key}\":`, error);\n return null;\n }\n }\n\n async setItem(key: string, value: string): Promise<void> {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(key, value);\n } catch (error) {\n // Common causes: storage full, private mode, SecurityError\n logger.warn(`LocalStorage.setItem failed for key \"${key}\":`, error);\n }\n }\n\n async removeItem(key: string): Promise<void> {\n if (typeof window === 'undefined') return;\n try {\n localStorage.removeItem(key);\n } catch (error) {\n logger.warn(`LocalStorage.removeItem failed for key \"${key}\":`, error);\n }\n }\n}\n\n/**\n * AsyncStorage adapter for React Native\n * Provide AsyncStorage from @react-native-async-storage/async-storage\n */\nexport class AsyncStorageAdapter implements StorageAdapter {\n private storage: {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, value: string): Promise<void>;\n removeItem(key: string): Promise<void>;\n };\n\n constructor(asyncStorage: AsyncStorageAdapter['storage']) {\n this.storage = asyncStorage;\n }\n\n async getItem(key: string): Promise<string | null> {\n try {\n return await this.storage.getItem(key);\n } catch (error) {\n logger.warn(`AsyncStorage.getItem failed for key \"${key}\":`, error);\n return null;\n }\n }\n\n async setItem(key: string, value: string): Promise<void> {\n try {\n await this.storage.setItem(key, value);\n } catch (error) {\n logger.warn(`AsyncStorage.setItem failed for key \"${key}\":`, error);\n }\n }\n\n async removeItem(key: string): Promise<void> {\n try {\n await this.storage.removeItem(key);\n } catch (error) {\n logger.warn(`AsyncStorage.removeItem failed for key \"${key}\":`, error);\n }\n }\n}\n\n/**\n * In-memory storage adapter (for SSR or testing)\n */\nexport class MemoryStorageAdapter implements StorageAdapter {\n private store: Map<string, string> = new Map();\n\n async getItem(key: string): Promise<string | null> {\n return this.store.get(key) || null;\n }\n\n async setItem(key: string, value: string): Promise<void> {\n this.store.set(key, value);\n }\n\n async removeItem(key: string): Promise<void> {\n this.store.delete(key);\n }\n\n /** Clear all stored data (useful for testing) */\n clear(): void {\n this.store.clear();\n }\n}\n","// src/lib/api/auth.ts\n// ZO API authentication functions\n\nimport { ZoApiClient } from './client';\nimport type {\n ZoAuthOTPRequest,\n ZoAuthOTPVerifyRequest,\n ZoAuthResponse,\n ZoErrorResponse,\n} from '../types';\n\nexport class ZoAuth {\n constructor(private client: ZoApiClient) {}\n\n /**\n * Send OTP to phone number\n * Step 1 of ZO phone authentication\n */\n async sendOTP(\n countryCode: string,\n phoneNumber: string\n ): Promise<{ success: boolean; message: string }> {\n try {\n const payload: ZoAuthOTPRequest = {\n mobile_country_code: countryCode,\n mobile_number: phoneNumber,\n message_channel: '', // Empty string as per ZO API spec\n };\n\n const response = await this.client.axiosInstance.post(\n '/api/v1/auth/login/mobile/otp/',\n payload\n );\n\n if (response.status >= 200 && response.status < 300) {\n return {\n success: true,\n message: response.data?.message || 'OTP sent successfully',\n };\n }\n\n return {\n success: false,\n message: response.data?.message || `Unexpected status: ${response.status}`,\n };\n } catch (error: any) {\n const errorData = error.response?.data as ZoErrorResponse;\n const errorMessage = errorData?.detail || errorData?.message || errorData?.error || error.message || 'Failed to send OTP';\n\n return {\n success: false,\n message: errorMessage,\n };\n }\n }\n\n /**\n * Verify OTP and authenticate user\n * Step 2 of ZO phone authentication\n * Returns full auth response with tokens and user profile\n */\n async verifyOTP(\n countryCode: string,\n phoneNumber: string,\n otp: string\n ): Promise<{\n success: boolean;\n data?: ZoAuthResponse;\n error?: string;\n }> {\n try {\n const payload: ZoAuthOTPVerifyRequest = {\n mobile_country_code: countryCode,\n mobile_number: phoneNumber,\n otp,\n };\n\n const response = await this.client.axiosInstance.post<ZoAuthResponse>(\n '/api/v1/auth/login/mobile/',\n payload\n );\n\n // Parse response data if it's a string\n let responseData: ZoAuthResponse;\n if (typeof response.data === 'string') {\n try {\n responseData = JSON.parse(response.data);\n } catch {\n return {\n success: false,\n error: 'Invalid response format from authentication service',\n };\n }\n } else {\n responseData = response.data;\n }\n\n // Validate response structure\n if (!responseData || !responseData.user || !responseData.access_token) {\n return {\n success: false,\n error: 'Invalid response structure from authentication service',\n };\n }\n\n // Note: Session storage is handled by ZoPassportSDK.saveSession()\n return {\n success: true,\n data: responseData,\n };\n } catch (error: any) {\n const errorMessage = this.extractErrorMessage(error);\n return {\n success: false,\n error: errorMessage,\n };\n }\n }\n\n /**\n * Refresh access token using refresh token\n */\n async refreshAccessToken(\n refreshToken: string\n ): Promise<{\n success: boolean;\n tokens?: {\n access: string;\n refresh: string;\n access_expiry: string;\n refresh_expiry: string;\n };\n error?: string;\n }> {\n try {\n const response = await this.client.axiosInstance.post('/api/v1/auth/token/refresh/', {\n refresh_token: refreshToken,\n });\n\n return {\n success: true,\n tokens: response.data,\n };\n } catch (error: any) {\n return {\n success: false,\n error: 'Failed to refresh authentication',\n };\n }\n }\n\n /**\n * Check if user is authenticated\n */\n async checkLoginStatus(accessToken: string): Promise<{\n success: boolean;\n isAuthenticated: boolean;\n }> {\n try {\n const response = await this.client.axiosInstance.get('/api/v1/auth/login/check/', {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n return {\n success: true,\n isAuthenticated: response.data.authenticated === true,\n };\n } catch {\n return {\n success: false,\n isAuthenticated: false,\n };\n }\n }\n\n /**\n * Extract error message from various ZO API error formats\n */\n private extractErrorMessage(error: any): string {\n const errorData = error.response?.data;\n\n if (errorData) {\n // Format 1: { success: false, errors: [...] }\n if (errorData.errors && Array.isArray(errorData.errors)) {\n return errorData.errors[0] || 'Invalid OTP';\n }\n // Format 2: { detail: \"...\", message: \"...\" }\n if (errorData.detail) return errorData.detail;\n if (errorData.message) return errorData.message;\n // Format 3: { error: \"...\" }\n if (errorData.error) return errorData.error;\n }\n\n return 'Authentication failed';\n }\n}\n\n","// src/lib/api/profile.ts\n// ZO API profile functions\n\nimport { ZoApiClient } from './client';\nimport type { ZoProfileResponse, ZoProfileUpdatePayload, ZoErrorResponse } from '../types';\n\nexport class ZoProfile {\n constructor(private client: ZoApiClient) {}\n\n /**\n * Get user profile\n */\n async getProfile(accessToken: string): Promise<{\n success: boolean;\n profile?: ZoProfileResponse;\n error?: string;\n }> {\n try {\n const response = await this.client.axiosInstance.get<ZoProfileResponse>(\n '/api/v1/profile/me/',\n {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n }\n );\n\n return {\n success: true,\n profile: response.data,\n };\n } catch (error: any) {\n const errorData = error.response?.data as ZoErrorResponse;\n return {\n success: false,\n error: errorData?.detail || errorData?.message || 'Failed to fetch profile',\n };\n }\n }\n\n /**\n * Update user profile (partial updates supported)\n */\n async updateProfile(\n accessToken: string,\n updates: ZoProfileUpdatePayload\n ): Promise<{\n success: boolean;\n profile?: ZoProfileResponse;\n error?: string;\n }> {\n try {\n const response = await this.client.axiosInstance.post<ZoProfileResponse>(\n '/api/v1/profile/me/',\n updates,\n {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n }\n );\n\n return {\n success: true,\n profile: response.data,\n };\n } catch (error: any) {\n const errorData = error.response?.data as ZoErrorResponse;\n return {\n success: false,\n error: errorData?.detail || errorData?.message || 'Failed to update profile',\n };\n }\n }\n}\n\n","// src/lib/api/avatar.ts\n// ZO API avatar generation functions\n\nimport { ZoApiClient } from './client';\nimport type {\n ZoAvatarGenerateRequest,\n ZoAvatarGenerateResponse,\n ZoAvatarStatusResponse,\n ZoErrorResponse,\n} from '../types';\n\nexport class ZoAvatar {\n constructor(private client: ZoApiClient) {}\n\n /**\n * Generate avatar for user\n */\n async generateAvatar(\n accessToken: string,\n bodyType: 'bro' | 'bae'\n ): Promise<{\n success: boolean;\n task_id?: string;\n status?: string;\n error?: string;\n }> {\n try {\n const payload: ZoAvatarGenerateRequest = {\n body_type: bodyType,\n };\n\n const response = await this.client.axiosInstance.post<ZoAvatarGenerateResponse>(\n '/api/v1/avatar/generate/',\n payload,\n {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n }\n );\n\n return {\n success: true,\n task_id: response.data.task_id,\n status: response.data.status,\n };\n } catch (error: any) {\n const errorData = error.response?.data as ZoErrorResponse;\n return {\n success: false,\n error: errorData?.detail || errorData?.message || 'Failed to generate avatar',\n };\n }\n }\n\n /**\n * Check avatar generation status\n */\n async getAvatarStatus(\n accessToken: string,\n taskId: string\n ): Promise<{\n success: boolean;\n status?: 'pending' | 'processing' | 'completed' | 'failed';\n avatarUrl?: string;\n error?: string;\n }> {\n try {\n const response = await this.client.axiosInstance.get<ZoAvatarStatusResponse>(\n `/api/v1/avatar/status/${taskId}/`,\n {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n }\n );\n\n return {\n success: true,\n status: response.data.status,\n avatarUrl: response.data.result?.avatar_url,\n };\n } catch (error: any) {\n const errorData = error.response?.data as ZoErrorResponse;\n return {\n success: false,\n error: errorData?.detail || errorData?.message || 'Failed to get avatar status',\n };\n }\n }\n\n /**\n * Poll avatar status until completion\n */\n async pollAvatarStatus(\n accessToken: string,\n taskId: string,\n options: {\n onProgress?: (status: string) => void;\n onComplete?: (avatarUrl: string) => void;\n onError?: (error: string) => void;\n maxAttempts?: number;\n interval?: number;\n } = {}\n ): Promise<void> {\n const {\n onProgress,\n onComplete,\n onError,\n maxAttempts = 30,\n interval = 2000,\n } = options;\n\n let attempts = 0;\n\n const poll = async () => {\n attempts++;\n\n if (attempts > maxAttempts) {\n const timeoutError = 'Avatar generation timed out';\n onError?.(timeoutError);\n return;\n }\n\n const result = await this.getAvatarStatus(accessToken, taskId);\n\n if (!result.success) {\n onError?.(result.error || 'Unknown error');\n return;\n }\n\n onProgress?.(result.status || 'unknown');\n\n if (result.status === 'completed' && result.avatarUrl) {\n onComplete?.(result.avatarUrl);\n return;\n }\n\n if (result.status === 'failed') {\n onError?.('Avatar generation failed');\n return;\n }\n\n // Continue polling\n setTimeout(poll, interval);\n };\n\n poll();\n }\n}\n\n","// src/lib/api/wallet.ts\n// Framework-agnostic Wallet API\n\nimport { ZoApiClient } from './client';\nimport { logger } from '../utils/logger';\nimport type { BalanceResponse, TransactionsResponse, Transaction } from '../types/wallet';\n\n// $Zo Token Configuration\nconst ZO_TOKEN_CONFIG = {\n base: {\n rpc: 'https://mainnet.base.org',\n contractAddress: '0x111142c7ecaf39797b7865b82034269962142069', // $Zo token on Base\n decimals: 18,\n },\n avalanche: {\n rpc: 'https://api.avax.network/ext/bc/C/rpc',\n contractAddress: '0x111142c7ecaf39797b7865b82034269962142069', // $Zo token on Avalanche (update if different)\n decimals: 18,\n },\n};\n\n// ERC-20 balanceOf ABI (minimal)\nconst ERC20_BALANCE_ABI = '0x70a08231'; // balanceOf(address)\n\nexport class ZoWallet {\n private client: ZoApiClient;\n private cachedBalance: number = 0;\n private userWalletAddress: string | null = null;\n private network: 'base' | 'avalanche' = 'base';\n\n constructor(client: ZoApiClient) {\n this.client = client;\n }\n\n /**\n * Set the user's wallet address for on-chain queries\n */\n setWalletAddress(address: string, network: 'base' | 'avalanche' = 'base') {\n this.userWalletAddress = address;\n this.network = network;\n logger.debug(`Wallet address set: ${address} on ${network}`);\n }\n\n /**\n * Get wallet balance - tries on-chain first, then API fallback\n * @returns Wallet balance amount\n */\n async getBalance(): Promise<number> {\n // Try on-chain balance first if wallet address is set\n if (this.userWalletAddress) {\n try {\n const onChainBalance = await this.getOnChainBalance();\n if (onChainBalance !== null) {\n this.cachedBalance = onChainBalance;\n return onChainBalance;\n }\n } catch (error) {\n logger.warn('On-chain balance check failed, falling back to API:', error);\n }\n }\n\n // Fallback to API endpoints\n const apiBalance = await this.getBalanceFromAPI();\n if (apiBalance !== null) {\n return apiBalance;\n }\n\n // Return cached balance or 0\n logger.debug('Returning cached/default balance:', this.cachedBalance);\n return this.cachedBalance;\n }\n\n /**\n * Fetch balance directly from blockchain via JSON-RPC\n */\n private async getOnChainBalance(): Promise<number | null> {\n if (!this.userWalletAddress) {\n logger.warn('No wallet address set for on-chain query');\n return null;\n }\n\n const config = ZO_TOKEN_CONFIG[this.network];\n\n try {\n // Prepare the eth_call for balanceOf(address)\n const paddedAddress = this.userWalletAddress.toLowerCase().replace('0x', '').padStart(64, '0');\n const data = ERC20_BALANCE_ABI + paddedAddress;\n\n const response = await fetch(config.rpc, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'eth_call',\n params: [\n {\n to: config.contractAddress,\n data: data,\n },\n 'latest',\n ],\n }),\n });\n\n const result = await response.json();\n \n if (result.error) {\n logger.warn('RPC error:', result.error);\n return null;\n }\n\n // Parse the hex balance\n const rawBalance = BigInt(result.result || '0x0');\n const balance = Number(rawBalance) / Math.pow(10, config.decimals);\n \n logger.debug(`On-chain balance fetched: ${balance} $Zo`);\n return balance;\n } catch (error) {\n logger.warn('Failed to fetch on-chain balance:', error);\n return null;\n }\n }\n\n /**\n * Fetch balance from Zo API endpoints (tries multiple endpoints with fallback)\n */\n private async getBalanceFromAPI(): Promise<number | null> {\n const endpoints = [\n '/api/v1/web3/token/airdrops/summary',\n '/api/v1/wallet/balance',\n '/api/v1/profile/wallet',\n ];\n\n const errors: Array<{ endpoint: string; status?: number; message: string }> = [];\n\n for (const endpoint of endpoints) {\n try {\n const response = await this.client.axiosInstance.get<BalanceResponse>(endpoint);\n const balance = response.data?.data?.total_amount \n ?? (response.data as any)?.balance\n ?? (response.data as any)?.total_amount;\n \n if (typeof balance === 'number') {\n logger.debug(`Balance fetched from API ${endpoint}:`, balance);\n this.cachedBalance = balance;\n return balance;\n }\n } catch (error: any) {\n // Collect error info for debugging (skip 404s as they're expected)\n if (error?.response?.status !== 404) {\n errors.push({\n endpoint,\n status: error?.response?.status,\n message: error?.message || 'Unknown error',\n });\n }\n }\n }\n\n // Log aggregated errors if all endpoints failed\n if (errors.length > 0) {\n logger.warn('All balance API endpoints failed:', errors);\n }\n\n return null;\n }\n\n /**\n * Get transaction history\n * @param page - Optional page number for pagination\n * @returns Array of transactions\n */\n async getTransactions(page?: number): Promise<{\n transactions: Transaction[];\n next?: string;\n previous?: string;\n count: number;\n }> {\n const endpoints = [\n page ? `/api/v1/profile/completion-grants/claims?page=${page}` : '/api/v1/profile/completion-grants/claims',\n page ? `/api/v1/wallet/transactions?page=${page}` : '/api/v1/wallet/transactions',\n ];\n\n const errors: Array<{ endpoint: string; status?: number; message: string }> = [];\n\n for (const url of endpoints) {\n try {\n const response = await this.client.axiosInstance.get<TransactionsResponse>(url);\n // Handle multiple API response formats\n const data = (response.data?.data || response.data) as {\n results?: Transaction[];\n transactions?: Transaction[];\n next?: string;\n previous?: string;\n count?: number;\n };\n \n return {\n transactions: data?.results ?? data?.transactions ?? [],\n next: data?.next,\n previous: data?.previous,\n count: data?.count ?? 0,\n };\n } catch (error: any) {\n // Collect error info for debugging (skip 404s as they're expected)\n if (error?.response?.status !== 404) {\n errors.push({\n endpoint: url,\n status: error?.response?.status,\n message: error?.message || 'Unknown error',\n });\n }\n }\n }\n\n // Log aggregated errors if all endpoints failed\n if (errors.length > 0) {\n logger.warn('All transaction API endpoints failed:', errors);\n }\n\n // Return empty if all endpoints fail\n return {\n transactions: [],\n next: undefined,\n previous: undefined,\n count: 0,\n };\n }\n}\n","// ZoPassportSDK - Main SDK class\n// One-stop initialization for the entire Zo Passport experience\n\nimport { ZoApiClient, ZoPassportConfig } from './lib/api/client';\nimport { ZoAuth } from './lib/api/auth';\nimport { ZoProfile } from './lib/api/profile';\nimport { ZoAvatar } from './lib/api/avatar';\nimport { ZoWallet } from './lib/api/wallet';\nimport { LocalStorageAdapter, AsyncStorageAdapter, StorageAdapter, STORAGE_KEYS } from './lib/utils/storage';\nimport { logger } from './lib/utils/logger';\nimport type { ZoUser, ZoAuthResponse, Transaction } from './lib/types';\n\nexport interface ZoPassportSDKConfig extends ZoPassportConfig {\n /** Optional: Provide a custom storage adapter (default: LocalStorageAdapter) */\n storageAdapter?: StorageAdapter;\n /** Optional: Enable auto token refresh (default: true) */\n autoRefresh?: boolean;\n /** Optional: Token refresh interval in ms (default: 60000 = 1 minute) */\n refreshInterval?: number;\n /** Optional: Enable debug logging (default: false) */\n debug?: boolean;\n}\n\nexport class ZoPassportSDK {\n private client: ZoApiClient;\n private storage: StorageAdapter;\n private refreshTimer: ReturnType<typeof setTimeout> | null = null;\n private _readyPromise: Promise<void>;\n\n public auth: ZoAuth;\n public profile: ZoProfile;\n public avatar: ZoAvatar;\n public wallet: ZoWallet;\n\n private _user: ZoUser | null = null;\n private _isAuthenticated: boolean = false;\n\n constructor(config: ZoPassportSDKConfig) {\n // Configure debug logging\n if (config.debug) {\n logger.enable();\n logger.setLevel('debug');\n }\n\n // Initialize storage adapter\n this.storage = config.storageAdapter || new LocalStorageAdapter();\n\n // Initialize API client\n this.client = new ZoApiClient({\n ...config,\n storageAdapter: this.storage,\n });\n\n // Initialize API modules\n this.auth = new ZoAuth(this.client);\n this.profile = new ZoProfile(this.client);\n this.avatar = new ZoAvatar(this.client);\n this.wallet = new ZoWallet(this.client);\n\n // Start auto-refresh if enabled\n if (config.autoRefresh !== false) {\n this.startAutoRefresh(config.refreshInterval || 60000);\n }\n\n // Load existing session (store promise for ready() method)\n this._readyPromise = this.loadSession();\n \n logger.debug('SDK initialized with config:', { \n baseUrl: config.baseUrl, \n autoRefresh: config.autoRefresh !== false,\n });\n }\n\n /**\n * Wait for the SDK to be ready (session loaded from storage)\n * Use this if you need to check isAuthenticated immediately after construction\n */\n async ready(): Promise<void> {\n return this._readyPromise;\n }\n\n // =====================\n // Session Management\n // =====================\n\n private async loadSession(): Promise<void> {\n try {\n const userJson = await this.storage.getItem(STORAGE_KEYS.USER);\n const accessToken = await this.storage.getItem(STORAGE_KEYS.ACCESS_TOKEN);\n\n if (userJson && accessToken) {\n this._user = JSON.parse(userJson);\n this._isAuthenticated = true;\n }\n } catch (error) {\n logger.warn('Failed to load session:', error);\n }\n }\n\n private async saveSession(authResponse: ZoAuthResponse): Promise<void> {\n await this.storage.setItem(STORAGE_KEYS.ACCESS_TOKEN, authResponse.access_token);\n await this.storage.setItem(STORAGE_KEYS.REFRESH_TOKEN, authResponse.refresh_token);\n await this.storage.setItem(STORAGE_KEYS.TOKEN_EXPIRY, authResponse.access_token_expiry);\n await this.storage.setItem(STORAGE_KEYS.REFRESH_EXPIRY, authResponse.refresh_token_expiry);\n await this.storage.setItem(STORAGE_KEYS.USER, JSON.stringify(authResponse.user));\n await this.storage.setItem(STORAGE_KEYS.CLIENT_DEVICE_ID, authResponse.device_id || '');\n await this.storage.setItem(STORAGE_KEYS.CLIENT_DEVICE_SECRET, authResponse.device_secret || '');\n\n this._user = authResponse.user;\n this._isAuthenticated = true;\n }\n\n async clearSession(): Promise<void> {\n await this.storage.removeItem(STORAGE_KEYS.ACCESS_TOKEN);\n await this.storage.removeItem(STORAGE_KEYS.REFRESH_TOKEN);\n await this.storage.removeItem(STORAGE_KEYS.TOKEN_EXPIRY);\n await this.storage.removeItem(STORAGE_KEYS.REFRESH_EXPIRY);\n await this.storage.removeItem(STORAGE_KEYS.USER);\n await this.storage.removeItem(STORAGE_KEYS.CLIENT_DEVICE_ID);\n await this.storage.removeItem(STORAGE_KEYS.CLIENT_DEVICE_SECRET);\n\n this._user = null;\n this._isAuthenticated = false;\n }\n\n // =====================\n // Auto Token Refresh\n // =====================\n\n private startAutoRefresh(interval: number): void {\n this.refreshTimer = setInterval(async () => {\n await this.refreshTokenIfNeeded();\n }, interval);\n }\n\n private stopAutoRefresh(): void {\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer);\n this.refreshTimer = null;\n }\n }\n\n private async refreshTokenIfNeeded(): Promise<void> {\n const tokenExpiry = await this.storage.getItem(STORAGE_KEYS.TOKEN_EXPIRY);\n const refreshToken = await this.storage.getItem(STORAGE_KEYS.REFRESH_TOKEN);\n\n if (!tokenExpiry || !refreshToken) return;\n\n const expiryDate = new Date(tokenExpiry);\n const now = new Date();\n const twoMinutes = 2 * 60 * 1000;\n\n // Refresh if expiring within 2 minutes\n if (expiryDate.getTime() - now.getTime() < twoMinutes) {\n const result = await this.auth.refreshAccessToken(refreshToken);\n if (result.success && result.tokens) {\n await this.storage.setItem(STORAGE_KEYS.ACCESS_TOKEN, result.tokens.access);\n await this.storage.setItem(STORAGE_KEYS.REFRESH_TOKEN, result.tokens.refresh);\n await this.storage.setItem(STORAGE_KEYS.TOKEN_EXPIRY, result.tokens.access_expiry);\n await this.storage.setItem(STORAGE_KEYS.REFRESH_EXPIRY, result.tokens.refresh_expiry);\n }\n }\n }\n\n // =====================\n // Public API\n // =====================\n\n get user(): ZoUser | null {\n return this._user;\n }\n\n get isAuthenticated(): boolean {\n return this._isAuthenticated;\n }\n\n /**\n * Complete phone authentication flow\n */\n async loginWithPhone(\n countryCode: string,\n phoneNumber: string,\n otp: string\n ): Promise<{ success: boolean; user?: ZoUser; error?: string }> {\n const result = await this.auth.verifyOTP(countryCode, phoneNumber, otp);\n\n if (result.success && result.data) {\n await this.saveSession(result.data);\n \n // Set wallet address for on-chain balance queries\n if (result.data.user?.wallet_address) {\n this.wallet.setWalletAddress(result.data.user.wallet_address, 'base');\n }\n \n return { success: true, user: result.data.user };\n }\n\n return { success: false, error: result.error };\n }\n\n /**\n * Logout and clear session\n */\n async logout(): Promise<void> {\n await this.clearSession();\n this.stopAutoRefresh();\n }\n\n /**\n * Get current user profile\n */\n async getProfile(): Promise<ZoUser | null> {\n const accessToken = await this.storage.getItem(STORAGE_KEYS.ACCESS_TOKEN);\n if (!accessToken) return null;\n\n const result = await this.profile.getProfile(accessToken);\n if (result.success && result.profile) {\n this._user = result.profile as ZoUser;\n await this.storage.setItem(STORAGE_KEYS.USER, JSON.stringify(result.profile));\n \n // Set wallet address for on-chain balance queries\n if (result.profile.wallet_address) {\n this.wallet.setWalletAddress(result.profile.wallet_address, 'base');\n }\n \n return result.profile as ZoUser;\n }\n\n return null;\n }\n\n /**\n * Update user profile\n */\n async updateProfile(updates: {\n first_name?: string;\n last_name?: string;\n bio?: string;\n date_of_birth?: string;\n place_name?: string;\n body_type?: 'bro' | 'bae';\n }): Promise<{ success: boolean; profile?: ZoUser; error?: string }> {\n const accessToken = await this.storage.getItem(STORAGE_KEYS.ACCESS_TOKEN);\n if (!accessToken) return { success: false, error: 'Not authenticated' };\n\n const result = await this.profile.updateProfile(accessToken, updates);\n if (result.success && result.profile) {\n this._user = result.profile as ZoUser;\n await this.storage.setItem(STORAGE_KEYS.USER, JSON.stringify(result.profile));\n return { success: true, profile: result.profile as ZoUser };\n }\n\n return { success: false, error: result.error };\n }\n\n /**\n * Generate avatar\n */\n async generateAvatar(bodyType: 'bro' | 'bae'): Promise<{\n success: boolean;\n avatarUrl?: string;\n error?: string;\n }> {\n const accessToken = await this.storage.getItem(STORAGE_KEYS.ACCESS_TOKEN);\n if (!accessToken) return { success: false, error: 'Not authenticated' };\n\n // Start generation\n const startResult = await this.avatar.generateAvatar(accessToken, bodyType);\n if (!startResult.success || !startResult.task_id) {\n return { success: false, error: startResult.error };\n }\n\n // Poll for completion\n return new Promise((resolve) => {\n this.avatar.pollAvatarStatus(accessToken, startResult.task_id!, {\n onComplete: (avatarUrl) => {\n resolve({ success: true, avatarUrl });\n },\n onError: (error) => {\n resolve({ success: false, error });\n },\n });\n });\n }\n\n /**\n * Get wallet balance\n */\n async getWalletBalance(): Promise<number> {\n return this.wallet.getBalance();\n }\n\n /**\n * Get wallet transactions\n */\n async getWalletTransactions(page?: number): Promise<{\n transactions: Transaction[];\n next?: string;\n previous?: string;\n count: number;\n }> {\n return this.wallet.getTransactions(page);\n }\n\n /**\n * Cleanup\n */\n destroy(): void {\n this.stopAutoRefresh();\n }\n}\n\n","// src/components/ZoProgressRing.tsx\n// Circular progress ring component\n\nimport React from 'react';\n\nexport interface ZoProgressRingProps {\n /** Progress percentage (0-100) */\n progress: number;\n /** Size in pixels (default: 140) */\n size?: number;\n /** Stroke width in pixels (default: 4) */\n strokeWidth?: number;\n /** Primary stroke color (default: #FFFFFF) */\n primaryColor?: string;\n /** Secondary/background stroke color (default: rgba(255,255,255,0.2)) */\n secondaryColor?: string;\n}\n\nexport const ZoProgressRing: React.FC<ZoProgressRingProps> = ({\n progress,\n size = 140,\n strokeWidth = 4,\n primaryColor = '#FFFFFF',\n secondaryColor = 'rgba(255,255,255,0.2)',\n}) => {\n const radius = (size - strokeWidth) / 2;\n const circumference = radius * 2 * Math.PI;\n const strokeDashoffset = circumference - (progress / 100) * circumference;\n\n return (\n <svg width={size} height={size} style={{ transform: 'rotate(-90deg)' }}>\n {/* Background circle */}\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n strokeWidth={strokeWidth}\n fill=\"none\"\n stroke={secondaryColor}\n />\n {/* Progress circle */}\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n stroke={primaryColor}\n strokeWidth={strokeWidth}\n fill=\"none\"\n strokeDasharray={circumference}\n strokeDashoffset={strokeDashoffset}\n strokeLinecap=\"round\"\n style={{ transition: 'stroke-dashoffset 0.5s ease-in-out' }}\n />\n </svg>\n );\n};\n\n","// src/components/FounderBadge.tsx\n// Founder badge SVG icon\n\nimport React from 'react';\n\nexport interface FounderBadgeProps {\n /** Size in pixels (default: 32) */\n size?: number;\n}\n\nexport const FounderBadge: React.FC<FounderBadgeProps> = ({ size = 32 }) => (\n <svg width={size} height={size} viewBox=\"0 0 28 28\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12.0117 3.15234C13.1449 2.14828 14.8551 2.14828 15.9883 3.15234L16.0996 3.25684L17.7715 4.89453L20.1123 4.91895L20.2646 4.92383C21.7758 5.01516 22.9848 6.22423 23.0762 7.73535L23.0811 7.8877L23.1045 10.2275L24.7432 11.9004L24.8477 12.0117C25.8517 13.1449 25.8517 14.8551 24.8477 15.9883L24.7432 16.0996L23.1045 17.7715L23.0811 20.1123C23.0646 21.6938 21.8262 22.9818 20.2646 23.0762L20.1123 23.0811L17.7715 23.1045L16.0996 24.7432C14.9697 25.8498 13.1826 25.8852 12.0117 24.8477L11.9004 24.7432L10.2275 23.1045L7.8877 23.0811C6.30625 23.0646 5.01821 21.8262 4.92383 20.2646L4.91895 20.1123L4.89453 17.7715L3.25684 16.0996C2.11446 14.9333 2.11446 13.0667 3.25684 11.9004L4.89453 10.2275L4.91895 7.8877L4.92383 7.73535C5.01821 6.17382 6.30624 4.93536 7.8877 4.91895L10.2275 4.89453L11.9004 3.25684L12.0117 3.15234Z\"\n fill=\"#FF2F8E\"\n stroke=\"#111111\"\n strokeWidth=\"4\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M13.5008 16.1741H15.8997C16.4443 16.1741 16.8858 16.6156 16.8858 17.1602C16.8858 17.7048 16.4443 18.1463 15.8997 18.1463H12.2286C11.4558 18.1463 10.8293 17.5199 10.8293 16.7471C10.8293 16.4219 10.9425 16.1069 11.1495 15.8562L14.0743 12.3137H11.8434C11.2988 12.3137 10.8573 11.8722 10.8573 11.3276C10.8573 10.783 11.2988 10.3415 11.8434 10.3415H15.4226C16.1921 10.3415 16.8158 10.9652 16.8158 11.7347C16.8158 12.0634 16.6996 12.3816 16.4876 12.6329L13.5008 16.1741Z\"\n fill=\"white\"\n />\n </svg>\n);\n\n","// src/components/ZoAvatar.tsx\n// Avatar display component with fallback\n\nimport React, { useState } from 'react';\n\nexport interface ZoAvatarProps {\n /** Avatar image URL */\n src?: string;\n /** User name (for alt text and fallback) */\n name?: string;\n /** Size in pixels (default: 120) */\n size?: number;\n /** Fallback image URL */\n fallbackUrl?: string;\n /** Additional CSS class */\n className?: string;\n}\n\n// Default fallback avatar\nconst DEFAULT_FALLBACK = '/images/rank1.jpeg';\n\nexport const ZoAvatar: React.FC<ZoAvatarProps> = ({\n src,\n name = 'User',\n size = 120,\n fallbackUrl = DEFAULT_FALLBACK,\n className = '',\n}) => {\n const [imgSrc, setImgSrc] = useState(src || fallbackUrl);\n const [hasError, setHasError] = useState(false);\n\n const handleError = () => {\n if (!hasError) {\n setHasError(true);\n setImgSrc(fallbackUrl);\n }\n };\n\n // Generate initials for text fallback\n const initials = name\n .split(' ')\n .map(n => n[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n\n return (\n <div\n className={`zo-avatar ${className}`}\n style={{\n width: size,\n height: size,\n borderRadius: '50%',\n overflow: 'hidden',\n backgroundColor: '#1a1a1a',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n {imgSrc ? (\n <img\n src={imgSrc}\n alt={name}\n onError={handleError}\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n }}\n />\n ) : (\n <span\n style={{\n fontSize: size * 0.4,\n fontWeight: 700,\n color: '#ffffff',\n fontFamily: 'Rubik, system-ui, sans-serif',\n }}\n >\n {initials}\n </span>\n )}\n </div>\n );\n};\n\n","// src/components/ZoPassportCard.tsx\n// Leather passport card component\n\nimport React from 'react';\nimport { ZoProgressRing } from './ZoProgressRing';\nimport { FounderBadge } from './FounderBadge';\nimport { ZoAvatar } from './ZoAvatar';\n\n// CDN URLs for passport backgrounds\nconst FOUNDER_BG = 'https://proxy.cdn.zo.xyz/gallery/media/images/a1659b07-94f0-4490-9b3c-3366715d9717_20250515053726.png';\nconst CITIZEN_BG = 'https://proxy.cdn.zo.xyz/gallery/media/images/bda9da5a-eefe-411d-8d90-667c80024463_20250515053805.png';\n\nexport interface ZoPassportCardProps {\n /** User profile data */\n profile: {\n avatar?: string;\n name?: string;\n isFounder?: boolean;\n };\n /** Profile completion */\n completion: {\n done: number;\n total: number;\n };\n /** Additional CSS class */\n className?: string;\n /** Optional: Override founder background URL */\n founderBgUrl?: string;\n /** Optional: Override citizen background URL */\n citizenBgUrl?: string;\n /** Optional: Default avatar fallback URL */\n defaultAvatarUrl?: string;\n}\n\nexport const ZoPassportCard: React.FC<ZoPassportCardProps> = ({\n profile,\n completion,\n className = '',\n founderBgUrl = FOUNDER_BG,\n citizenBgUrl = CITIZEN_BG,\n defaultAvatarUrl = '/images/rank1.jpeg',\n}) => {\n const isFounder = profile?.isFounder || false;\n const name = profile?.name || 'New Citizen';\n const avatar = profile?.avatar || defaultAvatarUrl;\n const done = completion?.done || 0;\n const total = completion?.total || 1;\n const progress = Math.min(100, Math.max(0, (done / total) * 100));\n\n const bgImage = isFounder ? founderBgUrl : citizenBgUrl;\n const textColor = isFounder ? 'white' : '#111111';\n const shadowStyle = isFounder\n ? '0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 8px 10px -6px rgba(0, 0, 0, 0.1)'\n : '0 20px 25px -5px rgba(241, 86, 63, 0.5), 0 8px 10px -6px rgba(241, 86, 63, 0.1)';\n\n return (\n <div\n className={`zo-passport-card ${className}`}\n style={{\n position: 'relative',\n width: '234px',\n height: '300px',\n borderRadius: '0 20px 20px 0',\n overflow: 'hidden',\n fontFamily: 'Rubik, system-ui, sans-serif',\n boxShadow: shadowStyle,\n }}\n >\n {/* Background Image */}\n <div style={{ position: 'absolute', inset: 0 }}>\n <img\n src={bgImage}\n alt=\"Passport Background\"\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n }}\n />\n </div>\n\n {/* Circular Progress - Centered */}\n <div\n style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n top: '-10px',\n }}\n >\n <ZoProgressRing\n progress={progress}\n size={140}\n strokeWidth={4}\n primaryColor={isFounder ? '#FFFFFF' : '#111111'}\n secondaryColor={isFounder ? 'rgba(255,255,255,0.2)' : 'rgba(0,0,0,0.1)'}\n />\n </div>\n\n {/* Avatar - Centered */}\n <div\n style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n top: '-10px',\n }}\n >\n <div\n style={{\n width: '120px',\n height: '120px',\n borderRadius: '50%',\n overflow: 'hidden',\n }}\n >\n <ZoAvatar src={avatar} name={name} size={120} />\n </div>\n\n {/* Founder Badge */}\n {isFounder && (\n <div\n style={{\n position: 'absolute',\n bottom: '84px',\n right: '60px',\n }}\n >\n <FounderBadge size={32} />\n </div>\n )}\n </div>\n\n {/* Text Container - Bottom */}\n <div\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n bottom: '16px',\n textAlign: 'center',\n padding: '0 16px',\n display: 'flex',\n flexDirection: 'column',\n gap: '4px',\n }}\n >\n <p\n style={{\n margin: 0,\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: textColor,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {name}\n </p>\n <p\n style={{\n margin: 0,\n fontSize: '10px',\n lineHeight: '14px',\n letterSpacing: '0.05em',\n textTransform: 'uppercase',\n color: textColor,\n opacity: 0.7,\n }}\n >\n {isFounder ? 'Founder of Zo World' : 'Citizen of Zo World'}\n </p>\n </div>\n </div>\n );\n};\n\n","// src/components/ZoPassportPage.tsx\n// Full Passport Page with all profile information - Mobile Responsive\n\nimport React, { useEffect } from 'react';\nimport { ZoPassportCard } from './ZoPassportCard';\nimport { WalletCard } from './wallet'; // Uses WalletCardWeb (web-compatible)\nimport type { ZoUser } from '../lib/types';\nimport { CULTURE_STICKERS } from '../../assets';\n\n// Extended culture sticker mapping with aliases for flexible matching\nconst CULTURE_STICKER_MAP: Record<string, string> = {\n // Base mappings from CULTURE_STICKERS\n ...CULTURE_STICKERS,\n // Aliases for common variations\n 'game': CULTURE_STICKERS.gaming,\n 'games': CULTURE_STICKERS.gaming,\n 'sport': CULTURE_STICKERS.sports,\n // Full name variants (for when API returns full names)\n 'travel & adventure': CULTURE_STICKERS.travel,\n 'science & technology': CULTURE_STICKERS.tech,\n 'music & entertainment': CULTURE_STICKERS.music,\n 'health & fitness': CULTURE_STICKERS.fitness,\n 'literature & stories': CULTURE_STICKERS.literature,\n 'television & cinema': CULTURE_STICKERS.cinema,\n 'nature & wildlife': CULTURE_STICKERS.nature,\n 'home & lifestyle': CULTURE_STICKERS.lifestyle,\n 'stories & journal': CULTURE_STICKERS.stories,\n // Special cultures\n 'follow-your-heart': '/cultural-stickers/FollowYourHeart.png',\n 'followyourheart': '/cultural-stickers/FollowYourHeart.png',\n 'follow your heart': '/cultural-stickers/FollowYourHeart.png',\n 'law & order': CULTURE_STICKERS.law,\n};\n\n// Culture can be a string (culture key) or an object with key/name/icon\ntype CultureItem = string | { key?: string; name?: string; icon?: string };\n\nconst getCultureSticker = (culture: CultureItem): string => {\n // Handle string cultures (just the key)\n if (typeof culture === 'string') {\n const keyMatch = CULTURE_STICKER_MAP[culture.toLowerCase()];\n if (keyMatch) return keyMatch;\n return '/cultural-stickers/FollowYourHeart.png';\n }\n // Handle object cultures\n if (culture.key) {\n const keyMatch = CULTURE_STICKER_MAP[culture.key.toLowerCase()];\n if (keyMatch) return keyMatch;\n }\n if (culture.name) {\n const nameMatch = CULTURE_STICKER_MAP[culture.name.toLowerCase()];\n if (nameMatch) return nameMatch;\n const nameLower = culture.name.toLowerCase();\n for (const [mapKey, path] of Object.entries(CULTURE_STICKER_MAP)) {\n if (nameLower.includes(mapKey) || mapKey.includes(nameLower)) {\n return path;\n }\n }\n }\n if (culture.icon && !culture.icon.includes('proxy.cdn.zo.xyz/profile/culture')) {\n return culture.icon;\n }\n return '/cultural-stickers/FollowYourHeart.png';\n};\n\nconst getCultureName = (culture: CultureItem): string => {\n if (typeof culture === 'string') return culture;\n return culture.name || culture.key || 'Culture';\n};\n\nconst getCultureKey = (culture: CultureItem): string => {\n if (typeof culture === 'string') return culture;\n return culture.key || culture.name || '';\n};\n\nexport interface ZoPassportPageProps {\n user: ZoUser | null;\n balance?: number;\n completion?: { done: number; total: number };\n walletOpen?: boolean;\n onWalletToggle?: () => void;\n onRemoveCulture?: (cultureKey: string) => void;\n}\n\nconst formatDate = (dateStr?: string | null): string => {\n if (!dateStr) return 'Not set';\n try {\n const date = new Date(dateStr);\n return date.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });\n } catch {\n return dateStr;\n }\n};\n\nconst formatPhone = (phone?: string, countryCode?: string): string => {\n if (!phone) return 'Not set';\n return countryCode ? `${countryCode}${phone}` : phone;\n};\n\nimport { injectStyles } from '../lib/utils/styles';\n\nconst STYLE_ID = 'zo-passport-responsive-styles';\nconst CSS = `\n .zo-passport-container {\n width: 100%;\n min-height: auto;\n background: #000000;\n color: #FFFFFF;\n font-family: 'Rubik', system-ui, sans-serif;\n padding: 16px;\n padding-bottom: 60px;\n box-sizing: border-box;\n }\n \n .zo-passport-header {\n margin-bottom: 24px;\n text-align: center;\n }\n \n .zo-passport-title {\n font-size: 24px;\n font-weight: 700;\n margin: 0;\n font-family: 'Syne', system-ui, sans-serif;\n }\n \n .zo-passport-subtitle {\n font-size: 12px;\n color: rgba(255, 255, 255, 0.6);\n margin: 4px 0 0 0;\n }\n \n .zo-passport-grid {\n display: flex;\n flex-direction: column;\n gap: 24px;\n max-width: 1200px;\n margin: 0 auto;\n }\n \n .zo-passport-card-section {\n display: flex;\n justify-content: center;\n }\n \n .zo-passport-section {\n background: rgba(255, 255, 255, 0.03);\n border-radius: 16px;\n padding: 20px;\n }\n \n .zo-passport-section-title {\n font-size: 14px;\n font-weight: 600;\n margin: 0 0 16px 0;\n letter-spacing: 0.02em;\n color: rgba(255, 255, 255, 0.9);\n }\n \n .zo-passport-info-list {\n display: flex;\n flex-direction: column;\n gap: 16px;\n }\n \n .zo-passport-info-row {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n }\n \n .zo-passport-info-icon {\n font-size: 16px;\n width: 20px;\n text-align: center;\n flex-shrink: 0;\n }\n \n .zo-passport-info-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n }\n \n .zo-passport-info-label {\n font-size: 10px;\n color: rgba(255, 255, 255, 0.5);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n \n .zo-passport-info-value {\n font-size: 13px;\n color: #FFFFFF;\n word-break: break-word;\n }\n \n .zo-passport-wallet-wrapper {\n margin-bottom: 16px;\n }\n \n .zo-passport-cultures {\n background: rgba(255, 255, 255, 0.05);\n border: 1px solid rgba(255, 255, 255, 0.1);\n border-radius: 12px;\n padding: 16px;\n }\n \n .zo-passport-cultures-header {\n margin-bottom: 12px;\n }\n \n .zo-passport-cultures-title {\n font-size: 12px;\n color: rgba(255, 255, 255, 0.7);\n }\n \n .zo-passport-culture-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n }\n \n .zo-passport-culture-tag {\n display: flex;\n align-items: center;\n gap: 6px;\n background: rgba(255, 255, 255, 0.08);\n border: 1px solid rgba(255, 255, 255, 0.15);\n border-radius: 20px;\n padding: 6px 10px;\n }\n \n .zo-passport-culture-sticker {\n width: 16px;\n height: 16px;\n object-fit: contain;\n }\n \n .zo-passport-culture-name {\n font-size: 11px;\n color: #FFFFFF;\n font-weight: 500;\n }\n \n .zo-passport-culture-remove {\n background: none;\n border: none;\n color: rgba(255, 255, 255, 0.5);\n font-size: 14px;\n cursor: pointer;\n padding: 0;\n line-height: 1;\n margin-left: 2px;\n }\n \n .zo-passport-loading {\n color: rgba(255, 255, 255, 0.6);\n font-size: 14px;\n text-align: center;\n padding: 40px;\n }\n \n /* Tablet (768px+) */\n @media (min-width: 768px) {\n .zo-passport-container {\n padding: 24px;\n }\n \n .zo-passport-header {\n text-align: left;\n margin-bottom: 32px;\n }\n \n .zo-passport-title {\n font-size: 28px;\n }\n \n .zo-passport-subtitle {\n font-size: 14px;\n }\n \n .zo-passport-grid {\n display: grid;\n grid-template-columns: auto 1fr;\n gap: 32px;\n }\n \n .zo-passport-card-section {\n justify-content: flex-start;\n }\n \n .zo-passport-content-columns {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 24px;\n }\n \n .zo-passport-section-title {\n font-size: 15px;\n margin-bottom: 20px;\n }\n \n .zo-passport-info-icon {\n font-size: 18px;\n width: 24px;\n }\n \n .zo-passport-info-label {\n font-size: 11px;\n }\n \n .zo-passport-info-value {\n font-size: 14px;\n }\n \n .zo-passport-culture-sticker {\n width: 18px;\n height: 18px;\n }\n \n .zo-passport-culture-name {\n font-size: 12px;\n }\n }\n \n /* Desktop (1024px+) */\n @media (min-width: 1024px) {\n .zo-passport-container {\n padding: 40px;\n }\n \n .zo-passport-header {\n margin-bottom: 40px;\n }\n \n .zo-passport-title {\n font-size: 32px;\n }\n \n .zo-passport-grid {\n grid-template-columns: auto 1fr 1fr;\n gap: 48px;\n }\n \n .zo-passport-content-columns {\n display: contents;\n }\n \n .zo-passport-section {\n padding: 24px;\n }\n \n .zo-passport-info-list {\n gap: 20px;\n }\n \n .zo-passport-culture-sticker {\n width: 20px;\n height: 20px;\n }\n \n .zo-passport-culture-name {\n font-size: 13px;\n }\n }\n`;\n\nexport const ZoPassportPage: React.FC<ZoPassportPageProps> = ({\n user,\n balance = 0,\n completion = { done: 0, total: 10 },\n walletOpen = false,\n onWalletToggle,\n onRemoveCulture,\n}) => {\n useEffect(() => {\n const cleanup = injectStyles(STYLE_ID, CSS);\n return cleanup;\n }, []);\n\n if (!user) {\n return (\n <div className=\"zo-passport-container\">\n <p className=\"zo-passport-loading\">Loading passport...</p>\n </div>\n );\n }\n\n const isFounder = user.membership === 'founder';\n const fullName = [user.first_name, user.last_name].filter(Boolean).join(' ') || 'Not set';\n const cultures = user.cultures || [];\n\n return (\n <div className=\"zo-passport-container\">\n {/* Header */}\n <div className=\"zo-passport-header\">\n <h1 className=\"zo-passport-title\">Zo Passport</h1>\n <p className=\"zo-passport-subtitle\">Your identity in Zo World</p>\n </div>\n\n {/* Main Content Grid */}\n <div className=\"zo-passport-grid\">\n {/* Passport Card */}\n <div className=\"zo-passport-card-section\">\n <ZoPassportCard\n profile={{\n avatar: user.avatar?.image || user.pfp_image,\n name: user.first_name || 'Citizen',\n isFounder,\n }}\n completion={completion}\n />\n </div>\n\n {/* Content Columns */}\n <div className=\"zo-passport-content-columns\">\n {/* General Information */}\n <div className=\"zo-passport-section\">\n <h2 className=\"zo-passport-section-title\">General Information</h2>\n <div className=\"zo-passport-info-list\">\n <InfoRow icon=\"✏️\" label=\"Full Name\" value={fullName} />\n <InfoRow icon=\"👤\" label=\"Short Bio\" value={user.bio || 'Not set'} />\n <InfoRow icon=\"🎂\" label=\"Born on\" value={formatDate(user.date_of_birth)} />\n <InfoRow icon=\"🧬\" label=\"Body Type\" value={user.body_type ? user.body_type.charAt(0).toUpperCase() + user.body_type.slice(1) : 'Not set'} />\n <InfoRow icon=\"📍\" label=\"Location\" value={user.place_name || 'Not set'} />\n </div>\n\n {/* Communication */}\n <h2 className=\"zo-passport-section-title\" style={{ marginTop: 24 }}>Communication</h2>\n <div className=\"zo-passport-info-list\">\n <InfoRow icon=\"📧\" label=\"Email\" value={user.email_address || 'Not set'} />\n <InfoRow icon=\"📱\" label=\"Phone\" value={formatPhone(user.mobile_number)} />\n </div>\n </div>\n\n {/* Wallet & Cultures */}\n <div className=\"zo-passport-section\">\n <h2 className=\"zo-passport-section-title\">For the Culture</h2>\n \n {/* Wallet Card */}\n <div className=\"zo-passport-wallet-wrapper\">\n <WalletCard\n balance={balance}\n user={{\n avatar: user.avatar?.image ? { image: user.avatar.image } : undefined,\n first_name: user.first_name || 'Citizen',\n nickname: user.first_name,\n wallet_address: user.wallet_address || '',\n }}\n isOpen={walletOpen}\n onToggle={onWalletToggle}\n />\n </div>\n\n {/* Cultures */}\n {cultures.length > 0 && (\n <div className=\"zo-passport-cultures\">\n <div className=\"zo-passport-cultures-header\">\n <span className=\"zo-passport-cultures-title\">\n Selected Cultures ({cultures.length})\n </span>\n </div>\n <div className=\"zo-passport-culture-tags\">\n {cultures.map((culture, index) => (\n <CultureTag\n key={getCultureKey(culture) || index}\n stickerUrl={getCultureSticker(culture)}\n name={getCultureName(culture)}\n onRemove={onRemoveCulture ? () => onRemoveCulture(getCultureKey(culture)) : undefined}\n />\n ))}\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n};\n\n// Info Row Component\nconst InfoRow: React.FC<{ icon: string; label: string; value: string }> = ({ icon, label, value }) => (\n <div className=\"zo-passport-info-row\">\n <span className=\"zo-passport-info-icon\">{icon}</span>\n <div className=\"zo-passport-info-content\">\n <span className=\"zo-passport-info-label\">{label}</span>\n <span className=\"zo-passport-info-value\">{value}</span>\n </div>\n </div>\n);\n\n// Culture Tag Component\nconst CultureTag: React.FC<{ stickerUrl: string; name: string; onRemove?: () => void }> = ({ stickerUrl, name, onRemove }) => (\n <div className=\"zo-passport-culture-tag\">\n <img \n src={stickerUrl} \n alt={name} \n className=\"zo-passport-culture-sticker\"\n onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}\n />\n <span className=\"zo-passport-culture-name\">{name}</span>\n {onRemove && (\n <button className=\"zo-passport-culture-remove\" onClick={onRemove}>×</button>\n )}\n </div>\n);\n\nexport default ZoPassportPage;\n","// WalletCardWeb.tsx - Web-compatible Wallet Card Component\n// Uses CSS and DOM APIs instead of React Native primitives\n\nimport React, { useEffect, memo } from 'react';\nimport { formatBalance, formatWalletAddress, formatNickname } from '../../lib/utils/wallet';\nimport { injectStyles } from '../../lib/utils/styles';\nimport type { WalletCardProps } from '../../lib/types/wallet';\n\n// Zo coin asset\nconst ZO_COIN_URL = '/zo-coin.gif';\n\nconst STYLE_ID = 'zo-wallet-card-web-styles';\nconst CSS = `\n .zo-wallet-card-web {\n position: relative;\n width: 100%;\n max-width: 320px;\n aspect-ratio: 1.6;\n border-radius: 16px;\n overflow: hidden;\n background: linear-gradient(145deg, #1a1a1a 0%, #0d0d0d 100%);\n border: 1px solid rgba(255,255,255,0.1);\n box-shadow: 0 8px 32px rgba(0,0,0,0.4);\n cursor: pointer;\n transition: transform 0.3s ease, box-shadow 0.3s ease;\n font-family: 'Rubik', system-ui, sans-serif;\n }\n\n .zo-wallet-card-web:hover {\n transform: translateY(-2px);\n box-shadow: 0 12px 40px rgba(0,0,0,0.5);\n }\n\n .zo-wallet-card-web.is-open {\n transform: translateY(-20px);\n }\n\n .zo-wallet-card-web-inner {\n position: relative;\n height: 100%;\n display: flex;\n flex-direction: column;\n padding: 20px;\n z-index: 1;\n }\n\n .zo-wallet-card-web-shine {\n position: absolute;\n top: 0;\n left: -100%;\n width: 50%;\n height: 100%;\n background: linear-gradient(\n 90deg,\n transparent,\n rgba(255,255,255,0.05),\n transparent\n );\n animation: zo-wallet-shine 3s ease-in-out infinite;\n pointer-events: none;\n }\n\n @keyframes zo-wallet-shine {\n 0% { left: -100%; }\n 50% { left: 100%; }\n 100% { left: 100%; }\n }\n\n .zo-wallet-card-web-balance-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .zo-wallet-card-web-balance-wrapper {\n display: flex;\n align-items: baseline;\n gap: 6px;\n }\n\n .zo-wallet-card-web-balance {\n font-size: 28px;\n font-weight: 700;\n color: #fff;\n margin: 0;\n }\n\n .zo-wallet-card-web-currency {\n font-size: 14px;\n color: rgba(255,255,255,0.5);\n }\n\n .zo-wallet-card-web-coin {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n }\n\n .zo-wallet-card-web-spacer {\n flex: 1;\n }\n\n .zo-wallet-card-web-user {\n display: flex;\n align-items: center;\n gap: 12px;\n padding-top: 12px;\n border-top: 1px solid rgba(255,255,255,0.08);\n }\n\n .zo-wallet-card-web-avatar {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n object-fit: cover;\n border: 2px solid rgba(255,255,255,0.15);\n }\n\n .zo-wallet-card-web-avatar-placeholder {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: linear-gradient(135deg, #333 0%, #222 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 14px;\n color: rgba(255,255,255,0.5);\n border: 2px solid rgba(255,255,255,0.15);\n }\n\n .zo-wallet-card-web-user-info {\n flex: 1;\n min-width: 0;\n }\n\n .zo-wallet-card-web-username {\n font-size: 14px;\n font-weight: 600;\n color: #fff;\n margin: 0 0 2px 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .zo-wallet-card-web-address {\n font-size: 11px;\n color: rgba(255,255,255,0.4);\n margin: 0;\n font-family: 'SF Mono', Monaco, monospace;\n }\n\n .zo-wallet-card-web-loading {\n opacity: 0.5;\n }\n\n .zo-wallet-card-web-cover {\n position: absolute;\n inset: 0;\n background: linear-gradient(145deg, #2d2d2d 0%, #1a1a1a 100%);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: opacity 0.3s ease;\n z-index: 2;\n }\n\n .zo-wallet-card-web.is-open .zo-wallet-card-web-cover {\n opacity: 0;\n pointer-events: none;\n }\n\n .zo-wallet-card-web-cover-text {\n font-size: 14px;\n color: rgba(255,255,255,0.6);\n font-weight: 500;\n }\n\n .zo-wallet-card-web-stitch {\n position: absolute;\n inset: 6px;\n border: 1px dashed rgba(255,255,255,0.15);\n border-radius: 12px;\n pointer-events: none;\n }\n`;\n\nexport const WalletCardWeb: React.FC<WalletCardProps> = memo(({\n balance,\n user,\n isOpen = false,\n onToggle,\n isLoading = false,\n}) => {\n useEffect(() => {\n const cleanup = injectStyles(STYLE_ID, CSS);\n return cleanup;\n }, []);\n\n const displayName = user.nickname\n ? formatNickname(user.nickname)\n : user.first_name || 'You';\n\n const walletText = `${user.first_name || 'Your'}'s wallet`;\n\n return (\n <div\n className={`zo-wallet-card-web ${isOpen ? 'is-open' : ''} ${isLoading ? 'zo-wallet-card-web-loading' : ''}`}\n onClick={onToggle}\n >\n {/* Shine Effect */}\n <div className=\"zo-wallet-card-web-shine\" />\n \n {/* Stitch Effect */}\n <div className=\"zo-wallet-card-web-stitch\" />\n\n {/* Card Content */}\n <div className=\"zo-wallet-card-web-inner\">\n {/* Balance Row */}\n <div className=\"zo-wallet-card-web-balance-row\">\n <div className=\"zo-wallet-card-web-balance-wrapper\">\n <p className=\"zo-wallet-card-web-balance\">\n {isLoading ? '...' : formatBalance(balance)}\n </p>\n <span className=\"zo-wallet-card-web-currency\">$Zo</span>\n </div>\n <img\n src={ZO_COIN_URL}\n alt=\"Zo Coin\"\n className=\"zo-wallet-card-web-coin\"\n />\n </div>\n\n <div className=\"zo-wallet-card-web-spacer\" />\n\n {/* User Info */}\n <div className=\"zo-wallet-card-web-user\">\n {user.avatar?.image ? (\n <img\n src={user.avatar.image}\n alt={displayName}\n className=\"zo-wallet-card-web-avatar\"\n />\n ) : (\n <div className=\"zo-wallet-card-web-avatar-placeholder\">\n {(user.first_name?.[0] || 'Z').toUpperCase()}\n </div>\n )}\n <div className=\"zo-wallet-card-web-user-info\">\n <p className=\"zo-wallet-card-web-username\">{displayName}</p>\n <p className=\"zo-wallet-card-web-address\">\n {formatWalletAddress(user.wallet_address || '')}\n </p>\n </div>\n </div>\n </div>\n\n {/* Cover (shown when closed) */}\n <div className=\"zo-wallet-card-web-cover\">\n <span className=\"zo-wallet-card-web-cover-text\">{walletText}</span>\n </div>\n </div>\n );\n});\n\nWalletCardWeb.displayName = 'WalletCardWeb';\n\nexport default WalletCardWeb;\n\n","// Wallet Formatting Utilities\n// Framework-agnostic pure functions for wallet data formatting\n\n/**\n * Format balance number with commas\n * @param balance - Raw balance number\n * @returns Formatted string (e.g., \"1,234.56\")\n */\nexport const formatBalance = (balance: number): string => {\n if (balance === 0) return '0';\n\n const formatted = balance.toLocaleString('en-US', {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n });\n\n return formatted;\n};\n\n/**\n * Format balance for short display\n * @param balance - Raw balance number\n * @returns Shortened string (e.g., \"1.2K\", \"1.5M\")\n */\nexport const formatBalanceShort = (balance: number): string => {\n if (balance === 0) return '0';\n if (balance < 1000) return formatBalance(balance);\n if (balance < 1000000) return `${(balance / 1000).toFixed(1)}K`;\n return `${(balance / 1000000).toFixed(1)}M`;\n};\n\n/**\n * Format wallet address to short form\n * @param address - Full wallet address\n * @returns Shortened address (e.g., \"0x12...34ab\")\n */\nexport const formatWalletAddress = (address: string): string => {\n if (!address || address.length < 8) return address;\n return `${address.slice(0, 4)}...${address.slice(-4)}`;\n};\n\n/**\n * Format nickname with @ prefix\n * @param nickname - User nickname\n * @returns Formatted nickname (e.g., \"@john\")\n */\nexport const formatNickname = (nickname: string): string => {\n if (!nickname) return '';\n return nickname.startsWith('@') ? nickname : `@${nickname}`;\n};\n\n/**\n * Format transaction amount\n * @param amount - Transaction amount\n * @param action - deposit or spend\n * @returns Formatted amount with +/- prefix\n */\nexport const formatTransactionAmount = (\n amount: number,\n action: 'deposit' | 'spend'\n): string => {\n const formatted = formatBalance(amount);\n return action === 'spend' ? `- ${formatted}` : `+ ${formatted}`;\n};\n\n/**\n * Get transaction color\n * @param action - deposit or spend\n * @returns Color hex code\n */\nexport const getTransactionColor = (action: 'deposit' | 'spend'): string => {\n return action === 'spend' ? '#FF4444' : '#00C853';\n};\n","// src/lib/utils/styles.ts\n// Utility for managing injected CSS with proper cleanup\n\n// Track how many components are using each style\nconst styleRefCounts = new Map<string, number>();\n\n/**\n * Inject styles into the document head with reference counting\n * Multiple components can share the same styles safely\n * \n * @param styleId - Unique identifier for the style block\n * @param css - CSS content to inject\n * @returns Cleanup function to call on unmount\n */\nexport function injectStyles(styleId: string, css: string): () => void {\n if (typeof document === 'undefined') {\n // SSR - return no-op cleanup\n return () => {};\n }\n\n const currentCount = styleRefCounts.get(styleId) || 0;\n\n if (currentCount === 0) {\n // First component using this style - inject it\n const style = document.createElement('style');\n style.id = styleId;\n style.textContent = css;\n document.head.appendChild(style);\n }\n\n // Increment reference count\n styleRefCounts.set(styleId, currentCount + 1);\n\n // Return cleanup function\n return () => {\n const count = styleRefCounts.get(styleId) || 0;\n if (count <= 1) {\n // Last component using this style - remove it\n const style = document.getElementById(styleId);\n if (style) {\n style.remove();\n }\n styleRefCounts.delete(styleId);\n } else {\n // Other components still using this style\n styleRefCounts.set(styleId, count - 1);\n }\n };\n}\n\n/**\n * Check if styles are already injected\n * @param styleId - Unique identifier for the style block\n */\nexport function hasStyles(styleId: string): boolean {\n if (typeof document === 'undefined') return false;\n return document.getElementById(styleId) !== null;\n}\n\n","// WalletFullPage.tsx - Full screen wallet page matching passport wallet design\nimport React, { useEffect } from 'react';\nimport type { ZoUser } from '../../lib/types';\nimport { formatWalletAddress } from '../../lib/utils/wallet';\nimport { injectStyles } from '../../lib/utils/styles';\n\n// Zo coin asset\nconst ZO_COIN_URL = '/zo-coin.gif';\n\n// Wallet background (leather texture)\nconst WALLET_BG = 'https://proxy.cdn.zo.xyz/public/wallet-background.png';\n\nexport interface WalletFullPageProps {\n user: ZoUser | null;\n balance: number;\n onClose: () => void;\n zoCoinUrl?: string;\n isLoading?: boolean;\n onRefresh?: () => void;\n}\n\nconst STYLE_ID = 'zo-wallet-fullpage-styles';\nconst CSS = `\n .zo-wallet-fullpage {\n position: fixed;\n inset: 0;\n background: #000;\n z-index: 1000;\n display: flex;\n flex-direction: column;\n font-family: 'Rubik', system-ui, sans-serif;\n color: #fff;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n }\n \n .zo-wallet-header {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid rgba(255,255,255,0.1);\n position: sticky;\n top: 0;\n background: #000;\n z-index: 10;\n }\n \n .zo-wallet-back {\n background: none;\n border: none;\n color: #fff;\n font-size: 24px;\n cursor: pointer;\n padding: 8px;\n margin-right: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n \n .zo-wallet-header-title {\n font-size: 18px;\n font-weight: 600;\n margin: 0;\n }\n \n .zo-wallet-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 24px 16px 60px;\n }\n \n /* Wallet Card - Leather Style */\n .zo-wallet-leather-card {\n position: relative;\n width: 100%;\n max-width: 360px;\n aspect-ratio: 1.6;\n border-radius: 16px;\n overflow: hidden;\n background: linear-gradient(145deg, #2d2d2d 0%, #1a1a1a 100%);\n border: 2px dashed rgba(255,255,255,0.15);\n box-shadow: \n 0 20px 40px rgba(0,0,0,0.5),\n inset 0 1px 0 rgba(255,255,255,0.1);\n margin-bottom: 24px;\n }\n \n .zo-wallet-leather-bg {\n position: absolute;\n inset: 0;\n background-image: url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\"><defs><pattern id=\"grain\" patternUnits=\"userSpaceOnUse\" width=\"100\" height=\"100\"><circle cx=\"25\" cy=\"25\" r=\"1\" fill=\"rgba(255,255,255,0.03)\"/><circle cx=\"75\" cy=\"75\" r=\"1\" fill=\"rgba(255,255,255,0.03)\"/><circle cx=\"50\" cy=\"10\" r=\"0.5\" fill=\"rgba(255,255,255,0.02)\"/><circle cx=\"10\" cy=\"60\" r=\"0.5\" fill=\"rgba(255,255,255,0.02)\"/><circle cx=\"90\" cy=\"40\" r=\"0.5\" fill=\"rgba(255,255,255,0.02)\"/></pattern></defs><rect width=\"100\" height=\"100\" fill=\"url(%23grain)\"/></svg>');\n opacity: 0.5;\n }\n \n .zo-wallet-leather-content {\n position: relative;\n z-index: 1;\n height: 100%;\n display: flex;\n flex-direction: column;\n padding: 24px;\n }\n \n /* Balance Section */\n .zo-wallet-balance-section {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: auto;\n }\n \n .zo-wallet-balance-left {\n display: flex;\n align-items: baseline;\n gap: 8px;\n }\n \n .zo-wallet-balance-amount {\n font-size: 42px;\n font-weight: 700;\n margin: 0;\n color: #fff;\n }\n \n .zo-wallet-balance-currency {\n font-size: 16px;\n color: rgba(255,255,255,0.6);\n }\n \n .zo-wallet-coin {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n }\n \n /* User Section */\n .zo-wallet-user-section {\n display: flex;\n align-items: center;\n gap: 12px;\n padding-top: 16px;\n border-top: 1px solid rgba(255,255,255,0.1);\n }\n \n .zo-wallet-avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n object-fit: cover;\n border: 2px solid rgba(255,255,255,0.2);\n }\n \n .zo-wallet-user-details {\n flex: 1;\n }\n \n .zo-wallet-user-name {\n font-size: 14px;\n font-weight: 600;\n margin: 0 0 2px 0;\n color: #fff;\n }\n \n .zo-wallet-user-address {\n font-size: 11px;\n color: rgba(255,255,255,0.5);\n margin: 0;\n font-family: monospace;\n }\n \n /* Wallet Label */\n .zo-wallet-label {\n text-align: center;\n padding: 20px;\n background: rgba(255,255,255,0.03);\n border: 1px solid rgba(255,255,255,0.08);\n border-radius: 12px;\n margin-top: 8px;\n }\n \n .zo-wallet-label-text {\n font-size: 14px;\n color: rgba(255,255,255,0.6);\n margin: 0;\n }\n \n /* Info Section */\n .zo-wallet-info-section {\n width: 100%;\n max-width: 360px;\n margin-top: 24px;\n }\n \n .zo-wallet-info-title {\n font-size: 12px;\n font-weight: 600;\n color: rgba(255,255,255,0.5);\n margin: 0 0 12px 0;\n text-transform: uppercase;\n letter-spacing: 0.1em;\n }\n \n .zo-wallet-info-card {\n background: rgba(255,255,255,0.03);\n border: 1px solid rgba(255,255,255,0.08);\n border-radius: 12px;\n padding: 16px;\n }\n \n .zo-wallet-info-text {\n font-size: 13px;\n color: rgba(255,255,255,0.6);\n line-height: 1.6;\n margin: 0;\n }\n \n /* Stitching Effect */\n .zo-wallet-stitch {\n position: absolute;\n border: 1px dashed rgba(255,255,255,0.2);\n border-radius: 12px;\n inset: 8px;\n pointer-events: none;\n }\n \n @media (min-width: 768px) {\n .zo-wallet-leather-card {\n max-width: 420px;\n }\n \n .zo-wallet-balance-amount {\n font-size: 56px;\n }\n \n .zo-wallet-coin {\n width: 56px;\n height: 56px;\n }\n \n .zo-wallet-leather-content {\n padding: 32px;\n }\n }\n`;\n\nexport const WalletFullPage: React.FC<WalletFullPageProps> = ({\n user,\n balance,\n onClose,\n zoCoinUrl = ZO_COIN_URL,\n isLoading = false,\n onRefresh,\n}) => {\n useEffect(() => {\n const cleanupStyles = injectStyles(STYLE_ID, CSS);\n document.body.style.overflow = 'hidden';\n return () => {\n cleanupStyles();\n document.body.style.overflow = '';\n };\n }, []);\n\n const displayName = user?.first_name || 'Citizen';\n\n return (\n <div className=\"zo-wallet-fullpage\">\n {/* Header */}\n <div className=\"zo-wallet-header\">\n <button className=\"zo-wallet-back\" onClick={onClose}>\n ←\n </button>\n <h1 className=\"zo-wallet-header-title\">{displayName}'s Wallet</h1>\n {onRefresh && (\n <button \n className=\"zo-wallet-refresh\" \n onClick={onRefresh}\n disabled={isLoading}\n style={{\n marginLeft: 'auto',\n background: 'none',\n border: '1px solid rgba(255,255,255,0.2)',\n borderRadius: '8px',\n padding: '8px 12px',\n color: '#fff',\n cursor: isLoading ? 'wait' : 'pointer',\n fontSize: '12px',\n opacity: isLoading ? 0.5 : 1,\n }}\n >\n {isLoading ? '...' : '↻ Refresh'}\n </button>\n )}\n </div>\n\n {/* Content */}\n <div className=\"zo-wallet-content\">\n {/* Leather Wallet Card */}\n <div className=\"zo-wallet-leather-card\">\n <div className=\"zo-wallet-leather-bg\" />\n <div className=\"zo-wallet-stitch\" />\n \n <div className=\"zo-wallet-leather-content\">\n {/* Balance */}\n <div className=\"zo-wallet-balance-section\">\n <div className=\"zo-wallet-balance-left\">\n <h2 className=\"zo-wallet-balance-amount\" style={{ opacity: isLoading ? 0.5 : 1 }}>\n {isLoading ? '...' : balance}\n </h2>\n <span className=\"zo-wallet-balance-currency\">$Zo</span>\n </div>\n <img \n src={zoCoinUrl} \n alt=\"Zo Coin\" \n className=\"zo-wallet-coin\"\n style={{ \n animation: isLoading ? 'spin 1s linear infinite' : 'none',\n }}\n />\n </div>\n\n {/* User Info */}\n {user && (\n <div className=\"zo-wallet-user-section\">\n {(user.avatar?.image || user.pfp_image) && (\n <img \n src={user.avatar?.image || user.pfp_image} \n alt={displayName}\n className=\"zo-wallet-avatar\"\n />\n )}\n <div className=\"zo-wallet-user-details\">\n <p className=\"zo-wallet-user-name\">{displayName}</p>\n <p className=\"zo-wallet-user-address\">\n {formatWalletAddress(user.wallet_address || '')}\n </p>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Wallet Label */}\n <div className=\"zo-wallet-label\">\n <p className=\"zo-wallet-label-text\">{displayName}'s wallet</p>\n </div>\n\n {/* Info Section */}\n <div className=\"zo-wallet-info-section\">\n <h3 className=\"zo-wallet-info-title\">About $Zo</h3>\n <div className=\"zo-wallet-info-card\">\n <p className=\"zo-wallet-info-text\">\n Earn $Zo tokens by completing quests, exploring locations, \n booking stays, and participating in the Zo World ecosystem.\n </p>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default WalletFullPage;\n","// Wallet Asset URLs - Production CDN\nexport const WALLET_ASSETS = {\n walletBackground:\n 'https://proxy.cdn.zo.xyz/gallery/media/images/2e1fe74c-673c-4acd-a5aa-4ac13027dfb2_20250706072110.png',\n walletCover:\n 'https://proxy.cdn.zo.xyz/gallery/media/images/aeb1d508-c511-46a9-b4f8-260ea8825c6a_20250706072152.png',\n shine:\n 'https://proxy.cdn.zo.xyz/gallery/media/images/2a117a82-e399-4278-8eac-0d5b9209d150_20250706073538.png',\n} as const;\n\nexport const WALLET_COLORS = {\n background: '#111111',\n cardBackground: '#222222',\n cardInner: 'rgba(255, 255, 255, 0.24)',\n cardContent: '#111111',\n cardBorder: 'rgba(255, 255, 255, 0.16)',\n textWhite: '#FFFFFF',\n textGray: 'rgba(255, 255, 255, 0.44)',\n zoGreen: '#00C853',\n shadowDark: 'rgba(25, 25, 25, 1)',\n} as const;\n\nexport const WALLET_DIMENSIONS = {\n cardAspectRatio: 312 / 200,\n coverAspectRatio: 312 / 120,\n cardBorderRadius: 16,\n innerBorderRadius: 12,\n avatarSize: 32,\n tokenSize: 16,\n tokenVideoSize: 24,\n} as const;\n\nexport const ANIMATIONS = {\n shineDuration: 1500,\n cardTransition: 300,\n fadeInDuration: 500,\n} as const;\n\n","// Asset path constants for Zo Passport SDK\n// Use these when configuring components\n\nexport const ASSETS = {\n // Core avatars\n BRO_AVATAR: '/bro.png',\n BAE_AVATAR: '/bae.png',\n FALLBACK_AVATAR: '/zo-fallback.png',\n DEFAULT_AVATAR: '/images/rank1.jpeg',\n\n // Branding\n ZO_LOGO: '/figma-assets/landing-zo-logo.png',\n ZO_COIN: '/zo-coin.gif',\n\n // Videos\n LANDING_VIDEO: '/videos/loading-screen-background.mp4',\n PORTAL_VIDEO: '/videos/opening-disks.mp4',\n\n // Passport backgrounds (CDN)\n FOUNDER_BG: 'https://proxy.cdn.zo.xyz/gallery/media/images/a1659b07-94f0-4490-9b3c-3366715d9717_20250515053726.png',\n CITIZEN_BG: 'https://proxy.cdn.zo.xyz/gallery/media/images/bda9da5a-eefe-411d-8d90-667c80024463_20250515053805.png',\n\n // Lotties\n LOADER: '/lotties/loader.json',\n SPINNER: '/lotties/spinner.json',\n} as const;\n\n// Cultural sticker paths\nexport const CULTURE_STICKERS = {\n travel: '/cultural-stickers/Travel&Adventure.png',\n design: '/cultural-stickers/Design.png',\n tech: '/cultural-stickers/Science&Technology.png',\n food: '/cultural-stickers/Food.png',\n music: '/cultural-stickers/Music&Entertainment.png',\n photography: '/cultural-stickers/Photography.png',\n fitness: '/cultural-stickers/Health&Fitness.png',\n sports: '/cultural-stickers/Sport.png',\n literature: '/cultural-stickers/Literature&Stories.png',\n cinema: '/cultural-stickers/Television&Cinema.png',\n spiritual: '/cultural-stickers/Spiritual.png',\n nature: '/cultural-stickers/Nature&Wildlife.png',\n business: '/cultural-stickers/Business.png',\n law: '/cultural-stickers/Law.png',\n lifestyle: '/cultural-stickers/Home&Lifestyle.png',\n gaming: '/cultural-stickers/Game.png',\n stories: '/cultural-stickers/Stories&Journal.png',\n} as const;\n\n// Culture metadata\nexport const CULTURES = [\n { id: 'travel', name: 'Travel & Adventure', icon: CULTURE_STICKERS.travel },\n { id: 'design', name: 'Design', icon: CULTURE_STICKERS.design },\n { id: 'tech', name: 'Science & Technology', icon: CULTURE_STICKERS.tech },\n { id: 'food', name: 'Food', icon: CULTURE_STICKERS.food },\n { id: 'music', name: 'Music & Entertainment', icon: CULTURE_STICKERS.music },\n { id: 'photography', name: 'Photography', icon: CULTURE_STICKERS.photography },\n { id: 'fitness', name: 'Health & Fitness', icon: CULTURE_STICKERS.fitness },\n { id: 'sports', name: 'Sport', icon: CULTURE_STICKERS.sports },\n { id: 'literature', name: 'Literature & Stories', icon: CULTURE_STICKERS.literature },\n { id: 'cinema', name: 'Television & Cinema', icon: CULTURE_STICKERS.cinema },\n { id: 'spiritual', name: 'Spiritual', icon: CULTURE_STICKERS.spiritual },\n { id: 'nature', name: 'Nature & Wildlife', icon: CULTURE_STICKERS.nature },\n { id: 'business', name: 'Business', icon: CULTURE_STICKERS.business },\n { id: 'law', name: 'Law', icon: CULTURE_STICKERS.law },\n { id: 'lifestyle', name: 'Home & Lifestyle', icon: CULTURE_STICKERS.lifestyle },\n { id: 'gaming', name: 'Game', icon: CULTURE_STICKERS.gaming },\n { id: 'stories', name: 'Stories & Journal', icon: CULTURE_STICKERS.stories },\n] as const;\n\nexport type CultureId = typeof CULTURES[number]['id'];\n\n// =====================\n// Wallet Assets\n// =====================\n\nexport * from './wallet/constants';\n","// src/lib/utils/phone.ts\n// Phone number formatting utilities\n\nexport const COUNTRY_CODES = [\n { code: '1', country: 'US', flag: '🇺🇸', name: 'United States' },\n { code: '91', country: 'IN', flag: '🇮🇳', name: 'India' },\n { code: '44', country: 'GB', flag: '🇬🇧', name: 'United Kingdom' },\n { code: '86', country: 'CN', flag: '🇨🇳', name: 'China' },\n { code: '81', country: 'JP', flag: '🇯🇵', name: 'Japan' },\n { code: '82', country: 'KR', flag: '🇰🇷', name: 'South Korea' },\n { code: '33', country: 'FR', flag: '🇫🇷', name: 'France' },\n { code: '49', country: 'DE', flag: '🇩🇪', name: 'Germany' },\n { code: '7', country: 'RU', flag: '🇷🇺', name: 'Russia' },\n { code: '55', country: 'BR', flag: '🇧🇷', name: 'Brazil' },\n { code: '61', country: 'AU', flag: '🇦🇺', name: 'Australia' },\n { code: '65', country: 'SG', flag: '🇸🇬', name: 'Singapore' },\n { code: '971', country: 'AE', flag: '🇦🇪', name: 'UAE' },\n { code: '966', country: 'SA', flag: '🇸🇦', name: 'Saudi Arabia' },\n { code: '62', country: 'ID', flag: '🇮🇩', name: 'Indonesia' },\n { code: '60', country: 'MY', flag: '🇲🇾', name: 'Malaysia' },\n { code: '66', country: 'TH', flag: '🇹🇭', name: 'Thailand' },\n { code: '84', country: 'VN', flag: '🇻🇳', name: 'Vietnam' },\n { code: '63', country: 'PH', flag: '🇵🇭', name: 'Philippines' },\n { code: '31', country: 'NL', flag: '🇳🇱', name: 'Netherlands' },\n] as const;\n\n/**\n * Format phone number for display\n * e.g., \"5551234567\" → \"555-123-4567\"\n */\nexport function formatPhoneNumber(phone: string): string {\n const cleaned = phone.replace(/\\D/g, '');\n \n if (cleaned.length === 10) {\n return `${cleaned.slice(0, 3)}-${cleaned.slice(3, 6)}-${cleaned.slice(6)}`;\n }\n \n return cleaned;\n}\n\n/**\n * Parse phone number to clean digits only\n * Removes all non-digit characters\n */\nexport function parsePhoneNumber(phone: string): string {\n return phone.replace(/\\D/g, '');\n}\n\n","// src/components/PhoneInput.tsx\n// Phone number input with country code selector\n\nimport React, { useState } from 'react';\nimport { COUNTRY_CODES, parsePhoneNumber } from '../lib/utils/phone';\n\nexport interface PhoneInputProps {\n /** Current phone number value */\n value: string;\n /** Current country code (without +) */\n countryCode: string;\n /** Callback when phone number changes */\n onChange: (phone: string) => void;\n /** Callback when country code changes */\n onCountryChange: (code: string) => void;\n /** Placeholder text */\n placeholder?: string;\n /** Disabled state */\n disabled?: boolean;\n /** Error message */\n error?: string;\n /** Additional CSS class */\n className?: string;\n}\n\nexport const PhoneInput: React.FC<PhoneInputProps> = ({\n value,\n countryCode,\n onChange,\n onCountryChange,\n placeholder = '555-123-4567',\n disabled = false,\n error,\n className = '',\n}) => {\n const handlePhoneChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const digits = parsePhoneNumber(e.target.value);\n onChange(digits);\n };\n\n return (\n <div className={`zo-phone-input ${className}`}>\n <div style={{ display: 'flex', gap: '8px' }}>\n {/* Country Code Selector */}\n <select\n value={countryCode}\n onChange={(e) => onCountryChange(e.target.value)}\n disabled={disabled}\n style={{\n flex: 1,\n backgroundColor: 'rgba(255, 255, 255, 0.1)',\n border: '1px solid rgba(255, 255, 255, 0.2)',\n borderRadius: '8px',\n padding: '12px 16px',\n color: 'white',\n fontFamily: 'Rubik, system-ui, sans-serif',\n fontSize: '14px',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.5 : 1,\n }}\n >\n {COUNTRY_CODES.map((country) => (\n <option key={country.code} value={country.code} style={{ backgroundColor: 'black' }}>\n {country.flag} +{country.code}\n </option>\n ))}\n </select>\n\n {/* Phone Number Input */}\n <input\n type=\"tel\"\n value={value}\n onChange={handlePhoneChange}\n placeholder={placeholder}\n disabled={disabled}\n style={{\n flex: 2,\n backgroundColor: 'rgba(255, 255, 255, 0.1)',\n border: error\n ? '1px solid #ef4444'\n : '1px solid rgba(255, 255, 255, 0.2)',\n borderRadius: '8px',\n padding: '12px 16px',\n color: 'white',\n fontFamily: 'Rubik, system-ui, sans-serif',\n fontSize: '14px',\n cursor: disabled ? 'not-allowed' : 'text',\n opacity: disabled ? 0.5 : 1,\n }}\n />\n </div>\n\n {/* Error Message */}\n {error && (\n <p\n style={{\n color: '#ef4444',\n fontSize: '14px',\n marginTop: '8px',\n fontFamily: 'Rubik, system-ui, sans-serif',\n }}\n >\n {error}\n </p>\n )}\n </div>\n );\n};\n\n","// src/components/OTPInput.tsx\n// 6-digit OTP input component\n\nimport React, { useRef, useEffect } from 'react';\n\nexport interface OTPInputProps {\n /** Current OTP value array */\n value: string[];\n /** Callback when OTP changes */\n onChange: (otp: string[]) => void;\n /** Callback when all 6 digits entered */\n onComplete?: (otp: string) => void;\n /** Number of digits (default: 6) */\n length?: number;\n /** Disabled state */\n disabled?: boolean;\n /** Error message */\n error?: string;\n /** Auto-focus first input */\n autoFocus?: boolean;\n /** Additional CSS class */\n className?: string;\n}\n\nexport const OTPInput: React.FC<OTPInputProps> = ({\n value,\n onChange,\n onComplete,\n length = 6,\n disabled = false,\n error,\n autoFocus = true,\n className = '',\n}) => {\n const inputRefs = useRef<(HTMLInputElement | null)[]>([]);\n\n // Initialize refs array\n useEffect(() => {\n inputRefs.current = inputRefs.current.slice(0, length);\n }, [length]);\n\n // Auto-focus first input\n useEffect(() => {\n if (autoFocus && inputRefs.current[0]) {\n setTimeout(() => inputRefs.current[0]?.focus(), 100);\n }\n }, [autoFocus]);\n\n const handleChange = (index: number, inputValue: string) => {\n // Only allow digits\n if (inputValue && !/^\\d$/.test(inputValue)) return;\n\n const newOtp = [...value];\n newOtp[index] = inputValue;\n onChange(newOtp);\n\n // Auto-focus next input\n if (inputValue && index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n\n // Check if complete\n if (newOtp.every(digit => digit !== '') && index === length - 1) {\n onComplete?.(newOtp.join(''));\n }\n };\n\n const handleKeyDown = (index: number, e: React.KeyboardEvent<HTMLInputElement>) => {\n // Backspace: move to previous input\n if (e.key === 'Backspace' && !value[index] && index > 0) {\n inputRefs.current[index - 1]?.focus();\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent) => {\n e.preventDefault();\n const pastedData = e.clipboardData.getData('text').slice(0, length);\n const digits = pastedData.replace(/\\D/g, '').split('');\n \n if (digits.length > 0) {\n const newOtp = [...value];\n digits.forEach((digit, i) => {\n if (i < length) newOtp[i] = digit;\n });\n onChange(newOtp);\n \n // Focus last filled input or the one after\n const focusIndex = Math.min(digits.length, length - 1);\n inputRefs.current[focusIndex]?.focus();\n \n if (newOtp.every(digit => digit !== '')) {\n onComplete?.(newOtp.join(''));\n }\n }\n };\n\n return (\n <div className={`zo-otp-input ${className}`}>\n <div style={{ display: 'flex', gap: '8px', justifyContent: 'center' }}>\n {Array.from({ length }).map((_, index) => (\n <input\n key={index}\n ref={(el) => { inputRefs.current[index] = el; }}\n type=\"text\"\n inputMode=\"numeric\"\n maxLength={1}\n value={value[index] || ''}\n onChange={(e) => handleChange(index, e.target.value)}\n onKeyDown={(e) => handleKeyDown(index, e)}\n onPaste={handlePaste}\n disabled={disabled}\n style={{\n width: '48px',\n height: '56px',\n backgroundColor: 'rgba(255, 255, 255, 0.1)',\n border: error\n ? '1px solid #ef4444'\n : '1px solid rgba(255, 255, 255, 0.2)',\n borderRadius: '8px',\n textAlign: 'center',\n color: 'white',\n fontFamily: 'Rubik, system-ui, sans-serif',\n fontSize: '20px',\n fontWeight: 600,\n cursor: disabled ? 'not-allowed' : 'text',\n opacity: disabled ? 0.5 : 1,\n }}\n />\n ))}\n </div>\n\n {/* Error Message */}\n {error && (\n <p\n style={{\n color: '#ef4444',\n fontSize: '14px',\n marginTop: '8px',\n textAlign: 'center',\n fontFamily: 'Rubik, system-ui, sans-serif',\n }}\n >\n {error}\n </p>\n )}\n </div>\n );\n};\n\n","// src/components/ZoAuth.tsx\n// Complete phone OTP authentication flow component\n\nimport React, { useState, useEffect } from 'react';\nimport { PhoneInput } from './PhoneInput';\nimport { OTPInput } from './OTPInput';\n\nimport type { ZoUser } from '../lib/types';\n\nexport interface ZoAuthProps {\n /** Callback when auth is successful */\n onSuccess: (userId: string, user: any) => void;\n /** Callback to close modal */\n onClose?: () => void;\n /** Send OTP function (from SDK) */\n sendOTP: (countryCode: string, phoneNumber: string) => Promise<{ success: boolean; message: string }>;\n /** Verify OTP function (from SDK) */\n verifyOTP: (countryCode: string, phoneNumber: string, otp: string) => Promise<{ success: boolean; user?: ZoUser; error?: string }>;\n /** Default country code (default: '91') */\n defaultCountryCode?: string;\n /** Show close button */\n showCloseButton?: boolean;\n /** Additional CSS class */\n className?: string;\n}\n\ntype Step = 'phone' | 'otp';\n\nexport const ZoAuth: React.FC<ZoAuthProps> = ({\n onSuccess,\n onClose,\n sendOTP,\n verifyOTP,\n defaultCountryCode = '91',\n showCloseButton = true,\n className = '',\n}) => {\n const [step, setStep] = useState<Step>('phone');\n const [countryCode, setCountryCode] = useState(defaultCountryCode);\n const [phoneNumber, setPhoneNumber] = useState('');\n const [otp, setOtp] = useState<string[]>(['', '', '', '', '', '']);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [resendCooldown, setResendCooldown] = useState(0);\n\n // Resend cooldown timer\n useEffect(() => {\n if (resendCooldown > 0) {\n const timer = setTimeout(() => setResendCooldown(resendCooldown - 1), 1000);\n return () => clearTimeout(timer);\n }\n }, [resendCooldown]);\n\n const handleSendOTP = async () => {\n if (!phoneNumber || phoneNumber.length < 10) {\n setError('Please enter a valid phone number');\n return;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await sendOTP(countryCode, phoneNumber);\n\n if (result.success) {\n setStep('otp');\n setResendCooldown(60);\n } else {\n setError(result.message || 'Failed to send OTP');\n }\n } catch (err: any) {\n setError(err.message || 'Failed to send verification code');\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleVerifyOTP = async (otpString: string) => {\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await verifyOTP(countryCode, phoneNumber, otpString);\n\n if (result.success && result.user) {\n onSuccess(result.user.id || '', result.user);\n } else {\n setError(result.error || 'Invalid verification code');\n setOtp(['', '', '', '', '', '']);\n }\n } catch (err: any) {\n setError(err.message || 'Invalid verification code');\n setOtp(['', '', '', '', '', '']);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleResendOTP = async () => {\n if (resendCooldown > 0) return;\n await handleSendOTP();\n };\n\n const containerStyle: React.CSSProperties = {\n position: 'relative',\n width: '100%',\n maxWidth: '400px',\n backgroundColor: 'rgba(0, 0, 0, 0.95)',\n border: '1px solid rgba(255, 255, 255, 0.2)',\n borderRadius: '24px',\n padding: '24px 32px',\n fontFamily: 'Rubik, system-ui, sans-serif',\n };\n\n return (\n <div className={`zo-auth ${className}`} style={containerStyle}>\n {/* Close Button */}\n {showCloseButton && onClose && (\n <button\n onClick={onClose}\n style={{\n position: 'absolute',\n top: '16px',\n right: '16px',\n width: '32px',\n height: '32px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'transparent',\n border: 'none',\n cursor: 'pointer',\n color: 'rgba(255, 255, 255, 0.6)',\n }}\n >\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n )}\n\n {/* Step 1: Phone Input */}\n {step === 'phone' && (\n <div>\n {/* Icon */}\n <div\n style={{\n width: '64px',\n height: '64px',\n margin: '0 auto 16px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'rgba(255, 255, 255, 0.1)',\n borderRadius: '50%',\n }}\n >\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"2\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z\" />\n </svg>\n </div>\n\n {/* Title */}\n <h2\n style={{\n textAlign: 'center',\n color: 'white',\n fontSize: '24px',\n fontWeight: 800,\n marginBottom: '8px',\n fontFamily: 'Syne, system-ui, sans-serif',\n }}\n >\n Enter Your Phone Number\n </h2>\n <p\n style={{\n textAlign: 'center',\n color: 'rgba(255, 255, 255, 0.6)',\n fontSize: '14px',\n marginBottom: '24px',\n }}\n >\n We'll send you a verification code\n </p>\n\n {/* Phone Input */}\n <PhoneInput\n value={phoneNumber}\n countryCode={countryCode}\n onChange={setPhoneNumber}\n onCountryChange={setCountryCode}\n disabled={isLoading}\n error={error || undefined}\n />\n\n {/* Send Button */}\n <button\n onClick={handleSendOTP}\n disabled={isLoading || phoneNumber.length < 10}\n style={{\n width: '100%',\n marginTop: '16px',\n padding: '16px',\n backgroundColor: 'black',\n border: '2px solid rgba(255, 255, 255, 0.2)',\n borderRadius: '12px',\n color: 'white',\n fontWeight: 500,\n fontSize: '16px',\n cursor: isLoading || phoneNumber.length < 10 ? 'not-allowed' : 'pointer',\n opacity: isLoading || phoneNumber.length < 10 ? 0.5 : 1,\n }}\n >\n {isLoading ? 'Sending Code...' : 'Send Code'}\n </button>\n </div>\n )}\n\n {/* Step 2: OTP Input */}\n {step === 'otp' && (\n <div>\n {/* Icon */}\n <div\n style={{\n width: '64px',\n height: '64px',\n margin: '0 auto 16px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'rgba(255, 255, 255, 0.1)',\n borderRadius: '50%',\n }}\n >\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" strokeWidth=\"2\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\" />\n </svg>\n </div>\n\n {/* Title */}\n <h2\n style={{\n textAlign: 'center',\n color: 'white',\n fontSize: '24px',\n fontWeight: 800,\n marginBottom: '8px',\n fontFamily: 'Syne, system-ui, sans-serif',\n }}\n >\n Enter Verification Code\n </h2>\n <p\n style={{\n textAlign: 'center',\n color: 'rgba(255, 255, 255, 0.6)',\n fontSize: '14px',\n marginBottom: '24px',\n }}\n >\n We sent a code to +{countryCode} {phoneNumber}\n </p>\n\n {/* OTP Input */}\n <OTPInput\n value={otp}\n onChange={setOtp}\n onComplete={handleVerifyOTP}\n disabled={isLoading}\n error={error || undefined}\n />\n\n {/* Verify Button */}\n <button\n onClick={() => handleVerifyOTP(otp.join(''))}\n disabled={isLoading || otp.some(d => !d)}\n style={{\n width: '100%',\n marginTop: '16px',\n padding: '16px',\n backgroundColor: 'black',\n border: '2px solid rgba(255, 255, 255, 0.2)',\n borderRadius: '12px',\n color: 'white',\n fontWeight: 500,\n fontSize: '16px',\n cursor: isLoading || otp.some(d => !d) ? 'not-allowed' : 'pointer',\n opacity: isLoading || otp.some(d => !d) ? 0.5 : 1,\n }}\n >\n {isLoading ? 'Verifying...' : 'Verify'}\n </button>\n\n {/* Resend Link */}\n <div style={{ textAlign: 'center', marginTop: '16px' }}>\n <button\n onClick={handleResendOTP}\n disabled={resendCooldown > 0}\n style={{\n backgroundColor: 'transparent',\n border: 'none',\n color: 'rgba(255, 255, 255, 0.6)',\n fontSize: '14px',\n cursor: resendCooldown > 0 ? 'not-allowed' : 'pointer',\n opacity: resendCooldown > 0 ? 0.5 : 1,\n }}\n >\n {resendCooldown > 0\n ? `Resend code in ${resendCooldown}s`\n : \"Didn't receive? Resend code\"}\n </button>\n </div>\n </div>\n )}\n </div>\n );\n};\n\n","// src/components/ZoLanding.tsx\n// Landing page component with video background\n\nimport React, { useState } from 'react';\nimport { ZoAuth } from './ZoAuth';\n\nexport interface ZoLandingProps {\n /** Callback when user successfully authenticates */\n onAuthSuccess: (userId: string, user: any) => void;\n /** Send OTP function (from SDK) */\n sendOTP: (countryCode: string, phoneNumber: string) => Promise<{ success: boolean; message: string }>;\n /** Verify OTP function (from SDK) */\n verifyOTP: (countryCode: string, phoneNumber: string, otp: string) => Promise<{ success: boolean; error?: string }>;\n /** Video background URL */\n videoUrl?: string;\n /** Zo logo URL */\n logoUrl?: string;\n /** Title text */\n title?: string;\n /** Subtitle lines */\n subtitles?: string[];\n /** Button text */\n buttonText?: string;\n /** Additional CSS class */\n className?: string;\n}\n\nexport const ZoLanding: React.FC<ZoLandingProps> = ({\n onAuthSuccess,\n sendOTP,\n verifyOTP,\n videoUrl = '/videos/loading-screen-background.mp4',\n logoUrl = '/figma-assets/landing-zo-logo.png',\n title = 'ZOHMMM!',\n subtitles = [\n 'Welcome to Zo World',\n 'A parallel reality where you live your best life, by following your heart.',\n 'Are you ready to tune in, Anon?',\n ],\n buttonText = 'Tune into Zo World',\n className = '',\n}) => {\n const [showAuth, setShowAuth] = useState(false);\n\n const containerStyle: React.CSSProperties = {\n position: 'fixed',\n inset: 0,\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: 'black',\n width: '100vw',\n height: '100vh',\n overflow: 'hidden',\n fontFamily: 'Rubik, system-ui, sans-serif',\n };\n\n return (\n <div className={`zo-landing ${className}`} style={containerStyle}>\n {/* Video Background */}\n <video\n autoPlay\n loop\n muted\n playsInline\n style={{\n position: 'fixed',\n inset: 0,\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n zIndex: 1,\n pointerEvents: 'none',\n }}\n >\n <source src={videoUrl} type=\"video/mp4\" />\n </video>\n\n {/* Gradient Overlay */}\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'linear-gradient(to bottom, transparent 50%, black)',\n zIndex: 2,\n pointerEvents: 'none',\n }}\n />\n\n {/* Zo Logo */}\n <img\n src={logoUrl}\n alt=\"Zo\"\n style={{\n position: 'absolute',\n left: '24px',\n top: '40px',\n width: '40px',\n height: '40px',\n objectFit: 'cover',\n zIndex: 10,\n }}\n />\n\n {/* Main Content */}\n <div\n style={{\n position: 'relative',\n zIndex: 10,\n width: '100%',\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '24px',\n }}\n >\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n width: '100%',\n maxWidth: '800px',\n gap: '32px',\n }}\n >\n {/* Header */}\n <div style={{ textAlign: 'center' }}>\n <h1\n style={{\n fontFamily: 'Syne, system-ui, sans-serif',\n fontSize: 'clamp(32px, 8vw, 72px)',\n fontWeight: 800,\n color: 'white',\n lineHeight: 1.1,\n letterSpacing: '0.32px',\n textTransform: 'uppercase',\n margin: 0,\n }}\n >\n {title}\n </h1>\n\n <div\n style={{\n marginTop: '16px',\n fontSize: 'clamp(16px, 3vw, 24px)',\n color: 'white',\n lineHeight: 1.5,\n }}\n >\n {subtitles.map((text, i) => (\n <p key={i} style={{ margin: '8px 0' }}>\n {text}\n </p>\n ))}\n </div>\n </div>\n\n {/* CTA Button */}\n <button\n onClick={() => setShowAuth(true)}\n style={{\n backgroundColor: 'black',\n border: '2px solid rgba(255, 255, 255, 0.2)',\n borderRadius: '12px',\n padding: '16px 20px',\n width: '100%',\n maxWidth: '400px',\n height: '64px',\n cursor: 'pointer',\n transition: 'all 0.3s',\n }}\n >\n <span\n style={{\n fontFamily: 'Rubik, system-ui, sans-serif',\n fontSize: '18px',\n fontWeight: 500,\n color: 'white',\n }}\n >\n {buttonText}\n </span>\n </button>\n </div>\n </div>\n\n {/* Auth Modal */}\n {showAuth && (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 10000,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '16px',\n }}\n >\n {/* Backdrop */}\n <div\n onClick={() => setShowAuth(false)}\n style={{\n position: 'absolute',\n inset: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.8)',\n backdropFilter: 'blur(4px)',\n }}\n />\n {/* Auth Component */}\n <div style={{ position: 'relative', zIndex: 1 }}>\n <ZoAuth\n onSuccess={(userId, user) => {\n setShowAuth(false);\n onAuthSuccess(userId, user);\n }}\n onClose={() => setShowAuth(false)}\n sendOTP={sendOTP}\n verifyOTP={verifyOTP}\n />\n </div>\n </div>\n )}\n </div>\n );\n};\n\n","// src/components/ZoOnboarding.tsx\n// Onboarding flow: nickname, body type, location, avatar generation\n\nimport React, { useState, useEffect, useRef } from 'react';\n\nexport interface ZoOnboardingProps {\n /** Callback when onboarding is complete */\n onComplete: (userData: OnboardingData) => void;\n /** Update profile function (from SDK) */\n updateProfile: (updates: { first_name?: string; body_type?: 'bro' | 'bae'; place_name?: string }) => Promise<{ success: boolean; error?: string }>;\n /** Get profile function (from SDK) to poll for avatar */\n getProfile: () => Promise<any>;\n /** Video background URL */\n videoUrl?: string;\n /** Zo logo URL */\n logoUrl?: string;\n /** Bro avatar preview URL */\n broAvatarUrl?: string;\n /** Bae avatar preview URL */\n baeAvatarUrl?: string;\n /** Additional CSS class */\n className?: string;\n}\n\nexport interface OnboardingData {\n nickname: string;\n bodyType: 'bro' | 'bae';\n city: string;\n avatarUrl: string | null;\n}\n\ntype Step = 'input' | 'generating' | 'success';\n\nexport const ZoOnboarding: React.FC<ZoOnboardingProps> = ({\n onComplete,\n updateProfile,\n getProfile,\n videoUrl = '/videos/loading-screen-background.mp4',\n logoUrl = '/figma-assets/landing-zo-logo.png',\n broAvatarUrl = '/bro.png',\n baeAvatarUrl = '/bae.png',\n className = '',\n}) => {\n // State\n const [step, setStep] = useState<Step>('input');\n const [nickname, setNickname] = useState('');\n const [bodyType, setBodyType] = useState<'bro' | 'bae'>('bro');\n const [city, setCity] = useState('');\n const [locationEnabled, setLocationEnabled] = useState(false);\n const [isLoadingLocation, setIsLoadingLocation] = useState(false);\n const [isSaving, setIsSaving] = useState(false);\n const [error, setError] = useState('');\n const [avatarUrl, setAvatarUrl] = useState<string | null>(null);\n\n // Refs for polling\n const pollingRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const attemptsRef = useRef(0);\n\n // Validation\n const isNicknameValid = nickname.length >= 4 && nickname.length <= 16 && /^[a-z0-9]*$/.test(nickname);\n const canSubmit = isNicknameValid && locationEnabled && bodyType && !isSaving;\n\n // Cleanup polling on unmount\n useEffect(() => {\n return () => {\n if (pollingRef.current) clearTimeout(pollingRef.current);\n };\n }, []);\n\n // Handle nickname change\n const handleNicknameChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setNickname(e.target.value.toLowerCase());\n setError('');\n };\n\n // Handle location enable\n const handleLocationEnable = () => {\n if ('geolocation' in navigator) {\n setIsLoadingLocation(true);\n navigator.geolocation.getCurrentPosition(\n async (position) => {\n try {\n const response = await fetch(\n `https://api.bigdatacloud.net/data/reverse-geocode-client?latitude=${position.coords.latitude}&longitude=${position.coords.longitude}&localityLanguage=en`\n );\n const data = await response.json();\n const detectedCity = data.city || data.locality || data.principalSubdivision || 'Unknown City';\n\n setCity(detectedCity);\n setLocationEnabled(true);\n setIsLoadingLocation(false);\n setError('');\n } catch (err) {\n console.error('Failed to get city:', err);\n setError('Failed to detect location. Please try again.');\n setLocationEnabled(false);\n setIsLoadingLocation(false);\n }\n },\n (err) => {\n console.error('Location error:', err);\n setError('Location access denied. Please enable permissions.');\n setLocationEnabled(false);\n setIsLoadingLocation(false);\n }\n );\n } else {\n setError('Geolocation is not supported by your browser.');\n }\n };\n\n // Handle submit\n const handleSubmit = async () => {\n if (!canSubmit) return;\n\n setIsSaving(true);\n setError('');\n\n try {\n // Update profile via SDK\n const result = await updateProfile({\n first_name: nickname,\n body_type: bodyType,\n place_name: city,\n });\n\n if (!result.success) {\n throw new Error(result.error || 'Profile update failed');\n }\n\n // Transition to generating step\n setStep('generating');\n\n // Start polling for avatar\n pollForAvatar();\n } catch (err: any) {\n console.error('Error saving user:', err);\n setError('Failed to save. Please try again.');\n setIsSaving(false);\n }\n };\n\n // Poll for avatar\n const pollForAvatar = async () => {\n attemptsRef.current += 1;\n const maxAttempts = 30;\n\n if (attemptsRef.current > maxAttempts) {\n // Timeout - use default avatar\n setAvatarUrl(bodyType === 'bro' ? broAvatarUrl : baeAvatarUrl);\n setStep('success');\n return;\n }\n\n try {\n const profile = await getProfile();\n\n if (profile?.avatar?.image) {\n setAvatarUrl(profile.avatar.image);\n setTimeout(() => setStep('success'), 1000);\n return;\n }\n\n // Poll again in 1s\n pollingRef.current = setTimeout(pollForAvatar, 1000);\n } catch (err) {\n console.error('Polling error:', err);\n pollingRef.current = setTimeout(pollForAvatar, 1000);\n }\n };\n\n // Handle complete\n const handleComplete = () => {\n onComplete({\n nickname,\n bodyType,\n city,\n avatarUrl,\n });\n };\n\n const containerStyle: React.CSSProperties = {\n position: 'fixed',\n inset: 0,\n display: 'flex',\n flexDirection: 'column',\n backgroundColor: 'black',\n width: '100vw',\n height: '100vh',\n overflow: 'hidden',\n fontFamily: 'Rubik, system-ui, sans-serif',\n };\n\n return (\n <div className={`zo-onboarding ${className}`} style={containerStyle}>\n {/* Video Background */}\n <video\n autoPlay\n loop\n muted\n playsInline\n style={{\n position: 'absolute',\n inset: 0,\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n opacity: 0.4,\n zIndex: 0,\n pointerEvents: 'none',\n }}\n >\n <source src={videoUrl} type=\"video/mp4\" />\n </video>\n\n {/* Gradient Overlay */}\n <div\n style={{\n position: 'absolute',\n inset: 0,\n background: 'linear-gradient(to bottom, transparent, transparent, black)',\n zIndex: 0,\n pointerEvents: 'none',\n }}\n />\n\n {/* Zo Logo */}\n <div style={{ position: 'absolute', left: '24px', top: '40px', width: '40px', height: '40px', zIndex: 50 }}>\n <img src={logoUrl} alt=\"Zo\" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />\n </div>\n\n {/* Main Container */}\n <div\n style={{\n position: 'relative',\n zIndex: 10,\n width: '100%',\n height: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n overflowY: 'auto',\n paddingTop: '120px',\n paddingBottom: '40px',\n }}\n >\n {/* INPUT STEP */}\n {step === 'input' && (\n <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', width: '100%', maxWidth: '360px', padding: '0 24px' }}>\n {/* Title */}\n <h1\n style={{\n fontFamily: 'Syne, system-ui, sans-serif',\n fontWeight: 800,\n color: 'white',\n textAlign: 'center',\n textTransform: 'uppercase',\n letterSpacing: '0.32px',\n lineHeight: 1.2,\n marginBottom: '24px',\n fontSize: 'clamp(24px, 6vw, 48px)',\n }}\n >\n WHO ARE YOU?\n </h1>\n\n {/* Subtitle */}\n <p\n style={{\n color: 'rgba(255, 255, 255, 0.6)',\n textAlign: 'center',\n lineHeight: 1.5,\n marginBottom: '40px',\n fontSize: 'clamp(14px, 2vw, 16px)',\n }}\n >\n A difficult question, I know. We'll get to it.\n <br />\n But let's start with choosing a nick.\n </p>\n\n {/* Nickname Input */}\n <input\n type=\"text\"\n value={nickname}\n onChange={handleNicknameChange}\n placeholder=\"samurai\"\n maxLength={16}\n style={{\n width: '100%',\n height: '56px',\n padding: '0 20px',\n backgroundColor: 'black',\n border: '1px solid #49494A',\n borderRadius: '12px',\n color: 'white',\n fontSize: '16px',\n marginBottom: '40px',\n }}\n autoFocus\n />\n\n {/* Body Type Selection */}\n <div style={{ width: '100%', marginBottom: '32px' }}>\n <p style={{ color: 'rgba(255, 255, 255, 0.8)', fontSize: '14px', textAlign: 'center', marginBottom: '16px' }}>\n Choose your avatar style\n </p>\n\n <div style={{ display: 'flex', gap: '16px', justifyContent: 'center' }}>\n {/* Bae Option */}\n <button\n onClick={() => setBodyType('bae')}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '8px',\n padding: '16px',\n borderRadius: '16px',\n border: bodyType === 'bae' ? '2px solid #CFFF50' : '2px solid rgba(255, 255, 255, 0.3)',\n backgroundColor: bodyType === 'bae' ? 'rgba(255, 255, 255, 0.3)' : 'rgba(255, 255, 255, 0.2)',\n cursor: 'pointer',\n minWidth: '120px',\n transform: bodyType === 'bae' ? 'scale(1.05)' : 'scale(1)',\n transition: 'all 0.3s',\n }}\n >\n <div style={{ width: '64px', height: '64px', borderRadius: '50%', overflow: 'hidden', backgroundColor: 'rgba(255, 255, 255, 0.1)' }}>\n <img src={baeAvatarUrl} alt=\"Bae\" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />\n </div>\n <span style={{ color: 'white', fontSize: '14px', fontWeight: 500 }}>Bae</span>\n </button>\n\n {/* Bro Option */}\n <button\n onClick={() => setBodyType('bro')}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '8px',\n padding: '16px',\n borderRadius: '16px',\n border: bodyType === 'bro' ? '2px solid #CFFF50' : '2px solid rgba(255, 255, 255, 0.3)',\n backgroundColor: bodyType === 'bro' ? 'rgba(255, 255, 255, 0.3)' : 'rgba(255, 255, 255, 0.2)',\n cursor: 'pointer',\n minWidth: '120px',\n transform: bodyType === 'bro' ? 'scale(1.05)' : 'scale(1)',\n transition: 'all 0.3s',\n }}\n >\n <div style={{ width: '64px', height: '64px', borderRadius: '50%', overflow: 'hidden', backgroundColor: 'rgba(255, 255, 255, 0.1)' }}>\n <img src={broAvatarUrl} alt=\"Bro\" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />\n </div>\n <span style={{ color: 'white', fontSize: '14px', fontWeight: 500 }}>Bro</span>\n </button>\n </div>\n </div>\n\n {/* Location Button */}\n <div style={{ width: '100%', marginBottom: '24px' }}>\n {!locationEnabled ? (\n <button\n onClick={handleLocationEnable}\n disabled={isLoadingLocation}\n style={{\n width: '100%',\n height: '48px',\n backgroundColor: 'rgba(255, 255, 255, 0.1)',\n border: '1px solid rgba(255, 255, 255, 0.2)',\n borderRadius: '12px',\n color: 'rgba(255, 255, 255, 0.8)',\n fontSize: '14px',\n cursor: isLoadingLocation ? 'wait' : 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n }}\n >\n 📍 {isLoadingLocation ? 'Detecting...' : 'Enable Location'}\n </button>\n ) : (\n <div\n style={{\n width: '100%',\n height: '48px',\n backgroundColor: 'rgba(207, 255, 80, 0.1)',\n border: '1px solid rgba(207, 255, 80, 0.5)',\n borderRadius: '12px',\n color: '#CFFF50',\n fontSize: '14px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n }}\n >\n 📍 <span style={{ color: 'white' }}>{city}</span>\n </div>\n )}\n </div>\n\n {/* Submit Button */}\n <button\n onClick={handleSubmit}\n disabled={!canSubmit}\n style={{\n width: '100%',\n height: '56px',\n backgroundColor: 'white',\n border: 'none',\n borderRadius: '12px',\n color: 'black',\n fontSize: '16px',\n fontWeight: 500,\n cursor: canSubmit ? 'pointer' : 'not-allowed',\n opacity: canSubmit ? 1 : 0.5,\n }}\n >\n {isSaving ? 'Processing...' : 'Get Citizenship'}\n </button>\n\n {/* Error */}\n {error && (\n <p style={{ color: '#ef4444', fontSize: '14px', marginTop: '16px', textAlign: 'center' }}>\n {error}\n </p>\n )}\n </div>\n )}\n\n {/* GENERATING STEP */}\n {step === 'generating' && (\n <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n <div\n style={{\n width: '200px',\n height: '200px',\n borderRadius: '50%',\n border: '2px solid rgba(255, 255, 255, 0.2)',\n backgroundColor: 'rgba(255, 255, 255, 0.1)',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n }}\n >\n <img\n src={bodyType === 'bro' ? broAvatarUrl : baeAvatarUrl}\n alt=\"Generating...\"\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n opacity: 0.8,\n animation: 'pulse 2s ease-in-out infinite',\n }}\n />\n </div>\n </div>\n )}\n\n {/* SUCCESS STEP */}\n {step === 'success' && (\n <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n {/* Avatar */}\n <div\n style={{\n width: '200px',\n height: '200px',\n borderRadius: '50%',\n border: '4px solid white',\n boxShadow: '0 0 40px rgba(255, 255, 255, 0.6)',\n overflow: 'hidden',\n }}\n >\n <img\n src={avatarUrl || (bodyType === 'bro' ? broAvatarUrl : baeAvatarUrl)}\n alt=\"Avatar\"\n style={{ width: '100%', height: '100%', objectFit: 'cover' }}\n />\n </div>\n\n {/* Success Button */}\n <button\n onClick={handleComplete}\n style={{\n position: 'fixed',\n bottom: '40px',\n left: '50%',\n transform: 'translateX(-50%)',\n width: '90%',\n maxWidth: '360px',\n height: '56px',\n backgroundColor: 'white',\n border: 'none',\n borderRadius: '12px',\n color: 'black',\n fontSize: '16px',\n fontWeight: 700,\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n cursor: 'pointer',\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.3)',\n }}\n >\n Zo Zo Zo! Let's Go\n </button>\n </div>\n )}\n </div>\n\n {/* CSS Animation */}\n <style>{`\n @keyframes pulse {\n 0%, 100% { transform: scale(1); opacity: 0.8; }\n 50% { transform: scale(1.05); opacity: 1; }\n }\n `}</style>\n </div>\n );\n};\n\n","// src/hooks/useAuth.ts\n// Hook for authentication state and operations\n\nimport { useState, useCallback } from 'react';\nimport { useZoPassport } from '../react';\n\nexport function useAuth() {\n const { sdk, user, isAuthenticated, isLoading, sendOTP, verifyOTP, logout } = useZoPassport();\n const [otpSent, setOtpSent] = useState(false);\n const [phoneNumber, setPhoneNumber] = useState('');\n const [countryCode, setCountryCode] = useState('91');\n\n const handleSendOTP = useCallback(async (code: string, phone: string) => {\n setCountryCode(code);\n setPhoneNumber(phone);\n const result = await sendOTP(code, phone);\n if (result.success) {\n setOtpSent(true);\n }\n return result;\n }, [sendOTP]);\n\n const handleVerifyOTP = useCallback(async (otp: string) => {\n const result = await verifyOTP(countryCode, phoneNumber, otp);\n if (result.success) {\n setOtpSent(false);\n }\n return result;\n }, [verifyOTP, countryCode, phoneNumber]);\n\n const handleLogout = useCallback(async () => {\n await logout();\n setOtpSent(false);\n setPhoneNumber('');\n }, [logout]);\n\n return {\n user,\n isAuthenticated,\n isLoading,\n otpSent,\n phoneNumber,\n countryCode,\n sendOTP: handleSendOTP,\n verifyOTP: handleVerifyOTP,\n logout: handleLogout,\n };\n}\n\n","// src/hooks/useProfile.ts\n// Hook for profile operations\n\nimport { useState, useCallback, useEffect } from 'react';\nimport { useZoPassport } from '../react';\nimport type { ZoUser, ZoProfileUpdatePayload } from '../lib/types';\n\nexport function useProfile() {\n const { sdk, user, isAuthenticated, refreshProfile } = useZoPassport();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Profile completion calculation\n const completion = user ? calculateCompletion(user) : { done: 0, total: 10, percentage: 0 };\n\n // Founder status\n const isFounder = user?.membership === 'founder';\n\n // Update profile\n const updateProfile = useCallback(async (updates: ZoProfileUpdatePayload) => {\n if (!sdk) return { success: false, error: 'SDK not initialized' };\n\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await sdk.updateProfile(updates);\n if (!result.success) {\n setError(result.error || 'Failed to update profile');\n }\n return result;\n } finally {\n setIsLoading(false);\n }\n }, [sdk]);\n\n // Refresh profile\n const reload = useCallback(async () => {\n setIsLoading(true);\n try {\n await refreshProfile();\n } finally {\n setIsLoading(false);\n }\n }, [refreshProfile]);\n\n return {\n user,\n isAuthenticated,\n isLoading,\n error,\n completion,\n isFounder,\n updateProfile,\n reload,\n };\n}\n\n// Helper function to calculate profile completion\nfunction calculateCompletion(user: ZoUser): { done: number; total: number; percentage: number } {\n const fields = [\n user.first_name,\n user.last_name,\n user.bio,\n user.date_of_birth,\n user.place_name,\n user.body_type,\n user.pfp_image,\n user.email_address,\n user.wallet_address,\n (user.cultures?.length ?? 0) > 0,\n ];\n\n const done = fields.filter(f => !!f).length;\n const total = fields.length;\n const percentage = Math.round((done / total) * 100);\n\n return { done, total, percentage };\n}\n\n","// src/hooks/useAvatar.ts\n// Hook for avatar operations\n\nimport { useState, useCallback } from 'react';\nimport { useZoPassport } from '../react';\n\nexport function useAvatar() {\n const { sdk, user, refreshProfile } = useZoPassport();\n const [isGenerating, setIsGenerating] = useState(false);\n const [progress, setProgress] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n // Current avatar URL\n const avatarUrl = user?.avatar?.image || user?.pfp_image;\n\n // Avatar status\n const avatarStatus = user?.avatar?.status || 'completed';\n\n // Generate avatar\n const generateAvatar = useCallback(async (bodyType: 'bro' | 'bae') => {\n if (!sdk) return { success: false, error: 'SDK not initialized' };\n\n setIsGenerating(true);\n setProgress('pending');\n setError(null);\n\n try {\n const result = await sdk.generateAvatar(bodyType);\n \n if (result.success) {\n // Refresh profile to get new avatar\n await refreshProfile();\n } else {\n setError(result.error || 'Failed to generate avatar');\n }\n\n return result;\n } finally {\n setIsGenerating(false);\n setProgress(null);\n }\n }, [sdk, refreshProfile]);\n\n return {\n avatarUrl,\n avatarStatus,\n isGenerating,\n progress,\n error,\n generateAvatar,\n };\n}\n\n","// Combined Wallet Hook - Extracted from Zostel app\nimport { useCallback } from 'react';\nimport type { AxiosInstance } from 'axios';\nimport { useWalletBalance } from './useWalletBalance';\nimport { useTransactions } from './useTransactions';\n\n// Minimal interface for API client (Axios-compatible)\ninterface ApiClient {\n get: AxiosInstance['get'];\n}\n\ninterface UseWalletOptions {\n autoRefetch?: boolean;\n refetchInterval?: number;\n}\n\n/**\n * Combined hook for wallet functionality\n * Fetches both balance and transactions\n * \n * @param apiClient - Axios instance or compatible client with .get() method\n * @param options - Configuration options\n */\nexport const useWallet = (\n apiClient?: ApiClient | null,\n options?: UseWalletOptions\n) => {\n const {\n balance,\n isLoading: isLoadingBalance,\n error: balanceError,\n refetch: refetchBalance,\n } = useWalletBalance(apiClient, options);\n\n const {\n transactions,\n isLoading: isLoadingTransactions,\n error: transactionsError,\n refetch: refetchTransactions,\n loadMore,\n } = useTransactions(apiClient, options);\n\n const isLoading = isLoadingBalance || isLoadingTransactions;\n const error = balanceError || transactionsError;\n\n const refetchAll = useCallback(async () => {\n await Promise.all([refetchBalance(), refetchTransactions()]);\n }, [refetchBalance, refetchTransactions]);\n\n return {\n balance,\n transactions,\n isLoading,\n error,\n refetch: refetchAll,\n loadMore,\n };\n};\n","// Wallet Balance Hook - Extracted from Zostel app\nimport { useState, useEffect, useCallback } from 'react';\nimport type { AxiosInstance } from 'axios';\n\n// Minimal interface for API client (Axios-compatible)\ninterface ApiClient {\n get: AxiosInstance['get'];\n}\n\ninterface UseWalletBalanceOptions {\n autoRefetch?: boolean;\n refetchInterval?: number;\n}\n\n/**\n * Hook to fetch wallet balance\n * Uses API: GET /api/v1/web3/token/airdrops/summary\n * \n * @param apiClient - Axios instance or compatible client with .get() method\n * @param options - Configuration options\n */\nexport const useWalletBalance = (\n apiClient?: ApiClient | null,\n options?: UseWalletBalanceOptions\n) => {\n const [balance, setBalance] = useState<number>(0);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchBalance = useCallback(async () => {\n if (!apiClient) {\n setError(new Error('API client not provided'));\n setIsLoading(false);\n return;\n }\n\n try {\n setIsLoading(true);\n const response = await apiClient.get('/api/v1/web3/token/airdrops/summary');\n const amount = response.data?.data?.total_amount ?? 0;\n setBalance(amount);\n setError(null);\n } catch (err) {\n console.error('Failed to fetch balance:', err);\n setError(err as Error);\n } finally {\n setIsLoading(false);\n }\n }, [apiClient]);\n\n useEffect(() => {\n fetchBalance();\n\n // Auto-refetch if enabled\n if (options?.autoRefetch) {\n const interval = setInterval(fetchBalance, options.refetchInterval || 30000);\n return () => clearInterval(interval);\n }\n }, [fetchBalance, options?.autoRefetch, options?.refetchInterval]);\n\n return {\n balance,\n isLoading,\n error,\n refetch: fetchBalance,\n };\n};\n","// Transactions Hook - Extracted from Zostel app\nimport { useState, useEffect, useCallback } from 'react';\nimport type { AxiosInstance } from 'axios';\nimport type { Transaction } from '../lib/types';\n\n// Minimal interface for API client (Axios-compatible)\ninterface ApiClient {\n get: AxiosInstance['get'];\n}\n\ninterface UseTransactionsOptions {\n limit?: number;\n autoRefetch?: boolean;\n}\n\n/**\n * Hook to fetch transaction history\n * Uses API: GET /api/v1/profile/completion-grants/claims\n * \n * @param apiClient - Axios instance or compatible client with .get() method\n * @param options - Configuration options\n */\nexport const useTransactions = (\n apiClient?: ApiClient | null,\n options?: UseTransactionsOptions\n) => {\n const [transactions, setTransactions] = useState<Transaction[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [hasMore, setHasMore] = useState(false);\n\n const fetchTransactions = useCallback(async () => {\n if (!apiClient) {\n setError(new Error('API client not provided'));\n setIsLoading(false);\n return;\n }\n\n try {\n setIsLoading(true);\n const response = await apiClient.get('/api/v1/profile/completion-grants/claims', {\n params: {\n limit: options?.limit || 20,\n },\n });\n\n const results = response.data?.data?.results ?? [];\n setTransactions(results);\n setHasMore(!!response.data?.data?.next);\n setError(null);\n } catch (err) {\n console.error('Failed to fetch transactions:', err);\n setError(err as Error);\n } finally {\n setIsLoading(false);\n }\n }, [apiClient, options?.limit]);\n\n const loadMore = useCallback(async () => {\n if (!hasMore || isLoading) return;\n // TODO: Implement pagination logic\n }, [hasMore, isLoading]);\n\n useEffect(() => {\n fetchTransactions();\n\n if (options?.autoRefetch) {\n const interval = setInterval(fetchTransactions, 60000); // Refetch every minute\n return () => clearInterval(interval);\n }\n }, [fetchTransactions, options?.autoRefetch]);\n\n return {\n transactions,\n isLoading,\n error,\n hasMore,\n refetch: fetchTransactions,\n loadMore,\n };\n};\n"],"mappings":"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","names":["ZoAuth","ZoAvatar","import_react","axios","import_jsx_runtime","import_jsx_runtime","ZoAvatar","import_jsx_runtime","ZoAvatar","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","ZO_COIN_URL","STYLE_ID","CSS","ZO_COIN_URL","import_jsx_runtime","STYLE_ID","CSS","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","ZoAuth","import_react","import_jsx_runtime","ZoAuth","import_react","import_jsx_runtime","import_react","import_react","import_react","import_react","import_react","import_react","import_jsx_runtime"]}