diff --git a/apps/mobile/.env.example b/apps/mobile/.env.example index 1eb60d9..3a248bf 100644 --- a/apps/mobile/.env.example +++ b/apps/mobile/.env.example @@ -1,20 +1,18 @@ -# ─── Agronavis Mobile App Environment ───────────────────────────────────────── -# Copy to .env and fill in values. Never commit .env. +# Agronavis Mobile App Environment +# Copy to .env and fill in your actual values. Never commit .env to source control. -# ── API ─────────────────────────────────────────────────────────────────────── -EXPO_PUBLIC_API_URL=http://localhost:3001/api/v1 -EXPO_PUBLIC_API_TIMEOUT=30000 +# Supabase (Auth + Database) +EXPO_PUBLIC_SUPABASE_URL=https://YOUR_PROJECT_ID.supabase.co +EXPO_PUBLIC_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY -# ── Clerk Auth ──────────────────────────────────────────────────────────────── -EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_YOUR_CLERK_KEY_HERE +# API (FastAPI backend — will be deployed on HuggingFace Spaces) +EXPO_PUBLIC_API_URL=http://localhost:8000/api/v1 +EXPO_PUBLIC_API_TIMEOUT=30000 -# ── Maps ────────────────────────────────────────────────────────────────────── +# Maps EXPO_PUBLIC_GOOGLE_MAPS_API_KEY=YOUR_GOOGLE_MAPS_KEY -# ── AI Services ─────────────────────────────────────────────────────────────── -EXPO_PUBLIC_ML_SERVICE_URL=http://localhost:8000 - -# ── Feature Flags ───────────────────────────────────────────────────────────── +# Feature Flags EXPO_PUBLIC_ENABLE_SAHAYAK=true EXPO_PUBLIC_ENABLE_MARKET_PRICES=true EXPO_PUBLIC_ENABLE_IOT=false diff --git a/apps/mobile/app.json b/apps/mobile/app.json index e6c99a2..f5fcd05 100644 --- a/apps/mobile/app.json +++ b/apps/mobile/app.json @@ -30,7 +30,7 @@ "foregroundImage": "./assets/images/adaptive-icon.png", "backgroundColor": "#0E3D1F" }, - "package": "com.karolix.agronavis", + "package": "com.agronavis.app", "permissions": [ "android.permission.CAMERA", "android.permission.ACCESS_FINE_LOCATION", diff --git a/apps/mobile/app/(auth)/_layout.tsx b/apps/mobile/app/(auth)/_layout.tsx index 67e81ce..1b490f4 100644 --- a/apps/mobile/app/(auth)/_layout.tsx +++ b/apps/mobile/app/(auth)/_layout.tsx @@ -6,7 +6,6 @@ export default function AuthLayout() { - ); } diff --git a/apps/mobile/app/(auth)/login.tsx b/apps/mobile/app/(auth)/login.tsx index 5296c01..fac482b 100644 --- a/apps/mobile/app/(auth)/login.tsx +++ b/apps/mobile/app/(auth)/login.tsx @@ -2,37 +2,52 @@ import { useState } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, KeyboardAvoidingView, Platform, - ScrollView, ActivityIndicator, StatusBar, + ScrollView, ActivityIndicator, StatusBar, Alert, } from 'react-native'; import { useRouter } from 'expo-router'; +import { useForm, Controller } from 'react-hook-form'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { z } from 'zod'; import { LinearGradient } from 'expo-linear-gradient'; import { MaterialIcons } from '@expo/vector-icons'; import { Colors, Radii } from '@/constants/theme'; +import { supabase } from '@/utils/supabase'; -function SocialBtn({ icon, label }: { icon: React.ComponentProps['name']; label: string }) { - return ( - - - {label} - - ); -} +// ─── Validation Schema ──────────────────────────────────────────────────────── + +const loginSchema = z.object({ + email: z.string().email('Enter a valid email address'), + password: z.string().min(8, 'Password must be at least 8 characters'), +}); + +type LoginFields = z.infer; + +// ─── Component ──────────────────────────────────────────────────────────────── export default function LoginScreen() { const router = useRouter(); - - const [email, setEmail] = useState(''); - const [password, setPassword] = useState(''); const [showPass, setShowPass] = useState(false); - const [loading, setLoading] = useState(false); + const { + control, + handleSubmit, + formState: { errors, isSubmitting }, + } = useForm({ + resolver: zodResolver(loginSchema), + defaultValues: { email: '', password: '' }, + }); + + const onSubmit = async (data: LoginFields) => { + const { error } = await supabase.auth.signInWithPassword({ + email: data.email, + password: data.password, + }); + + if (!error) { + // onAuthStateChange in useAuthStore and the root layout guard handle routing + return; + } - const handleLogin = () => { - setLoading(true); - // Simulate brief loading then navigate - setTimeout(() => { - setLoading(false); - router.replace('/(tabs)/dashboard'); - }, 600); + Alert.alert('Login failed', error.message); }; return ( @@ -56,40 +71,55 @@ export default function LoginScreen() { {/* Email */} Email - + - ( + + )} /> + {errors.email && {errors.email.message}} {/* Password */} Password - + Forgot Password? - + - ( + + )} /> setShowPass(p => !p)}> + {errors.password && {errors.password.message}} {/* Submit */} - + - {loading + {isSubmitting ? : Log In} - {/* Divider */} - - - Or continue with - - - - {/* Social stubs */} - - - - - {/* Footer */} - Don't have an account? - router.push('/(auth)/register')}> + Don't have an account? + router.push('/(auth)/register')}> Sign up @@ -168,10 +192,14 @@ const styles = StyleSheet.create({ borderRadius: Radii.lg, height: 56, paddingHorizontal: 14, + borderWidth: 1, + borderColor: 'transparent', }, + inputError: { borderColor: '#ef4444' }, inputIcon: { marginRight: 10 }, input: { flex: 1, fontSize: 15, fontWeight: '400', color: Colors.onSurface }, eyeBtn: { padding: 4 }, + fieldError: { fontSize: 12, color: '#ef4444', fontWeight: '500' }, submitBtn: { height: 56, borderRadius: Radii.xxl, @@ -184,20 +212,6 @@ const styles = StyleSheet.create({ elevation: 5, }, submitText: { fontSize: 17, fontWeight: '700', color: Colors.onPrimary, letterSpacing: 0.2 }, - divider: { flexDirection: 'row', alignItems: 'center', gap: 10 }, - dividerLine: { flex: 1, height: 1, backgroundColor: Colors.outlineVariant, opacity: 0.5 }, - dividerLabel: { fontSize: 13, color: Colors.onSurfaceVariant, fontWeight: '500' }, - socials: { gap: 10 }, - socialBtn: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - gap: 10, - height: 52, - borderRadius: Radii.lg, - backgroundColor: Colors.surfaceContainerHigh, - }, - socialLabel: { fontSize: 15, fontWeight: '600', color: Colors.onSurface }, footer: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', paddingTop: 4 }, footerText: { fontSize: 14, color: Colors.onSurfaceVariant }, footerLink: { fontSize: 14, fontWeight: '700', color: Colors.primary }, diff --git a/apps/mobile/app/(auth)/register.tsx b/apps/mobile/app/(auth)/register.tsx index 8ed740a..37be9e7 100644 --- a/apps/mobile/app/(auth)/register.tsx +++ b/apps/mobile/app/(auth)/register.tsx @@ -2,30 +2,64 @@ import { useState } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, KeyboardAvoidingView, Platform, ScrollView, - ActivityIndicator, StatusBar, + ActivityIndicator, StatusBar, Alert, } from 'react-native'; import { useRouter } from 'expo-router'; +import { useForm, Controller } from 'react-hook-form'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { z } from 'zod'; import { LinearGradient } from 'expo-linear-gradient'; import { MaterialIcons } from '@expo/vector-icons'; import { Colors, Radii } from '@/constants/theme'; +import { supabase } from '@/utils/supabase'; + +// ─── Validation Schema ──────────────────────────────────────────────────────── + +const registerSchema = z.object({ + fullName: z + .string() + .min(2, 'Full name must be at least 2 characters') + .max(80, 'Name is too long'), + email: z.string().email('Enter a valid email address'), + password: z + .string() + .min(8, 'Password must be at least 8 characters') + .regex(/[0-9!@#$%^&*]/, 'Password must include a number or special character'), + agreed: z.literal(true, { + errorMap: () => ({ message: 'You must accept the terms to continue' }), + }), +}); + +type RegisterFields = z.infer; + +// ─── Component ──────────────────────────────────────────────────────────────── export default function RegisterScreen() { const router = useRouter(); - - const [fullName, setFullName] = useState(''); - const [email, setEmail] = useState(''); - const [password, setPassword] = useState(''); const [showPass, setShowPass] = useState(false); - const [agreed, setAgreed] = useState(false); - const [loading, setLoading] = useState(false); - - const handleRegister = () => { - if (!agreed) return; - setLoading(true); - setTimeout(() => { - setLoading(false); - router.push('/(onboarding)/step1' as any); - }, 600); + + const { + control, + handleSubmit, + watch, + formState: { errors, isSubmitting }, + } = useForm({ + resolver: zodResolver(registerSchema), + defaultValues: { fullName: '', email: '', password: '', agreed: undefined }, + }); + + const agreedValue = watch('agreed'); + + const onSubmit = async (data: RegisterFields) => { + const { error } = await supabase.auth.signUp({ + email: data.email, + password: data.password, + options: { data: { full_name: data.fullName } }, + }); + + if (error) { + Alert.alert('Registration failed', error.message); + } }; return ( @@ -50,52 +84,75 @@ export default function RegisterScreen() { {/* Full Name */} Full Name - + - ( + + )} /> + {errors.fullName && {errors.fullName.message}} {/* Email */} Email - + - ( + + )} /> + {errors.email && {errors.email.message}} {/* Password */} Password - + - ( + + )} /> setShowPass(p => !p)}> + {errors.password && {errors.password.message}} {/* Terms */} - setAgreed(a => !a)} - activeOpacity={0.8} - > - {agreed && } - + ( + onChange(value ? undefined : true)} + activeOpacity={0.8} + > + {value && } + + )} + /> I agree to the{' '} Terms and Conditions + {errors.agreed && {errors.agreed.message}} {/* Submit */} - + - {loading + {isSubmitting ? : Create Account} @@ -139,7 +210,7 @@ export default function RegisterScreen() { {/* Footer */} Already have an account? - router.push('/(auth)/login')}> + router.push('/(auth)/login')}> Log in @@ -150,8 +221,8 @@ export default function RegisterScreen() { } const styles = StyleSheet.create({ - root: { flex: 1, backgroundColor: Colors.surface }, - scroll: { flexGrow: 1, justifyContent: 'center', padding: 24 }, + root: { flex: 1, backgroundColor: Colors.surface }, + scroll: { flexGrow: 1, justifyContent: 'center', padding: 24 }, card: { backgroundColor: Colors.surfaceContainerLow, borderRadius: Radii.xl, @@ -176,10 +247,14 @@ const styles = StyleSheet.create({ borderRadius: Radii.lg, height: 52, paddingHorizontal: 14, + borderWidth: 1, + borderColor: 'transparent', }, + inputError: { borderColor: '#ef4444' }, icon: { marginRight: 10 }, input: { flex: 1, fontSize: 15, fontWeight: '400', color: Colors.onSurface }, eyeBtn: { padding: 4 }, + fieldError: { fontSize: 12, color: '#ef4444', fontWeight: '500' }, terms: { flexDirection: 'row', alignItems: 'center', gap: 10 }, checkbox: { width: 22, height: 22, borderRadius: 6, borderWidth: 2, diff --git a/apps/mobile/app/(auth)/verify.tsx b/apps/mobile/app/(auth)/verify.tsx deleted file mode 100644 index 74156ea..0000000 --- a/apps/mobile/app/(auth)/verify.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { useEffect } from 'react'; -import { View, ActivityIndicator, StyleSheet } from 'react-native'; -import { useRouter } from 'expo-router'; -import { Colors } from '@/constants/theme'; - -// Verification is handled server-side — this screen redirects to dashboard. -export default function VerifyScreen() { - const router = useRouter(); - useEffect(() => { - const t = setTimeout(() => router.replace('/(tabs)/dashboard'), 500); - return () => clearTimeout(t); - }, []); - return ( - - - - ); -} - -const styles = StyleSheet.create({ - root: { flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: Colors.surface }, -}); diff --git a/apps/mobile/app/_layout.tsx b/apps/mobile/app/_layout.tsx index 416658d..cf27599 100644 --- a/apps/mobile/app/_layout.tsx +++ b/apps/mobile/app/_layout.tsx @@ -1,19 +1,109 @@ -import { Stack } from 'expo-router'; +import { useEffect } from 'react'; +import { Stack, useRouter, useSegments } from 'expo-router'; +import * as Linking from 'expo-linking'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; -import { StatusBar } from 'react-native'; +import { StatusBar, View, Text, StyleSheet } from 'react-native'; +import { useAuthStore } from '@/store/useAuthStore'; +import { supabase } from '@/utils/supabase'; +import { Colors } from '@/constants/theme'; +/** + * Root layout — handles three responsibilities: + * + * 1. Auth hydration: calls initialize() to pull the persisted session and + * subscribe to every future auth state change. + * + * 2. Protected routing: redirects unauthenticated users to /(auth)/welcome + * and authenticated users away from the auth group. + * + * 3. Deep link handling: captures Supabase email confirmation URLs that contain + * #access_token or #error fragments and passes them to setSession before any + * route redirect fires. This prevents the race condition where the app routes + * before the session is committed. + */ export default function RootLayout() { + const router = useRouter(); + const segments = useSegments(); + const url = Linking.useURL(); + + const { session, isLoading, isOffline, initialize, setSession } = useAuthStore(); + + // One-time initialization: hydrate from storage + subscribe to auth events + useEffect(() => { + const unsubscribe = initialize(); + return unsubscribe; + }, []); + + // Handle deep links containing Supabase auth hash fragments + useEffect(() => { + if (!url) return; + + // Supabase email confirmation URLs embed the token as a hash fragment + const fragment = url.includes('#') ? url.split('#')[1] : ''; + if (!fragment) return; + + const params = new URLSearchParams(fragment); + const accessToken = params.get('access_token'); + const refreshToken = params.get('refresh_token'); + + if (accessToken && refreshToken) { + supabase.auth + .setSession({ access_token: accessToken, refresh_token: refreshToken }) + .then(({ data, error }) => { + if (!error && data.session) { + setSession(data.session); + } + }); + } + }, [url]); + + // Protected routing guard — runs whenever auth state or route changes + useEffect(() => { + if (isLoading) return; + + const inAuthGroup = segments[0] === '(auth)'; + + if (!session && !inAuthGroup) { + router.replace('/(auth)/welcome'); + } else if (session && inAuthGroup) { + router.replace('/(tabs)/dashboard'); + } + }, [session, isLoading, segments]); + + // Offline banner — shows when the session persists but network is unreachable + const offlineBanner = isOffline ? ( + + No connection — working offline + + ) : null; + return ( - + + {offlineBanner} - {/* Standalone modal-style screens accessible from any tab */} - - + + + ); } + +const styles = StyleSheet.create({ + offlineBanner: { + backgroundColor: '#92400e', + paddingVertical: 6, + paddingHorizontal: 16, + alignItems: 'center', + }, + offlineText: { + color: '#fef3c7', + fontSize: 12, + fontWeight: '600', + letterSpacing: 0.2, + }, +}); diff --git a/apps/mobile/app/index.tsx b/apps/mobile/app/index.tsx index 6ac8091..56e2bd0 100644 --- a/apps/mobile/app/index.tsx +++ b/apps/mobile/app/index.tsx @@ -2,10 +2,9 @@ import { Redirect } from 'expo-router'; /** * Root index — Expo Router needs this file to handle the app's entry URL. - * Redirects immediately to the auth welcome screen. - * Once authentication is integrated (Clerk), add your auth check here: - * - isSignedIn → redirect to /(tabs) - * - not signed in → redirect to /(auth)/welcome + * The root _layout.tsx handles session hydration and protected routing via + * useAuthStore. This file always redirects to /(auth)/welcome; the layout + * guard will immediately push to /(tabs)/dashboard if a session exists. */ export default function Index() { return ; diff --git a/apps/mobile/app/profile/edit.tsx b/apps/mobile/app/profile/edit.tsx new file mode 100644 index 0000000..0ddc6fe --- /dev/null +++ b/apps/mobile/app/profile/edit.tsx @@ -0,0 +1,296 @@ +import { useState, useEffect } from 'react'; +import { + View, Text, TextInput, TouchableOpacity, + StyleSheet, StatusBar, ScrollView, + Image, ActivityIndicator, Alert, + KeyboardAvoidingView, Platform, +} from 'react-native'; +import { useRouter } from 'expo-router'; +import { MaterialIcons } from '@expo/vector-icons'; +import { useForm, Controller } from 'react-hook-form'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { z } from 'zod'; +import * as ImagePicker from 'expo-image-picker'; +import { Colors, Radii } from '@/constants/theme'; +import { useAuthStore } from '@/store/useAuthStore'; +import { supabase } from '@/utils/supabase'; + +const schema = z.object({ + full_name: z.string().min(2, 'Name must be at least 2 characters'), + phone: z.string().max(15).optional().or(z.literal('')), + state: z.string().max(60).optional().or(z.literal('')), + district: z.string().max(60).optional().or(z.literal('')), +}); + +type FormFields = z.infer; + +export default function EditProfileScreen() { + const router = useRouter(); + const user = useAuthStore(state => state.user); + + const [avatarUri, setAvatarUri] = useState(null); + const [uploading, setUploading] = useState(false); + + const { control, handleSubmit, reset, formState: { errors, isSubmitting } } = useForm({ + resolver: zodResolver(schema), + defaultValues: { full_name: '', phone: '', state: '', district: '' }, + }); + + useEffect(() => { + if (!user) return; + supabase + .from('farmers') + .select('full_name, phone, state, district, avatar_url') + .eq('id', user.id) + .single() + .then(({ data }) => { + if (!data) return; + reset({ + full_name: data.full_name ?? '', + phone: data.phone ?? '', + state: data.state ?? '', + district: data.district ?? '', + }); + if (data.avatar_url) setAvatarUri(data.avatar_url); + }); + }, [user, reset]); + + const pickAndUpload = async () => { + const result = await ImagePicker.launchImageLibraryAsync({ + mediaTypes: ['images'], + allowsEditing: true, + aspect: [1, 1], + quality: 0.7, + }); + if (result.canceled || !user) return; + + const asset = result.assets[0]; + const rawExt = asset.uri.split('.').pop()?.toLowerCase() ?? 'jpg'; + const ext = rawExt === 'jpg' ? 'jpeg' : rawExt; + const mimeType = `image/${ext}`; + const path = `${user.id}/avatar.${ext}`; + + setUploading(true); + let arrayBuffer: ArrayBuffer; + try { + const response = await fetch(asset.uri); + arrayBuffer = await response.arrayBuffer(); + } catch (e) { + setUploading(false); + Alert.alert('Upload failed', 'Could not read image file.'); + return; + } + + const { error } = await supabase.storage + .from('avatars') + .upload(path, arrayBuffer, { upsert: true, contentType: mimeType }); + + if (error) { + setUploading(false); + Alert.alert('Upload failed', error.message); + return; + } + + const { data: urlData } = supabase.storage.from('avatars').getPublicUrl(path); + const publicUrl = `${urlData.publicUrl}?t=${Date.now()}`; + + await supabase.from('farmers').update({ avatar_url: publicUrl }).eq('id', user.id); + setAvatarUri(publicUrl); + setUploading(false); + }; + + const onSubmit = async (data: FormFields) => { + if (!user) return; + const { error } = await supabase + .from('farmers') + .update({ + full_name: data.full_name, + phone: data.phone || null, + state: data.state || null, + district: data.district || null, + }) + .eq('id', user.id); + + if (error) { + Alert.alert('Save failed', error.message); + return; + } + router.back(); + }; + + return ( + + + + + router.back()} style={styles.iconBtn}> + + + Edit Profile + + + + + + {avatarUri ? ( + + ) : ( + + + + )} + + {uploading + ? + : } + + + + + + ( + + )} + /> + + + + ( + + )} + /> + + + + ( + + )} + /> + + + + ( + + )} + /> + + + + + {isSubmitting + ? + : Save Changes} + + + + + + ); +} + +function Field({ label, error, children }: { label: string; error?: string; children: React.ReactNode }) { + return ( + + {label} + + {children} + + {error ? {error} : null} + + ); +} + +const styles = StyleSheet.create({ + root: { flex: 1, backgroundColor: Colors.surface }, + header: { + flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', + paddingHorizontal: 20, paddingTop: 52, paddingBottom: 14, + backgroundColor: 'rgba(248,249,255,0.95)', + shadowColor: '#0b1c30', shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.06, shadowRadius: 12, elevation: 6, + }, + iconBtn: { padding: 8, borderRadius: Radii.full, backgroundColor: Colors.surfaceContainerHigh, width: 38, height: 38, alignItems: 'center', justifyContent: 'center' }, + headerTitle: { fontSize: 18, fontWeight: '800', color: Colors.onSurface }, + scroll: { paddingHorizontal: 20, paddingTop: 28, gap: 20, alignItems: 'center' }, + + avatarWrap: { + width: 110, height: 110, borderRadius: 55, + overflow: 'hidden', + shadowColor: '#0b1c30', shadowOffset: { width: 0, height: 6 }, + shadowOpacity: 0.1, shadowRadius: 16, elevation: 6, + }, + avatar: { width: 110, height: 110 }, + avatarPlaceholder: { backgroundColor: Colors.surfaceContainerHighest, alignItems: 'center', justifyContent: 'center' }, + avatarOverlay: { + position: 'absolute', bottom: 0, left: 0, right: 0, + height: 36, backgroundColor: 'rgba(0,0,0,0.45)', + alignItems: 'center', justifyContent: 'center', + }, + + form: { width: '100%', gap: 14 }, + fieldGroup: { gap: 6 }, + label: { fontSize: 13, fontWeight: '600', color: Colors.onSurface }, + inputWrap: { + backgroundColor: Colors.surfaceContainerHighest, + borderRadius: Radii.lg, height: 52, + paddingHorizontal: 14, borderWidth: 1, borderColor: 'transparent', + justifyContent: 'center', + }, + inputError: { borderColor: '#ef4444' }, + input: { fontSize: 15, color: Colors.onSurface, fontWeight: '400' }, + fieldError: { fontSize: 12, color: '#ef4444', fontWeight: '500' }, + + saveBtn: { + width: '100%', height: 54, borderRadius: Radii.xxl, + backgroundColor: Colors.primary, alignItems: 'center', justifyContent: 'center', + shadowColor: Colors.primary, shadowOffset: { width: 0, height: 8 }, + shadowOpacity: 0.3, shadowRadius: 16, elevation: 5, + }, + saveBtnText: { fontSize: 16, fontWeight: '700', color: Colors.onPrimary }, +}); diff --git a/apps/mobile/app/profile/index.tsx b/apps/mobile/app/profile/index.tsx index 4f1cd2a..11ae370 100644 --- a/apps/mobile/app/profile/index.tsx +++ b/apps/mobile/app/profile/index.tsx @@ -1,138 +1,138 @@ +import { useState, useCallback } from 'react'; import { View, Text, ScrollView, TouchableOpacity, - StyleSheet, StatusBar, Image, + StyleSheet, StatusBar, Image, ActivityIndicator, } from 'react-native'; -import { useRouter } from 'expo-router'; +import { useRouter, useFocusEffect } from 'expo-router'; import { LinearGradient } from 'expo-linear-gradient'; import { MaterialIcons } from '@expo/vector-icons'; import { Colors, Radii } from '@/constants/theme'; +import { useAuthStore } from '@/store/useAuthStore'; +import { supabase } from '@/utils/supabase'; + +type Farmer = { + full_name: string; + email: string; + phone: string | null; + state: string | null; + district: string | null; + avatar_url: string | null; +}; + +function avatarUri(farmer: Farmer): string { + if (farmer.avatar_url) return farmer.avatar_url; + const seed = encodeURIComponent(farmer.full_name || farmer.email); + return `https://api.dicebear.com/7.x/personas/png?seed=${seed}&size=200`; +} -const AVATAR_URL = 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&q=80'; +export default function ProfileScreen() { + const router = useRouter(); + const user = useAuthStore(state => state.user); + const signOut = useAuthStore(state => state.signOut); -const STATS = [ - { label: 'Total Acreage', value: '1,240', unit: 'ac', span: 2, icon: 'landscape' as const }, - { label: 'Active Crops', value: 'Wheat, Soy', unit: '', span: 1, icon: 'eco' as const }, - { label: 'Soil Health', value: '92%', unit: '', span: 1, icon: 'science' as const }, -]; + const [farmer, setFarmer] = useState(null); + const [loading, setLoading] = useState(true); -const CERTS = [ - { icon: 'verified' as const, title: 'Organic Certified', sub: 'Valid until Dec 2025' }, - { icon: 'handshake' as const, title: 'Fair Trade', sub: 'Verified Partner' }, -]; + const fetchFarmer = useCallback(async () => { + if (!user) return; + const { data } = await supabase + .from('farmers') + .select('full_name, email, phone, state, district, avatar_url') + .eq('id', user.id) + .single(); + if (data) setFarmer(data); + setLoading(false); + }, [user]); -export default function ProfileScreen() { - const router = useRouter(); + useFocusEffect(useCallback(() => { fetchFarmer(); }, [fetchFarmer])); + + const locationLabel = [farmer?.district, farmer?.state].filter(Boolean).join(', '); return ( - {/* Header */} - router.back()} style={styles.backBtn}> + router.back()} style={styles.iconBtn}> Profile - router.push('/(tabs)/farm/settings' as any)} - > - - + - - {/* Profile hero */} - - - - - + {loading ? ( + + + + ) : ( + + + + + + {farmer?.full_name ?? ''} + {farmer?.email ?? ''} + {locationLabel ? ( + + + {locationLabel} + + ) : null} + router.push('/profile/edit' as any)} + > + + Edit Profile + - Rajesh Kumar - - - Region: Northern Plains - - - - Edit Profile - - - - {/* Farm Stats */} - Farm Stats - - {/* Wide card */} - - - - {STATS[0].label} - - {STATS[0].value} - {STATS[0].unit} - - - - + + + + + - {/* Two half cards */} - {STATS.slice(1).map(stat => ( - - {stat.label} - {stat.label === 'Soil Health' ? ( - <> - {stat.value} - - - - - ) : ( - {stat.value} - )} - - ))} - - {/* Certifications */} - Certifications - - {CERTS.map(cert => ( - - - - - - {cert.title} - {cert.sub} - - - ))} - + signOut()} + activeOpacity={0.85} + > + + Log Out + - {/* Logout */} - router.replace('/(auth)/welcome')} - activeOpacity={0.85} - > - - Log Out - + + + )} + + ); +} - - +function Row({ icon, label, value }: { icon: any; label: string; value: string }) { + return ( + + + + {label} + {value} + ); } const styles = StyleSheet.create({ - root: { flex: 1, backgroundColor: Colors.surface }, + root: { flex: 1, backgroundColor: Colors.surface }, + loader: { flex: 1, alignItems: 'center', justifyContent: 'center' }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 20, paddingTop: 52, paddingBottom: 14, @@ -140,66 +140,41 @@ const styles = StyleSheet.create({ shadowColor: '#0b1c30', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.06, shadowRadius: 12, elevation: 6, }, - backBtn: { padding: 8, borderRadius: Radii.full, backgroundColor: Colors.surfaceContainerHigh }, - headerTitle: { fontSize: 18, fontWeight: '800', color: Colors.onSurface }, - settingsBtn: { padding: 8, borderRadius: Radii.full, backgroundColor: Colors.surfaceContainerHigh }, - scroll: { paddingHorizontal: 20, paddingTop: 24, gap: 14 }, - - hero: { alignItems: 'center', gap: 10 }, - avatarWrap: { position: 'relative' }, - avatar: { - width: 110, height: 110, borderRadius: 55, - borderWidth: 4, borderColor: Colors.surfaceContainerLowest, - shadowColor: '#0b1c30', shadowOffset: { width: 0, height: 10 }, - shadowOpacity: 0.1, shadowRadius: 20, elevation: 6, - }, - editAvatarBtn: { - position: 'absolute', bottom: 2, right: 2, width: 28, height: 28, - borderRadius: 14, backgroundColor: Colors.primaryContainer, - alignItems: 'center', justifyContent: 'center', - }, - name: { fontSize: 28, fontWeight: '900', letterSpacing: -0.6, color: Colors.onSurface }, - locationRow: { flexDirection: 'row', alignItems: 'center', gap: 4 }, - locationText: { fontSize: 14, color: Colors.onSurfaceVariant }, - editBtnWrap: { width: '100%', borderRadius: Radii.xl, overflow: 'hidden' }, - editBtn: { alignItems: 'center', justifyContent: 'center', height: 52 }, - editBtnText: { fontSize: 16, fontWeight: '700', color: Colors.onPrimary }, - - sectionTitle: { fontSize: 18, fontWeight: '800', color: Colors.onSurface, marginTop: 8 }, - - statsGrid: { flexDirection: 'row', flexWrap: 'wrap', gap: 10 }, - statCard: { - flex: 1, minWidth: '46%', backgroundColor: Colors.surfaceContainerLowest, - borderRadius: Radii.xl, padding: 18, gap: 6, + iconBtn: { padding: 8, borderRadius: Radii.full, backgroundColor: Colors.surfaceContainerHigh, width: 38, height: 38, alignItems: 'center', justifyContent: 'center' }, + headerTitle: { fontSize: 18, fontWeight: '800', color: Colors.onSurface }, + scroll: { paddingHorizontal: 20, paddingTop: 24, gap: 16 }, + + hero: { alignItems: 'center', gap: 8 }, + avatarWrap: { borderRadius: 60, overflow: 'hidden', width: 110, height: 110, shadowColor: '#0b1c30', shadowOffset: { width: 0, height: 8 }, shadowOpacity: 0.1, shadowRadius: 16, elevation: 6 }, + avatar: { width: 110, height: 110 }, + name: { fontSize: 26, fontWeight: '900', letterSpacing: -0.6, color: Colors.onSurface, marginTop: 4 }, + email: { fontSize: 13, color: Colors.onSurfaceVariant }, + locationRow: { flexDirection: 'row', alignItems: 'center', gap: 4 }, + locationText: { fontSize: 13, color: Colors.onSurfaceVariant }, + editBtnWrap: { width: '100%', borderRadius: Radii.xl, overflow: 'hidden', marginTop: 4 }, + editBtn: { alignItems: 'center', justifyContent: 'center', height: 52 }, + editBtnText: { fontSize: 16, fontWeight: '700', color: Colors.onPrimary }, + + infoCard: { + backgroundColor: Colors.surfaceContainerLowest, + borderRadius: Radii.xl, overflow: 'hidden', shadowColor: '#0b1c30', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.04, shadowRadius: 12, elevation: 2, }, - statCardWide: { minWidth: '100%', flexBasis: '100%' }, - statRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-end' }, - statLabel: { fontSize: 12, color: Colors.onSurfaceVariant, fontWeight: '600' }, - statValue: { fontSize: 26, fontWeight: '900', letterSpacing: -0.5, color: Colors.onSurface }, - statUnit: { fontSize: 14, fontWeight: '400', color: Colors.onSurfaceVariant }, - healthTrack: { height: 6, backgroundColor: Colors.surfaceContainer, borderRadius: 3, overflow: 'hidden' }, - healthFill: { height: '100%', backgroundColor: Colors.primary, borderRadius: 3 }, - - certsList: { gap: 10 }, - certRow: { - flexDirection: 'row', alignItems: 'center', gap: 14, - backgroundColor: Colors.surfaceContainerLow, borderRadius: Radii.xl, padding: 16, - borderWidth: 1, borderColor: Colors.outlineVariant, - }, - certIcon: { - width: 46, height: 46, borderRadius: 14, - backgroundColor: Colors.secondaryContainer, - alignItems: 'center', justifyContent: 'center', + row: { + flexDirection: 'row', alignItems: 'center', + paddingHorizontal: 18, paddingVertical: 14, + borderBottomWidth: StyleSheet.hairlineWidth, borderBottomColor: Colors.outlineVariant, }, - certTitle: { fontSize: 15, fontWeight: '700', color: Colors.onSurface }, - certSub: { fontSize: 12, color: Colors.onSurfaceVariant, marginTop: 2 }, + rowIcon: { marginRight: 14 }, + rowContent: { flex: 1 }, + rowLabel: { fontSize: 11, fontWeight: '600', color: Colors.onSurfaceVariant, textTransform: 'uppercase', letterSpacing: 0.5 }, + rowValue: { fontSize: 15, fontWeight: '500', color: Colors.onSurface, marginTop: 2 }, logoutBtn: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 8, paddingVertical: 16, borderRadius: Radii.xl, - backgroundColor: Colors.errorContainer, marginTop: 8, + backgroundColor: Colors.errorContainer, }, - logoutText: { fontSize: 15, fontWeight: '700', color: Colors.error }, + logoutText: { fontSize: 15, fontWeight: '700', color: Colors.error }, }); diff --git a/apps/mobile/eas.json b/apps/mobile/eas.json index 1a4b934..85ffbab 100644 --- a/apps/mobile/eas.json +++ b/apps/mobile/eas.json @@ -9,12 +9,21 @@ "distribution": "internal" }, "preview": { - "distribution": "internal" + "distribution": "internal", + "android": { + "buildType": "apk" + }, + "env": { + "npm_config_legacy_peer_deps": "true" + } }, "production": { "autoIncrement": true, "android": { "buildType": "apk" + }, + "env": { + "npm_config_legacy_peer_deps": "true" } } }, diff --git a/apps/mobile/eslint.config.js b/apps/mobile/eslint.config.js new file mode 100644 index 0000000..ba708ed --- /dev/null +++ b/apps/mobile/eslint.config.js @@ -0,0 +1,10 @@ +// https://docs.expo.dev/guides/using-eslint/ +const { defineConfig } = require('eslint/config'); +const expoConfig = require("eslint-config-expo/flat"); + +module.exports = defineConfig([ + expoConfig, + { + ignores: ["dist/*"], + } +]); diff --git a/apps/mobile/hooks/useRedux.ts b/apps/mobile/hooks/useRedux.ts deleted file mode 100644 index 7002cc4..0000000 --- a/apps/mobile/hooks/useRedux.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; -import type { RootState, AppDispatch } from '@store/index'; - -/** Typed dispatch hook — use this instead of plain useDispatch */ -export const useAppDispatch = () => useDispatch(); - -/** Typed selector hook — use this instead of plain useSelector */ -export const useAppSelector: TypedUseSelectorHook = useSelector; diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 4ccbff3..fdefc2a 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -20,15 +20,15 @@ }, "dependencies": { "@agronavis/shared-types": "*", - "@clerk/clerk-expo": "^2.15.2", "@expo/metro-runtime": "~6.1.2", "@expo/vector-icons": "^15.0.2", + "@hookform/resolvers": "^5.4.0", "@react-native-async-storage/async-storage": "^2.2.0", "@react-native-community/datetimepicker": "8.4.4", "@react-native-picker/picker": "2.11.1", "@react-navigation/bottom-tabs": "^7.4.0", "@react-navigation/native": "^7.1.8", - "@reduxjs/toolkit": "^2.9.0", + "@supabase/supabase-js": "^2.108.1", "axios": "^1.12.2", "expo": "~54.0.10", "expo-auth-session": "~7.0.11", @@ -52,6 +52,7 @@ "lottie-react-native": "^7.3.4", "react": "19.1.0", "react-dom": "19.1.0", + "react-hook-form": "^7.79.0", "react-native": "0.81.5", "react-native-chart-kit": "^6.12.0", "react-native-gesture-handler": "~2.28.0", @@ -64,9 +65,8 @@ "react-native-svg": "15.12.1", "react-native-web": "~0.21.0", "react-native-worklets": "0.5.1", - "react-redux": "^9.2.0", - "redux-persist": "^6.0.0", - "zod": "^3.23.8" + "zod": "^3.25.76", + "zustand": "^5.0.14" }, "devDependencies": { "@expo/ngrok": "^4.1.3", diff --git a/apps/mobile/services/api.ts b/apps/mobile/services/api.ts index 0aa5d82..1b65618 100644 --- a/apps/mobile/services/api.ts +++ b/apps/mobile/services/api.ts @@ -1,7 +1,11 @@ import axios from 'axios'; -import { API_URL, API_TIMEOUT } from '@constants/index'; +import { API_URL, API_TIMEOUT } from '@/constants'; +import { supabase } from '@/utils/supabase'; // ─── Base Axios Instance ────────────────────────────────────────────────────── +// Points to the FastAPI backend that will be deployed on HuggingFace Spaces +// alongside the trained ML model and edge functions. + const api = axios.create({ baseURL: API_URL, timeout: API_TIMEOUT, @@ -11,21 +15,28 @@ const api = axios.create({ }, }); -// ─── Request Interceptor — Attach Auth Token ────────────────────────────────── +// ─── Request Interceptor — Attach Supabase Auth Token ──────────────────────── +// Reads the active session from Supabase on every request so the token is +// always current after a silent refresh. No manual token injection required. + api.interceptors.request.use( - (config) => { - // Token is injected at call-site via setAuthToken() or from store middleware + async (config) => { + const { data } = await supabase.auth.getSession(); + if (data.session?.access_token) { + config.headers['Authorization'] = `Bearer ${data.session.access_token}`; + } return config; }, (error) => Promise.reject(error) ); // ─── Response Interceptor — Normalise Errors ───────────────────────────────── + api.interceptors.response.use( (response) => response, (error) => { if (error.response) { - const message = error.response.data?.message ?? 'An error occurred'; + const message = error.response.data?.detail ?? error.response.data?.message ?? 'An error occurred'; return Promise.reject(new Error(message)); } if (error.code === 'ECONNABORTED') { @@ -35,13 +46,4 @@ api.interceptors.response.use( } ); -/** Inject Clerk token into every outgoing request */ -export const setAuthToken = (token: string | null) => { - if (token) { - api.defaults.headers.common['Authorization'] = `Bearer ${token}`; - } else { - delete api.defaults.headers.common['Authorization']; - } -}; - export default api; diff --git a/apps/mobile/store/index.ts b/apps/mobile/store/index.ts deleted file mode 100644 index 1f38df4..0000000 --- a/apps/mobile/store/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { configureStore } from '@reduxjs/toolkit'; -import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from 'redux-persist'; -import AsyncStorage from '@react-native-async-storage/async-storage'; -import { combineReducers } from 'redux'; - -import authReducer from './slices/authSlice'; -import farmerReducer from './slices/farmerSlice'; -import farmReducer from './slices/farmSlice'; -import cropReducer from './slices/cropSlice'; -import weatherReducer from './slices/weatherSlice'; -import advisoryReducer from './slices/advisorySlice'; -import uiReducer from './slices/uiSlice'; - -// ─── Root Reducer ───────────────────────────────────────────────────────────── -const rootReducer = combineReducers({ - auth: authReducer, - farmer: farmerReducer, - farm: farmReducer, - crop: cropReducer, - weather: weatherReducer, - advisory: advisoryReducer, - ui: uiReducer, -}); - -import { Platform } from 'react-native'; - -const safeStorage = { - getItem: (key: string) => { - if (Platform.OS === 'web' && typeof window === 'undefined') return Promise.resolve(null); - return AsyncStorage.getItem(key); - }, - setItem: (key: string, value: string) => { - if (Platform.OS === 'web' && typeof window === 'undefined') return Promise.resolve(); - return AsyncStorage.setItem(key, value); - }, - removeItem: (key: string) => { - if (Platform.OS === 'web' && typeof window === 'undefined') return Promise.resolve(); - return AsyncStorage.removeItem(key); - }, -}; - -// ─── Persist Config ─────────────────────────────────────────────────────────── -const persistConfig = { - key: 'agronavis-root', - version: 1, - storage: safeStorage, - whitelist: ['auth', 'farmer', 'ui'], // Only persist auth, farmer profile, and UI prefs -}; - -const persistedReducer = persistReducer(persistConfig, rootReducer); - -// ─── Store ──────────────────────────────────────────────────────────────────── -export const store = configureStore({ - reducer: persistedReducer, - middleware: (getDefaultMiddleware) => - getDefaultMiddleware({ - serializableCheck: { - ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER], - }, - }), -}); - -export const persistor = persistStore(store); - -// ─── Types ──────────────────────────────────────────────────────────────────── -export type RootState = ReturnType; -export type AppDispatch = typeof store.dispatch; diff --git a/apps/mobile/store/slices/advisorySlice.ts b/apps/mobile/store/slices/advisorySlice.ts deleted file mode 100644 index 3011fa5..0000000 --- a/apps/mobile/store/slices/advisorySlice.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { createSlice } from '@reduxjs/toolkit'; - -const advisorySlice = createSlice({ - name: 'advisory', - initialState: { advisories: [], status: 'idle' as const }, - reducers: { - setAdvisories: (state, action) => { state.advisories = action.payload; }, - }, -}); - -export const { setAdvisories } = advisorySlice.actions; -export default advisorySlice.reducer; diff --git a/apps/mobile/store/slices/authSlice.ts b/apps/mobile/store/slices/authSlice.ts deleted file mode 100644 index f0bb5df..0000000 --- a/apps/mobile/store/slices/authSlice.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; - -interface AuthState { - isAuthenticated: boolean; - userId: string | null; - clerkToken: string | null; - isOnboardingComplete: boolean; -} - -const initialState: AuthState = { - isAuthenticated: false, - userId: null, - clerkToken: null, - isOnboardingComplete: false, -}; - -const authSlice = createSlice({ - name: 'auth', - initialState, - reducers: { - setAuthenticated(state, action: PayloadAction<{ userId: string; token: string }>) { - state.isAuthenticated = true; - state.userId = action.payload.userId; - state.clerkToken = action.payload.token; - }, - setOnboardingComplete(state) { - state.isOnboardingComplete = true; - }, - logout(state) { - state.isAuthenticated = false; - state.userId = null; - state.clerkToken = null; - }, - }, -}); - -export const { setAuthenticated, setOnboardingComplete, logout } = authSlice.actions; -export default authSlice.reducer; diff --git a/apps/mobile/store/slices/cropSlice.ts b/apps/mobile/store/slices/cropSlice.ts deleted file mode 100644 index 42e0834..0000000 --- a/apps/mobile/store/slices/cropSlice.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { createSlice } from '@reduxjs/toolkit'; - -const cropSlice = createSlice({ - name: 'crop', - initialState: { crops: [], status: 'idle' as const }, - reducers: { - setCrops: (state, action) => { state.crops = action.payload; }, - }, -}); - -export const { setCrops } = cropSlice.actions; -export default cropSlice.reducer; diff --git a/apps/mobile/store/slices/farmSlice.ts b/apps/mobile/store/slices/farmSlice.ts deleted file mode 100644 index e56b5ce..0000000 --- a/apps/mobile/store/slices/farmSlice.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { createSlice } from '@reduxjs/toolkit'; - -const farmSlice = createSlice({ - name: 'farm', - initialState: { farms: [], selectedFarmId: null as string | null, status: 'idle' as const }, - reducers: { - setFarms: (state, action) => { state.farms = action.payload; }, - setSelectedFarm: (state, action) => { state.selectedFarmId = action.payload; }, - }, -}); - -export const { setFarms, setSelectedFarm } = farmSlice.actions; -export default farmSlice.reducer; diff --git a/apps/mobile/store/slices/farmerSlice.ts b/apps/mobile/store/slices/farmerSlice.ts deleted file mode 100644 index 1092fd2..0000000 --- a/apps/mobile/store/slices/farmerSlice.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { Farmer } from '../../../../packages/shared-types/src/index'; -import { RequestStatus } from '../../types/api.types'; - -interface FarmerState { - profile: Farmer | null; - status: RequestStatus; - error: string | null; -} - -const initialState: FarmerState = { - profile: null, - status: 'idle', - error: null, -}; - -const farmerSlice = createSlice({ - name: 'farmer', - initialState, - reducers: { - setFarmerProfile(state, action: PayloadAction) { - state.profile = action.payload; - state.status = 'succeeded'; - state.error = null; - }, - setFarmerLoading(state) { - state.status = 'loading'; - }, - setFarmerError(state, action: PayloadAction) { - state.status = 'failed'; - state.error = action.payload; - }, - clearFarmerProfile(state) { - state.profile = null; - state.status = 'idle'; - state.error = null; - }, - }, -}); - -export const { setFarmerProfile, setFarmerLoading, setFarmerError, clearFarmerProfile } = farmerSlice.actions; -export default farmerSlice.reducer; diff --git a/apps/mobile/store/slices/uiSlice.ts b/apps/mobile/store/slices/uiSlice.ts deleted file mode 100644 index 2a132c8..0000000 --- a/apps/mobile/store/slices/uiSlice.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { ThemeMode } from '../../types/ui.types'; - -interface UIState { - theme: ThemeMode; - language: string; - isLoading: boolean; -} - -const uiSlice = createSlice({ - name: 'ui', - initialState: { theme: 'dark' as ThemeMode, language: 'en', isLoading: false as boolean } satisfies UIState, - reducers: { - setTheme: (state, action: PayloadAction) => { state.theme = action.payload; }, - setLanguage: (state, action: PayloadAction) => { state.language = action.payload; }, - setLoading: (state, action: PayloadAction) => { state.isLoading = action.payload; }, - }, -}); - -export const { setTheme, setLanguage, setLoading } = uiSlice.actions; -export default uiSlice.reducer; diff --git a/apps/mobile/store/slices/weatherSlice.ts b/apps/mobile/store/slices/weatherSlice.ts deleted file mode 100644 index ef4a5bf..0000000 --- a/apps/mobile/store/slices/weatherSlice.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { createSlice } from '@reduxjs/toolkit'; - -const weatherSlice = createSlice({ - name: 'weather', - initialState: { current: null as any, forecast: [], status: 'idle' as const }, - reducers: { - setWeather: (state, action) => { state.current = action.payload.current; state.forecast = action.payload.forecast; }, - }, -}); - -export const { setWeather } = weatherSlice.actions; -export default weatherSlice.reducer; diff --git a/apps/mobile/store/useAuthStore.ts b/apps/mobile/store/useAuthStore.ts new file mode 100644 index 0000000..768e4ea --- /dev/null +++ b/apps/mobile/store/useAuthStore.ts @@ -0,0 +1,67 @@ +import { create } from 'zustand'; +import type { Session, User } from '@supabase/supabase-js'; +import { supabase } from '@/utils/supabase'; + +interface AuthState { + session: Session | null; + user: User | null; + isLoading: boolean; + isOffline: boolean; +} + +interface AuthActions { + setSession: (session: Session | null) => void; + setLoading: (loading: boolean) => void; + setOffline: (offline: boolean) => void; + signOut: () => Promise; + initialize: () => () => void; +} + +/** + * Global auth store using Zustand. + * + * Three clean state values: + * session — the active Supabase session (null if unauthenticated) + * user — the Supabase User object derived from the session + * isLoading — true while the initial hydration check is running + * isOffline — true when a token refresh failed due to network, not an invalid token + * + * The `initialize` action registers supabase.auth.onAuthStateChange which keeps + * this store in sync with every token refresh, sign-in, and sign-out event. + * Call it once from the root layout and invoke the returned cleanup function on unmount. + */ +export const useAuthStore = create((set) => ({ + session: null, + user: null, + isLoading: true, + isOffline: false, + + setSession: (session) => + set({ session, user: session?.user ?? null }), + + setLoading: (isLoading) => set({ isLoading }), + + setOffline: (isOffline) => set({ isOffline }), + + signOut: async () => { + await supabase.auth.signOut(); + set({ session: null, user: null }); + }, + + initialize: () => { + // Hydrate from persisted storage on cold start + supabase.auth.getSession().then(({ data: { session } }) => { + set({ session, user: session?.user ?? null, isLoading: false }); + }); + + // Stay in sync with every auth event (token refresh, sign-in, sign-out) + const { data: { subscription } } = supabase.auth.onAuthStateChange( + (_event, session) => { + set({ session, user: session?.user ?? null, isLoading: false }); + } + ); + + // Return cleanup so root layout can unsubscribe on unmount + return () => subscription.unsubscribe(); + }, +})); diff --git a/apps/mobile/supabase/migrations/create_avatars_bucket.sql b/apps/mobile/supabase/migrations/create_avatars_bucket.sql new file mode 100644 index 0000000..1f883fa --- /dev/null +++ b/apps/mobile/supabase/migrations/create_avatars_bucket.sql @@ -0,0 +1,19 @@ +insert into storage.buckets (id, name, public) + values ('avatars', 'avatars', true) + on conflict (id) do nothing; + +create policy "avatars_public_read" + on storage.objects for select + using (bucket_id = 'avatars'); + +create policy "avatars_upload_own" + on storage.objects for insert + with check (bucket_id = 'avatars' and auth.uid()::text = (storage.foldername(name))[1]); + +create policy "avatars_update_own" + on storage.objects for update + using (bucket_id = 'avatars' and auth.uid()::text = (storage.foldername(name))[1]); + +create policy "avatars_delete_own" + on storage.objects for delete + using (bucket_id = 'avatars' and auth.uid()::text = (storage.foldername(name))[1]); diff --git a/apps/mobile/supabase/migrations/create_farmer_trigger.sql b/apps/mobile/supabase/migrations/create_farmer_trigger.sql new file mode 100644 index 0000000..f541726 --- /dev/null +++ b/apps/mobile/supabase/migrations/create_farmer_trigger.sql @@ -0,0 +1,225 @@ +-- ============================================================================= +-- Agronavis: Complete Database Schema — Run this in Supabase SQL Editor +-- ============================================================================= +-- Order of operations: +-- 1. Create all tables (farmers, farms, crops, sensor_readings, advisories) +-- 2. Create indexes for common query patterns +-- 3. Create the trigger that auto-populates farmers from auth.users +-- 4. Enable RLS and define row-level security policies +-- ============================================================================= + + +-- ─── 1. TABLES ─────────────────────────────────────────────────────────────── + +-- Farmer profile — one row per authenticated user +CREATE TABLE IF NOT EXISTS public.farmers ( + id uuid PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE, + email text NOT NULL, + full_name text NOT NULL DEFAULT 'Farmer', + phone text, + language text NOT NULL DEFAULT 'en', + state text, + district text, + avatar_url text, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now() +); + +-- Farm — a farmer can own multiple farm plots +CREATE TABLE IF NOT EXISTS public.farms ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + farmer_id uuid NOT NULL REFERENCES public.farmers(id) ON DELETE CASCADE, + name text NOT NULL, + area_acres numeric(8, 2), + soil_type text, + irrigation text, + latitude numeric(10, 7), + longitude numeric(10, 7), + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now() +); + +-- Crop — each planting season on a farm +CREATE TABLE IF NOT EXISTS public.crops ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + farm_id uuid NOT NULL REFERENCES public.farms(id) ON DELETE CASCADE, + farmer_id uuid NOT NULL REFERENCES public.farmers(id) ON DELETE CASCADE, + name text NOT NULL, + variety text, + category text, + sown_date date, + harvest_date date, + status text NOT NULL DEFAULT 'active' + CHECK (status IN ('active', 'harvested', 'failed')), + created_at timestamptz NOT NULL DEFAULT now() +); + +-- Sensor readings — IoT data points tied to a farm +CREATE TABLE IF NOT EXISTS public.sensor_readings ( + id bigserial PRIMARY KEY, + farm_id uuid NOT NULL REFERENCES public.farms(id) ON DELETE CASCADE, + sensor_type text NOT NULL, -- e.g. 'soil_moisture', 'temperature', 'humidity' + value numeric(10, 4) NOT NULL, + unit text NOT NULL, + recorded_at timestamptz NOT NULL DEFAULT now() +); + +-- AI advisories — recommendations generated by the ML model +CREATE TABLE IF NOT EXISTS public.advisories ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + farmer_id uuid NOT NULL REFERENCES public.farmers(id) ON DELETE CASCADE, + farm_id uuid REFERENCES public.farms(id) ON DELETE SET NULL, + crop_id uuid REFERENCES public.crops(id) ON DELETE SET NULL, + category text NOT NULL, -- e.g. 'irrigation', 'fertilizer', 'pest', 'weather' + title text NOT NULL, + body text NOT NULL, + severity text NOT NULL DEFAULT 'info' + CHECK (severity IN ('info', 'warning', 'critical')), + source text NOT NULL DEFAULT 'ml_model', + read boolean NOT NULL DEFAULT false, + created_at timestamptz NOT NULL DEFAULT now() +); + + +-- ─── 2. INDEXES ────────────────────────────────────────────────────────────── + +CREATE INDEX IF NOT EXISTS idx_farms_farmer_id ON public.farms(farmer_id); +CREATE INDEX IF NOT EXISTS idx_crops_farm_id ON public.crops(farm_id); +CREATE INDEX IF NOT EXISTS idx_crops_farmer_id ON public.crops(farmer_id); +CREATE INDEX IF NOT EXISTS idx_sensor_farm_recorded ON public.sensor_readings(farm_id, recorded_at DESC); +CREATE INDEX IF NOT EXISTS idx_advisories_farmer_id ON public.advisories(farmer_id, created_at DESC); + + +-- ─── 3. TRIGGER: auto-create farmer profile on signup ──────────────────────── + +CREATE OR REPLACE FUNCTION public.handle_new_user() +RETURNS TRIGGER +LANGUAGE plpgsql +SECURITY DEFINER +SET search_path = public +AS $$ +BEGIN + INSERT INTO public.farmers (id, email, full_name, created_at) + VALUES ( + new.id, + new.email, + COALESCE(new.raw_user_meta_data->>'full_name', 'Farmer'), + new.created_at + ) + ON CONFLICT (id) DO NOTHING; + RETURN new; +EXCEPTION + WHEN OTHERS THEN + -- Log but never block authentication + RAISE WARNING 'handle_new_user failed for user %: %', new.id, SQLERRM; + RETURN new; +END; +$$; + +DROP TRIGGER IF EXISTS on_auth_user_created ON auth.users; +CREATE TRIGGER on_auth_user_created + AFTER INSERT ON auth.users + FOR EACH ROW EXECUTE PROCEDURE public.handle_new_user(); + +-- Auto-update updated_at on farmers and farms +CREATE OR REPLACE FUNCTION public.set_updated_at() +RETURNS TRIGGER LANGUAGE plpgsql AS $$ +BEGIN + new.updated_at = now(); + RETURN new; +END; +$$; + +DROP TRIGGER IF EXISTS trg_farmers_updated_at ON public.farmers; +CREATE TRIGGER trg_farmers_updated_at + BEFORE UPDATE ON public.farmers + FOR EACH ROW EXECUTE PROCEDURE public.set_updated_at(); + +DROP TRIGGER IF EXISTS trg_farms_updated_at ON public.farms; +CREATE TRIGGER trg_farms_updated_at + BEFORE UPDATE ON public.farms + FOR EACH ROW EXECUTE PROCEDURE public.set_updated_at(); + + +-- ─── 4. ROW LEVEL SECURITY ─────────────────────────────────────────────────── + +ALTER TABLE public.farmers ENABLE ROW LEVEL SECURITY; +ALTER TABLE public.farms ENABLE ROW LEVEL SECURITY; +ALTER TABLE public.crops ENABLE ROW LEVEL SECURITY; +ALTER TABLE public.sensor_readings ENABLE ROW LEVEL SECURITY; +ALTER TABLE public.advisories ENABLE ROW LEVEL SECURITY; + +-- farmers +DROP POLICY IF EXISTS "farmers_select_own" ON public.farmers; +CREATE POLICY "farmers_select_own" + ON public.farmers FOR SELECT USING (auth.uid() = id); + +DROP POLICY IF EXISTS "farmers_update_own" ON public.farmers; +CREATE POLICY "farmers_update_own" + ON public.farmers FOR UPDATE USING (auth.uid() = id); + +-- farms (farmer owns all their farms) +DROP POLICY IF EXISTS "farms_select_own" ON public.farms; +CREATE POLICY "farms_select_own" + ON public.farms FOR SELECT USING (auth.uid() = farmer_id); + +DROP POLICY IF EXISTS "farms_insert_own" ON public.farms; +CREATE POLICY "farms_insert_own" + ON public.farms FOR INSERT WITH CHECK (auth.uid() = farmer_id); + +DROP POLICY IF EXISTS "farms_update_own" ON public.farms; +CREATE POLICY "farms_update_own" + ON public.farms FOR UPDATE USING (auth.uid() = farmer_id); + +DROP POLICY IF EXISTS "farms_delete_own" ON public.farms; +CREATE POLICY "farms_delete_own" + ON public.farms FOR DELETE USING (auth.uid() = farmer_id); + +-- crops +DROP POLICY IF EXISTS "crops_select_own" ON public.crops; +CREATE POLICY "crops_select_own" + ON public.crops FOR SELECT USING (auth.uid() = farmer_id); + +DROP POLICY IF EXISTS "crops_insert_own" ON public.crops; +CREATE POLICY "crops_insert_own" + ON public.crops FOR INSERT WITH CHECK (auth.uid() = farmer_id); + +DROP POLICY IF EXISTS "crops_update_own" ON public.crops; +CREATE POLICY "crops_update_own" + ON public.crops FOR UPDATE USING (auth.uid() = farmer_id); + +DROP POLICY IF EXISTS "crops_delete_own" ON public.crops; +CREATE POLICY "crops_delete_own" + ON public.crops FOR DELETE USING (auth.uid() = farmer_id); + +-- sensor_readings (readable if the farmer owns the farm) +DROP POLICY IF EXISTS "sensor_select_own_farm" ON public.sensor_readings; +CREATE POLICY "sensor_select_own_farm" + ON public.sensor_readings FOR SELECT + USING ( + EXISTS ( + SELECT 1 FROM public.farms + WHERE farms.id = sensor_readings.farm_id + AND farms.farmer_id = auth.uid() + ) + ); + +DROP POLICY IF EXISTS "sensor_insert_own_farm" ON public.sensor_readings; +CREATE POLICY "sensor_insert_own_farm" + ON public.sensor_readings FOR INSERT + WITH CHECK ( + EXISTS ( + SELECT 1 FROM public.farms + WHERE farms.id = sensor_readings.farm_id + AND farms.farmer_id = auth.uid() + ) + ); + +-- advisories +DROP POLICY IF EXISTS "advisories_select_own" ON public.advisories; +CREATE POLICY "advisories_select_own" + ON public.advisories FOR SELECT USING (auth.uid() = farmer_id); + +DROP POLICY IF EXISTS "advisories_update_own" ON public.advisories; +CREATE POLICY "advisories_update_own" + ON public.advisories FOR UPDATE USING (auth.uid() = farmer_id); diff --git a/apps/mobile/utils/supabase.ts b/apps/mobile/utils/supabase.ts new file mode 100644 index 0000000..9a1f078 --- /dev/null +++ b/apps/mobile/utils/supabase.ts @@ -0,0 +1,23 @@ +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { createClient } from '@supabase/supabase-js'; + +const supabaseUrl = process.env.EXPO_PUBLIC_SUPABASE_URL!; +const supabaseAnonKey = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY!; + +/** + * Supabase client configured for React Native. + * + * - storage: AsyncStorage ensures the session survives app restarts. + * - autoRefreshToken: silently re-fetches the access token before it expires. + * - persistSession: keeps the session across cold starts. + * - detectSessionInUrl: false — Expo Router handles deep-link routing at the + * framework layer, so the Supabase client must NOT attempt to parse URLs. + */ +export const supabase = createClient(supabaseUrl, supabaseAnonKey, { + auth: { + storage: AsyncStorage, + autoRefreshToken: true, + persistSession: true, + detectSessionInUrl: false, + }, +}); diff --git a/package-lock.json b/package-lock.json index 013ba5d..5fe8e74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,15 +29,15 @@ "version": "1.0.0", "dependencies": { "@agronavis/shared-types": "*", - "@clerk/clerk-expo": "^2.15.2", "@expo/metro-runtime": "~6.1.2", "@expo/vector-icons": "^15.0.2", + "@hookform/resolvers": "^5.4.0", "@react-native-async-storage/async-storage": "^2.2.0", "@react-native-community/datetimepicker": "8.4.4", "@react-native-picker/picker": "2.11.1", "@react-navigation/bottom-tabs": "^7.4.0", "@react-navigation/native": "^7.1.8", - "@reduxjs/toolkit": "^2.9.0", + "@supabase/supabase-js": "^2.108.1", "axios": "^1.12.2", "expo": "~54.0.10", "expo-auth-session": "~7.0.11", @@ -61,6 +61,7 @@ "lottie-react-native": "^7.3.4", "react": "19.1.0", "react-dom": "19.1.0", + "react-hook-form": "^7.79.0", "react-native": "0.81.5", "react-native-chart-kit": "^6.12.0", "react-native-gesture-handler": "~2.28.0", @@ -73,9 +74,8 @@ "react-native-svg": "15.12.1", "react-native-web": "~0.21.0", "react-native-worklets": "0.5.1", - "react-redux": "^9.2.0", - "redux-persist": "^6.0.0", - "zod": "^3.23.8" + "zod": "^3.25.76", + "zustand": "^5.0.14" }, "devDependencies": { "@expo/ngrok": "^4.1.3", @@ -185,12 +185,6 @@ } } }, - "node_modules/@adraffy/ens-normalize": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", - "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", - "license": "MIT" - }, "node_modules/@agronavis/backend": { "resolved": "backend", "link": true @@ -1731,22 +1725,6 @@ "node": ">=6.9.0" } }, - "node_modules/@base-org/account": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@base-org/account/-/account-2.0.1.tgz", - "integrity": "sha512-tySVNx+vd6XEynZL0uvB10uKiwnAfThr8AbKTwILVG86mPbLAhEOInQIk+uDnvpTvfdUhC1Bi5T/46JvFoLZQQ==", - "license": "Apache-2.0", - "dependencies": { - "@noble/hashes": "1.4.0", - "clsx": "1.2.1", - "eventemitter3": "5.0.1", - "idb-keyval": "6.2.1", - "ox": "0.6.9", - "preact": "10.24.2", - "viem": "^2.31.7", - "zustand": "5.0.3" - } - }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -1791,112 +1769,6 @@ "node": ">=18.17.0" } }, - "node_modules/@clerk/clerk-expo": { - "version": "2.19.31", - "resolved": "https://registry.npmjs.org/@clerk/clerk-expo/-/clerk-expo-2.19.31.tgz", - "integrity": "sha512-w3npdpbgmOQ2ybFuNo5XGauHJ1eq8ID76Y3l2zjj9wvawPCA3UKdPvPwFdR6ukVzd+ktzhTbFnKUeIM4vXe/6w==", - "license": "MIT", - "dependencies": { - "@clerk/clerk-js": "^5.125.5", - "@clerk/clerk-react": "^5.61.3", - "@clerk/shared": "^3.47.2", - "@clerk/types": "^4.101.20", - "base-64": "^1.0.0", - "react-native-url-polyfill": "2.0.0", - "tslib": "2.8.1" - }, - "engines": { - "node": ">=18.17.0" - }, - "peerDependencies": { - "@clerk/expo-passkeys": ">=0.0.6", - "expo-apple-authentication": ">=7.0.0", - "expo-auth-session": ">=5", - "expo-crypto": ">=12", - "expo-local-authentication": ">=13.5.0", - "expo-secure-store": ">=12.4.0", - "expo-web-browser": ">=12.5.0", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0", - "react-native": ">=0.73" - }, - "peerDependenciesMeta": { - "@clerk/expo-passkeys": { - "optional": true - }, - "expo-apple-authentication": { - "optional": true - }, - "expo-crypto": { - "optional": true - }, - "expo-local-authentication": { - "optional": true - }, - "expo-secure-store": { - "optional": true - } - } - }, - "node_modules/@clerk/clerk-js": { - "version": "5.125.10", - "resolved": "https://registry.npmjs.org/@clerk/clerk-js/-/clerk-js-5.125.10.tgz", - "integrity": "sha512-R0sZ5n4ND7xnHKkMoSuhcYa5+qcgHeYEsQ8eN0ti5hUgGH3LzQX1vJg0GHTEceJI68SrVETArRR7bxyMwS8QAg==", - "license": "MIT", - "dependencies": { - "@base-org/account": "2.0.1", - "@clerk/localizations": "^3.37.5", - "@clerk/shared": "^3.47.5", - "@coinbase/wallet-sdk": "4.3.0", - "@emotion/cache": "11.11.0", - "@emotion/react": "11.11.1", - "@floating-ui/react": "0.27.12", - "@floating-ui/react-dom": "^2.1.3", - "@formkit/auto-animate": "^0.8.2", - "@solana/wallet-adapter-base": "0.9.27", - "@solana/wallet-adapter-react": "0.15.39", - "@solana/wallet-standard": "1.1.4", - "@stripe/stripe-js": "5.6.0", - "@swc/helpers": "^0.5.17", - "@tanstack/query-core": "5.87.4", - "@wallet-standard/core": "1.1.1", - "@zxcvbn-ts/core": "3.0.4", - "@zxcvbn-ts/language-common": "3.0.4", - "alien-signals": "2.0.6", - "browser-tabs-lock": "1.3.0", - "copy-to-clipboard": "3.3.3", - "core-js": "3.41.0", - "crypto-js": "^4.2.0", - "dequal": "2.0.3", - "input-otp": "1.4.2", - "qrcode.react": "4.2.0", - "regenerator-runtime": "0.14.1" - }, - "engines": { - "node": ">=18.17.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0", - "react-dom": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0" - } - }, - "node_modules/@clerk/clerk-react": { - "version": "5.61.6", - "resolved": "https://registry.npmjs.org/@clerk/clerk-react/-/clerk-react-5.61.6.tgz", - "integrity": "sha512-OiyBlrnkRr9IhZtPd7EwlzhYScBpvNKJ8lgg7Uw6JElzJYz854IeQaez5mAfpiib3LcW/Dn53E2PQhagcuLJ3Q==", - "license": "MIT", - "dependencies": { - "@clerk/shared": "^3.47.5", - "tslib": "2.8.1" - }, - "engines": { - "node": ">=18.17.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0", - "react-dom": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0" - } - }, "node_modules/@clerk/express": { "version": "1.7.79", "resolved": "https://registry.npmjs.org/@clerk/express/-/express-1.7.79.tgz", @@ -1915,18 +1787,6 @@ "express": "^4.17.0 || ^5.0.0" } }, - "node_modules/@clerk/localizations": { - "version": "3.37.5", - "resolved": "https://registry.npmjs.org/@clerk/localizations/-/localizations-3.37.5.tgz", - "integrity": "sha512-OpFJuC77V/Kz6MvW9zYFxSIXDYhbmsmZ1f8jOxuvlIZXmXQPgyP8Eypq5495514uN/mWBrIbCNRsX/Rh1aFz0Q==", - "license": "MIT", - "dependencies": { - "@clerk/types": "^4.101.23" - }, - "engines": { - "node": ">=18.17.0" - } - }, "node_modules/@clerk/shared": { "version": "3.47.5", "resolved": "https://registry.npmjs.org/@clerk/shared/-/shared-3.47.5.tgz", @@ -1969,18 +1829,6 @@ "node": ">=18.17.0" } }, - "node_modules/@coinbase/wallet-sdk": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@coinbase/wallet-sdk/-/wallet-sdk-4.3.0.tgz", - "integrity": "sha512-T3+SNmiCw4HzDm4we9wCHCxlP0pqCiwKe4sOwPH3YAK2KSKjxPRydKu6UQJrdONFVLG7ujXvbd/6ZqmvJb8rkw==", - "license": "Apache-2.0", - "dependencies": { - "@noble/hashes": "^1.4.0", - "clsx": "^1.2.1", - "eventemitter3": "^5.0.1", - "preact": "^10.24.2" - } - }, "node_modules/@colors/colors": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", @@ -2071,132 +1919,6 @@ "tslib": "^2.4.0" } }, - "node_modules/@emotion/babel-plugin": { - "version": "11.13.5", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", - "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/serialize": "^1.3.3", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/babel-plugin/node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", - "license": "MIT" - }, - "node_modules/@emotion/cache": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", - "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", - "license": "MIT", - "dependencies": { - "@emotion/memoize": "^0.8.1", - "@emotion/sheet": "^1.2.2", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", - "stylis": "4.2.0" - } - }, - "node_modules/@emotion/hash": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", - "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", - "license": "MIT" - }, - "node_modules/@emotion/memoize": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", - "license": "MIT" - }, - "node_modules/@emotion/react": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", - "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/cache": "^11.11.0", - "@emotion/serialize": "^1.1.2", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", - "hoist-non-react-statics": "^3.3.1" - }, - "peerDependencies": { - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/serialize": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", - "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", - "license": "MIT", - "dependencies": { - "@emotion/hash": "^0.9.2", - "@emotion/memoize": "^0.9.0", - "@emotion/unitless": "^0.10.0", - "@emotion/utils": "^1.4.2", - "csstype": "^3.0.2" - } - }, - "node_modules/@emotion/serialize/node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", - "license": "MIT" - }, - "node_modules/@emotion/sheet": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", - "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", - "license": "MIT" - }, - "node_modules/@emotion/unitless": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", - "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", - "license": "MIT" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", - "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", - "license": "MIT", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@emotion/utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", - "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", - "license": "MIT" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", - "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==", - "license": "MIT" - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.7", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", @@ -3943,65 +3665,18 @@ "excpretty": "build/cli.js" } }, - "node_modules/@floating-ui/core": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", - "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", - "license": "MIT", - "dependencies": { - "@floating-ui/utils": "^0.2.11" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", - "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", - "license": "MIT", - "dependencies": { - "@floating-ui/core": "^1.7.5", - "@floating-ui/utils": "^0.2.11" - } - }, - "node_modules/@floating-ui/react": { - "version": "0.27.12", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.12.tgz", - "integrity": "sha512-kKlWNrpIQxF1B/a2MZvE0/uyKby4960yjO91W7nVyNKmmfNi62xU9HCjL1M1eWzx/LFj/VPSwJVbwQk9Pq/68A==", - "license": "MIT", - "dependencies": { - "@floating-ui/react-dom": "^2.1.3", - "@floating-ui/utils": "^0.2.9", - "tabbable": "^6.0.0" - }, - "peerDependencies": { - "react": ">=17.0.0", - "react-dom": ">=17.0.0" - } - }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", - "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", + "node_modules/@hookform/resolvers": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.4.0.tgz", + "integrity": "sha512-EIsqr/t/qbinPIhGjMdtvutIN1Kk4uwbROE9/UQ93CAVGR7GkA7Y92+fX80OzXi/OB67jVFYwKGO1WzkxmkFZw==", "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.7.6" + "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "react-hook-form": "^7.55.0" } }, - "node_modules/@floating-ui/utils": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", - "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", - "license": "MIT" - }, - "node_modules/@formkit/auto-animate": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/@formkit/auto-animate/-/auto-animate-0.8.4.tgz", - "integrity": "sha512-DHHC01EJ1p70Q0z/ZFRBIY8NDnmfKccQoyoM84Tgb6omLMat6jivCdf272Y8k3nf4Lzdin/Y4R9q8uFtU0GbnA==", - "license": "MIT" - }, "node_modules/@humanfs/core": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", @@ -4622,49 +4297,11 @@ "@tybys/wasm-util": "^0.10.0" } }, - "node_modules/@noble/ciphers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", - "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/curves": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", - "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@noble/hashes": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 16" @@ -4753,14 +4390,14 @@ "version": "5.22.0", "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz", "integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0" }, "node_modules/@prisma/engines": { "version": "5.22.0", "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.22.0.tgz", "integrity": "sha512-UNjfslWhAt06kVL3CjkuYpHAWSO6L4kDCVPegV6itt7nD1kSJavd3vhgAEhjglLJJKEdJ7oIqDJ+yHk6qO8gPA==", - "devOptional": true, + "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -4774,14 +4411,14 @@ "version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2.tgz", "integrity": "sha512-2PTmxFR2yHW/eB3uqWtcgRcgAbG1rwG9ZriSvQw+nnb7c4uCr3RAcGMb6/zfE88SKlC1Nj2ziUvc96Z379mHgQ==", - "devOptional": true, + "dev": true, "license": "Apache-2.0" }, "node_modules/@prisma/fetch-engine": { "version": "5.22.0", "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.22.0.tgz", "integrity": "sha512-bkrD/Mc2fSvkQBV5EpoFcZ87AvOgDxbG99488a5cexp5Ccny+UM6MAe/UFkUC0wLYD9+9befNOqGiIJhhq+HbA==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@prisma/debug": "5.22.0", @@ -4793,7 +4430,7 @@ "version": "5.22.0", "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.22.0.tgz", "integrity": "sha512-pHhpQdr1UPFpt+zFfnPazhulaZYCUqeIcPpJViYoq9R+D/yw4fjE+CtnsnKzPYm0ddUbeXUzjGVGIRVgPDCk4Q==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "dependencies": { "@prisma/debug": "5.22.0" @@ -5642,32 +5279,6 @@ "nanoid": "^3.3.11" } }, - "node_modules/@reduxjs/toolkit": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.11.2.tgz", - "integrity": "sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==", - "license": "MIT", - "dependencies": { - "@standard-schema/spec": "^1.0.0", - "@standard-schema/utils": "^0.3.0", - "immer": "^11.0.0", - "redux": "^5.0.1", - "redux-thunk": "^3.1.0", - "reselect": "^5.1.0" - }, - "peerDependencies": { - "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", - "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-redux": { - "optional": true - } - } - }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -5675,66 +5286,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@scure/base": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", - "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", - "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.9.0", - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip32/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", - "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@scure/bip39/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@sinclair/typebox": { "version": "0.27.10", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", @@ -5828,391 +5379,100 @@ "node": ">=18" } }, - "node_modules/@solana-mobile/mobile-wallet-adapter-protocol": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/@solana-mobile/mobile-wallet-adapter-protocol/-/mobile-wallet-adapter-protocol-2.2.8.tgz", - "integrity": "sha512-c3FQsrM7nV62DqVaHGKtr2osE2w5gS3/wjy8ILF0zczS/s1mERX+JTmf+UHd8xgESmEj/IM7q+U2Qhrmac1PdA==", - "license": "Apache-2.0", + "node_modules/@stablelib/base64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/base64/-/base64-1.0.1.tgz", + "integrity": "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, + "node_modules/@supabase/auth-js": { + "version": "2.108.1", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.108.1.tgz", + "integrity": "sha512-Lle5rKU8f9LF3K5dDd8Or8mkkG+ptzRZZWKPVMm9B9UuovH65Ss2+iFnQqRsCqaGouvJEcTWyl0cj2riNrrDLQ==", + "license": "MIT", "dependencies": { - "@solana/codecs-strings": "^6.0.0", - "@solana/wallet-standard-features": "^1.3.0", - "@solana/wallet-standard-util": "^1.1.2", - "@wallet-standard/core": "^1.1.1", - "js-base64": "^3.7.5" + "tslib": "2.8.1" }, - "peerDependencies": { - "react-native": ">0.74" + "engines": { + "node": ">=20.0.0" } }, - "node_modules/@solana-mobile/mobile-wallet-adapter-protocol-web3js": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/@solana-mobile/mobile-wallet-adapter-protocol-web3js/-/mobile-wallet-adapter-protocol-web3js-2.2.8.tgz", - "integrity": "sha512-W9DbsFvl5lSOe7KT3dJX4tjbxfYIoOtOTJpvLMgkojyRU0UKChQ4vHvbOZQ3GkUJ8wOIS4qdrM0Yytd1Vy+YQQ==", - "license": "Apache-2.0", + "node_modules/@supabase/functions-js": { + "version": "2.108.1", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.108.1.tgz", + "integrity": "sha512-fxBRW/A4IG7ADQztVt0NaEy5ysiO1WJ2pbldsnBchrkHuyepX0Krek9qA9T4gUQBVVTCE9Ea4pdsM5hfn3nc4A==", + "license": "MIT", "dependencies": { - "@solana-mobile/mobile-wallet-adapter-protocol": "^2.2.8", - "bs58": "^6.0.0", - "js-base64": "^3.7.5" + "tslib": "2.8.1" }, - "peerDependencies": { - "@solana/web3.js": "^1.98.4" + "engines": { + "node": ">=20.0.0" } }, - "node_modules/@solana-mobile/wallet-adapter-mobile": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/@solana-mobile/wallet-adapter-mobile/-/wallet-adapter-mobile-2.2.8.tgz", - "integrity": "sha512-ZbXY3/0+UnnyS0hvArpO1b1pYzaQAiVIp+HBUm11aLEkE5+ISvHTRPr/bCEUXZfPkez/1n9zH3H0leK25Lj6Nw==", - "license": "Apache-2.0", + "node_modules/@supabase/phoenix": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@supabase/phoenix/-/phoenix-0.4.2.tgz", + "integrity": "sha512-YSAGnmDAfuleFCVt3CeurQZAhxRfXWeZIIkwp7NhYzQ1UwW6ePSnzsFAiUm/mbCkfoCf70QQHKW/K6RKh52a4A==", + "license": "MIT" + }, + "node_modules/@supabase/postgrest-js": { + "version": "2.108.1", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.108.1.tgz", + "integrity": "sha512-9lj2MCPPMgSTaJ5y+amnhb3TWPtMFVlbDn2hmX/VV91xQU4j0AauwfMaBErHBJ+zzsSwjc0jLU+zLIZFLQzfig==", + "license": "MIT", "dependencies": { - "@solana-mobile/mobile-wallet-adapter-protocol": "^2.2.8", - "@solana-mobile/mobile-wallet-adapter-protocol-web3js": "^2.2.8", - "@solana-mobile/wallet-standard-mobile": "^0.5.2", - "@solana/wallet-adapter-base": "^0.9.27", - "@solana/wallet-standard-features": "^1.3.0", - "@wallet-standard/core": "^1.1.1", - "bs58": "^6.0.0", - "js-base64": "^3.7.5", - "tslib": "^2.8.1" - }, - "optionalDependencies": { - "@react-native-async-storage/async-storage": "^1.17.7" + "tslib": "2.8.1" }, - "peerDependencies": { - "@solana/web3.js": "^1.98.4", - "react-native": ">0.74" + "engines": { + "node": ">=20.0.0" } }, - "node_modules/@solana-mobile/wallet-adapter-mobile/node_modules/@react-native-async-storage/async-storage": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.24.0.tgz", - "integrity": "sha512-W4/vbwUOYOjco0x3toB8QCr7EjIP6nE9G7o8PMguvvjYT5Awg09lyV4enACRx4s++PPulBiBSjL0KTFx2u0Z/g==", + "node_modules/@supabase/realtime-js": { + "version": "2.108.1", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.108.1.tgz", + "integrity": "sha512-mHGGqOjwd1XTydcoffUqEMsbFQHUi6A3uhQ0EXr3iqzpLqItxKA9nbN6gIQxrZ7JRRnuUe/iOFPUkYV9Tdc5lg==", "license": "MIT", - "optional": true, "dependencies": { - "merge-options": "^3.0.4" + "@supabase/phoenix": "^0.4.2", + "tslib": "2.8.1" }, - "peerDependencies": { - "react-native": "^0.0.0-0 || >=0.60 <1.0" + "engines": { + "node": ">=20.0.0" } }, - "node_modules/@solana-mobile/wallet-standard-mobile": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@solana-mobile/wallet-standard-mobile/-/wallet-standard-mobile-0.5.2.tgz", - "integrity": "sha512-orEGv4N/Ttd0umwfWUzGcEnVc9eJDTgRSEcDitvFWpIf2D968h6128L0rq9/y7sUw88Gvu/lU0euoC2ASEijqQ==", - "license": "Apache-2.0", - "dependencies": { - "@solana-mobile/mobile-wallet-adapter-protocol": "^2.2.8", - "@solana/wallet-standard-chains": "^1.1.1", - "@solana/wallet-standard-features": "^1.3.0", - "@wallet-standard/base": "^1.0.1", - "@wallet-standard/features": "^1.0.3", - "@wallet-standard/wallet": "^1.1.0", - "bs58": "^6.0.0", - "js-base64": "^3.7.5", - "qrcode": "^1.5.4", - "tslib": "^2.8.1" - }, - "optionalDependencies": { - "@react-native-async-storage/async-storage": "^1.17.7" - } - }, - "node_modules/@solana-mobile/wallet-standard-mobile/node_modules/@react-native-async-storage/async-storage": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.24.0.tgz", - "integrity": "sha512-W4/vbwUOYOjco0x3toB8QCr7EjIP6nE9G7o8PMguvvjYT5Awg09lyV4enACRx4s++PPulBiBSjL0KTFx2u0Z/g==", - "license": "MIT", - "optional": true, - "dependencies": { - "merge-options": "^3.0.4" - }, - "peerDependencies": { - "react-native": "^0.0.0-0 || >=0.60 <1.0" - } - }, - "node_modules/@solana/codecs-core": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@solana/codecs-core/-/codecs-core-6.9.0.tgz", - "integrity": "sha512-F2BmLecG/1nTtnjyD509NsEc254pxJKa2bpvotymv1lL1WfEn3zchcZ9SMIiLyL4G6J8b9F3OKIq2YSZho2AOQ==", - "license": "MIT", - "dependencies": { - "@solana/errors": "6.9.0" - }, - "engines": { - "node": ">=20.18.0" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@solana/codecs-numbers": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@solana/codecs-numbers/-/codecs-numbers-6.9.0.tgz", - "integrity": "sha512-XMI0FOHV2h7yPAllxWCX8z+J1msidNjXzN1mRjH5KR6C+vfzyKa2xWHve0bNSV/bjVAhqqhc7dQCpBKuF4+ScQ==", - "license": "MIT", - "dependencies": { - "@solana/codecs-core": "6.9.0", - "@solana/errors": "6.9.0" - }, - "engines": { - "node": ">=20.18.0" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@solana/codecs-strings": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@solana/codecs-strings/-/codecs-strings-6.9.0.tgz", - "integrity": "sha512-PTqYQxMsmdfEEq29bV1AnALD4FjFEsSxOj1fYNqooOSTEQEpUoYEQtsd55/kBsnIKltXbvYwXYXBusm19n1sQA==", + "node_modules/@supabase/storage-js": { + "version": "2.108.1", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.108.1.tgz", + "integrity": "sha512-Er0SGGt85iT6ye+SSh98Az6L2CesoZJuyzEZYH2oBOAnIxa9Nn4CtwUC3veGxYggoT56X+3tVuuQeDBP8kR8sg==", "license": "MIT", "dependencies": { - "@solana/codecs-core": "6.9.0", - "@solana/codecs-numbers": "6.9.0", - "@solana/errors": "6.9.0" + "iceberg-js": "^0.8.1", + "tslib": "2.8.1" }, "engines": { - "node": ">=20.18.0" - }, - "peerDependencies": { - "fastestsmallesttextencoderdecoder": "^1.0.22", - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "fastestsmallesttextencoderdecoder": { - "optional": true - }, - "typescript": { - "optional": true - } + "node": ">=20.0.0" } }, - "node_modules/@solana/errors": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/@solana/errors/-/errors-6.9.0.tgz", - "integrity": "sha512-7i+b07KMnkbHvFlz7uWade3jvyc22UmVm8o9taxPK8YV3JNM/NkS8oQFvMac2MIaLPAlEs7I8MHyVLUal1yY4g==", + "node_modules/@supabase/supabase-js": { + "version": "2.108.1", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.108.1.tgz", + "integrity": "sha512-V/1hRKLSCJ0zEL+9QFRBUtivvePfOsaAYQmC0HhFNSHC2F3xFs4jSF3YhkLmzex6E4V4FGvmBDOP72D/53NnZA==", "license": "MIT", "dependencies": { - "chalk": "5.6.2", - "commander": "14.0.3" + "@supabase/auth-js": "2.108.1", + "@supabase/functions-js": "2.108.1", + "@supabase/postgrest-js": "2.108.1", + "@supabase/realtime-js": "2.108.1", + "@supabase/storage-js": "2.108.1" }, - "bin": { - "errors": "bin/cli.mjs" - }, - "engines": { - "node": ">=20.18.0" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@solana/errors/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@solana/wallet-adapter-base": { - "version": "0.9.27", - "resolved": "https://registry.npmjs.org/@solana/wallet-adapter-base/-/wallet-adapter-base-0.9.27.tgz", - "integrity": "sha512-kXjeNfNFVs/NE9GPmysBRKQ/nf+foSaq3kfVSeMcO/iVgigyRmB551OjU3WyAolLG/1jeEfKLqF9fKwMCRkUqg==", - "license": "Apache-2.0", - "dependencies": { - "@solana/wallet-standard-features": "^1.3.0", - "@wallet-standard/base": "^1.1.0", - "@wallet-standard/features": "^1.1.0", - "eventemitter3": "^5.0.1" - }, - "engines": { - "node": ">=20" - }, - "peerDependencies": { - "@solana/web3.js": "^1.98.0" - } - }, - "node_modules/@solana/wallet-adapter-react": { - "version": "0.15.39", - "resolved": "https://registry.npmjs.org/@solana/wallet-adapter-react/-/wallet-adapter-react-0.15.39.tgz", - "integrity": "sha512-WXtlo88ith5m22qB+qiGw301/Zb9r5pYr4QdXWmlXnRNqwST5MGmJWhG+/RVrzc+OG7kSb3z1gkVNv+2X/Y0Gg==", - "license": "Apache-2.0", - "dependencies": { - "@solana-mobile/wallet-adapter-mobile": "^2.2.0", - "@solana/wallet-adapter-base": "^0.9.27", - "@solana/wallet-standard-wallet-adapter-react": "^1.1.4" - }, - "engines": { - "node": ">=20" - }, - "peerDependencies": { - "@solana/web3.js": "^1.98.0", - "react": "*" - } - }, - "node_modules/@solana/wallet-standard": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@solana/wallet-standard/-/wallet-standard-1.1.4.tgz", - "integrity": "sha512-NF+MI5tOxyvfTU4A+O5idh/gJFmjm52bMwsPpFGRSL79GECSN0XLmpVOO/jqTKJgac2uIeYDpQw/eMaQuWuUXw==", - "license": "Apache-2.0", - "dependencies": { - "@solana/wallet-standard-core": "^1.1.2", - "@solana/wallet-standard-wallet-adapter": "^1.1.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@solana/wallet-standard-chains": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@solana/wallet-standard-chains/-/wallet-standard-chains-1.1.1.tgz", - "integrity": "sha512-Us3TgL4eMVoVWhuC4UrePlYnpWN+lwteCBlhZDUhFZBJ5UMGh94mYPXno3Ho7+iHPYRtuCi/ePvPcYBqCGuBOw==", - "license": "Apache-2.0", - "dependencies": { - "@wallet-standard/base": "^1.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@solana/wallet-standard-core": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@solana/wallet-standard-core/-/wallet-standard-core-1.1.2.tgz", - "integrity": "sha512-FaSmnVsIHkHhYlH8XX0Y4TYS+ebM+scW7ZeDkdXo3GiKge61Z34MfBPinZSUMV08hCtzxxqH2ydeU9+q/KDrLA==", - "license": "Apache-2.0", - "dependencies": { - "@solana/wallet-standard-chains": "^1.1.1", - "@solana/wallet-standard-features": "^1.3.0", - "@solana/wallet-standard-util": "^1.1.2" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@solana/wallet-standard-features": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@solana/wallet-standard-features/-/wallet-standard-features-1.3.0.tgz", - "integrity": "sha512-ZhpZtD+4VArf6RPitsVExvgkF+nGghd1rzPjd97GmBximpnt1rsUxMOEyoIEuH3XBxPyNB6Us7ha7RHWQR+abg==", - "license": "Apache-2.0", - "dependencies": { - "@wallet-standard/base": "^1.1.0", - "@wallet-standard/features": "^1.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@solana/wallet-standard-util": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@solana/wallet-standard-util/-/wallet-standard-util-1.1.2.tgz", - "integrity": "sha512-rUXFNP4OY81Ddq7qOjQV4Kmkozx4wjYAxljvyrqPx8Ycz0FYChG/hQVWqvgpK3sPsEaO/7ABG1NOACsyAKWNOA==", - "license": "Apache-2.0", - "dependencies": { - "@noble/curves": "^1.8.0", - "@solana/wallet-standard-chains": "^1.1.1", - "@solana/wallet-standard-features": "^1.3.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@solana/wallet-standard-wallet-adapter": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@solana/wallet-standard-wallet-adapter/-/wallet-standard-wallet-adapter-1.1.4.tgz", - "integrity": "sha512-YSBrxwov4irg2hx9gcmM4VTew3ofNnkqsXQ42JwcS6ykF1P1ecVY8JCbrv75Nwe6UodnqeoZRbN7n/p3awtjNQ==", - "license": "Apache-2.0", - "dependencies": { - "@solana/wallet-standard-wallet-adapter-base": "^1.1.4", - "@solana/wallet-standard-wallet-adapter-react": "^1.1.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@solana/wallet-standard-wallet-adapter-base": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@solana/wallet-standard-wallet-adapter-base/-/wallet-standard-wallet-adapter-base-1.1.4.tgz", - "integrity": "sha512-Q2Rie9YaidyFA4UxcUIxUsvynW+/gE2noj/Wmk+IOwDwlVrJUAXCvFaCNsPDSyKoiYEKxkSnlG13OA1v08G4iw==", - "license": "Apache-2.0", - "dependencies": { - "@solana/wallet-adapter-base": "^0.9.23", - "@solana/wallet-standard-chains": "^1.1.1", - "@solana/wallet-standard-features": "^1.3.0", - "@solana/wallet-standard-util": "^1.1.2", - "@wallet-standard/app": "^1.1.0", - "@wallet-standard/base": "^1.1.0", - "@wallet-standard/features": "^1.1.0", - "@wallet-standard/wallet": "^1.1.0" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "@solana/web3.js": "^1.98.0", - "bs58": "^6.0.0" - } - }, - "node_modules/@solana/wallet-standard-wallet-adapter-react": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@solana/wallet-standard-wallet-adapter-react/-/wallet-standard-wallet-adapter-react-1.1.4.tgz", - "integrity": "sha512-xa4KVmPgB7bTiWo4U7lg0N6dVUtt2I2WhEnKlIv0jdihNvtyhOjCKMjucWet6KAVhir6I/mSWrJk1U9SvVvhCg==", - "license": "Apache-2.0", - "dependencies": { - "@solana/wallet-standard-wallet-adapter-base": "^1.1.4", - "@wallet-standard/app": "^1.1.0", - "@wallet-standard/base": "^1.1.0" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "@solana/wallet-adapter-base": "*", - "react": "*" - } - }, - "node_modules/@stablelib/base64": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@stablelib/base64/-/base64-1.0.1.tgz", - "integrity": "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==", - "license": "MIT" - }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", - "license": "MIT" - }, - "node_modules/@standard-schema/utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", - "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", - "license": "MIT" - }, - "node_modules/@stripe/stripe-js": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-5.6.0.tgz", - "integrity": "sha512-w8CEY73X/7tw2KKlL3iOk679V9bWseE4GzNz3zlaYxcTjmcmWOathRb0emgo/QQ3eoNzmq68+2Y2gxluAv3xGw==", - "license": "MIT", "engines": { - "node": ">=12.16" + "node": ">=20.0.0" } }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { @@ -6542,15 +5802,6 @@ } } }, - "node_modules/@swc/helpers": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.21.tgz", - "integrity": "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.8.0" - } - }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -6564,16 +5815,6 @@ "node": ">=10" } }, - "node_modules/@tanstack/query-core": { - "version": "5.87.4", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.87.4.tgz", - "integrity": "sha512-uNsg6zMxraEPDVO2Bn+F3/ctHi+Zsk+MMpcN8h6P7ozqD088F6mFY5TfGM7zuyIrL7HKpDyu6QHfLWiDxh3cuw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, "node_modules/@tootallnate/once": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.1.tgz", @@ -6929,12 +6170,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "license": "MIT" - }, "node_modules/@types/qs": { "version": "6.15.1", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz", @@ -6953,7 +6188,7 @@ "version": "19.1.17", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.17.tgz", "integrity": "sha512-Qec1E3mhALmaspIrhWt9jkQMNdw6bReVu64mjvhbhq2NFPftLPVr+l1SZgmw/66WwBNpDh7ao5AT6gF5v41PFA==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.0.2" @@ -7045,12 +6280,6 @@ "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", "license": "MIT" }, - "node_modules/@types/use-sync-external-store": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", - "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", - "license": "MIT" - }, "node_modules/@types/yargs": { "version": "17.0.35", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", @@ -7634,104 +6863,6 @@ "@urql/core": "^5.0.0" } }, - "node_modules/@wallet-standard/app": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@wallet-standard/app/-/app-1.1.0.tgz", - "integrity": "sha512-3CijvrO9utx598kjr45hTbbeeykQrQfKmSnxeWOgU25TOEpvcipD/bYDQWIqUv1Oc6KK4YStokSMu/FBNecGUQ==", - "license": "Apache-2.0", - "dependencies": { - "@wallet-standard/base": "^1.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@wallet-standard/base": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@wallet-standard/base/-/base-1.1.0.tgz", - "integrity": "sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=16" - } - }, - "node_modules/@wallet-standard/core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@wallet-standard/core/-/core-1.1.1.tgz", - "integrity": "sha512-5Xmjc6+Oe0hcPfVc5n8F77NVLwx1JVAoCVgQpLyv/43/bhtIif+Gx3WUrDlaSDoM8i2kA2xd6YoFbHCxs+e0zA==", - "license": "Apache-2.0", - "dependencies": { - "@wallet-standard/app": "^1.1.0", - "@wallet-standard/base": "^1.1.0", - "@wallet-standard/errors": "^0.1.1", - "@wallet-standard/features": "^1.1.0", - "@wallet-standard/wallet": "^1.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@wallet-standard/errors": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@wallet-standard/errors/-/errors-0.1.1.tgz", - "integrity": "sha512-V8Ju1Wvol8i/VDyQOHhjhxmMVwmKiwyxUZBnHhtiPZJTWY0U/Shb2iEWyGngYEbAkp2sGTmEeNX1tVyGR7PqNw==", - "license": "Apache-2.0", - "dependencies": { - "chalk": "^5.4.1", - "commander": "^13.1.0" - }, - "bin": { - "errors": "bin/cli.mjs" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@wallet-standard/errors/node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@wallet-standard/errors/node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@wallet-standard/features": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@wallet-standard/features/-/features-1.1.0.tgz", - "integrity": "sha512-hiEivWNztx73s+7iLxsuD1sOJ28xtRix58W7Xnz4XzzA/pF0+aicnWgjOdA10doVDEDZdUuZCIIqG96SFNlDUg==", - "license": "Apache-2.0", - "dependencies": { - "@wallet-standard/base": "^1.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@wallet-standard/wallet": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@wallet-standard/wallet/-/wallet-1.1.0.tgz", - "integrity": "sha512-Gt8TnSlDZpAl+RWOOAB/kuvC7RpcdWAlFbHNoi4gsXsfaWa1QCT6LBcfIYTPdOZC9OVZUDwqGuGAcqZejDmHjg==", - "license": "Apache-2.0", - "dependencies": { - "@wallet-standard/base": "^1.1.0" - }, - "engines": { - "node": ">=16" - } - }, "node_modules/@xmldom/xmldom": { "version": "0.8.13", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", @@ -7741,21 +6872,6 @@ "node": ">=10.0.0" } }, - "node_modules/@zxcvbn-ts/core": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@zxcvbn-ts/core/-/core-3.0.4.tgz", - "integrity": "sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==", - "license": "MIT", - "dependencies": { - "fastest-levenshtein": "1.0.16" - } - }, - "node_modules/@zxcvbn-ts/language-common": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-common/-/language-common-3.0.4.tgz", - "integrity": "sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw==", - "license": "MIT" - }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -7764,27 +6880,6 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/abitype": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.4.tgz", - "integrity": "sha512-dpKH+N27vRjarMVTFFkeY445VTKftzGWpL0FiT7xmVmzQRKazZexzC5uHG0f6XKsVLAuUlndnbGau6lRejClxg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3.22.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -7886,12 +6981,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/alien-signals": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-2.0.6.tgz", - "integrity": "sha512-P3TxJSe31bUHBiblg59oU1PpaWPtmxF9GhJ/cB7OkgJ0qN/ifFSKUI25/v8ZhsT+lIG6ac8DpTOplXxORX6F3Q==", - "license": "MIT" - }, "node_modules/anser": { "version": "1.4.10", "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", @@ -8324,21 +7413,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, "node_modules/babel-plugin-module-resolver": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.3.tgz", @@ -8538,18 +7612,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, - "node_modules/base-64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", - "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", - "license": "MIT" - }, - "node_modules/base-x": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.1.tgz", - "integrity": "sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==", - "license": "MIT" - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -8746,16 +7808,6 @@ "node": ">=8" } }, - "node_modules/browser-tabs-lock": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-tabs-lock/-/browser-tabs-lock-1.3.0.tgz", - "integrity": "sha512-g6nHaobTiT0eMZ7jh16YpD2kcjAp+PInbiVq3M1x6KKaEIVhT4v9oURNIpZLOZ3LQbQ3XYfNhMAb/9hzNLIWrw==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "lodash": ">=4.17.21" - } - }, "node_modules/browserslist": { "version": "4.28.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", @@ -8802,15 +7854,6 @@ "node": ">= 6" } }, - "node_modules/bs58": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", - "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", - "license": "MIT", - "dependencies": { - "base-x": "^5.0.0" - } - }, "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -8972,6 +8015,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -9173,15 +8217,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -9253,15 +8288,6 @@ "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", - "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", - "license": "MIT", - "engines": { - "node": ">=20" - } - }, "node_modules/component-emitter": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", @@ -9426,12 +8452,6 @@ "node": ">= 0.6" } }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "license": "MIT" - }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", @@ -9454,26 +8474,6 @@ "dev": true, "license": "MIT" }, - "node_modules/copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "license": "MIT", - "dependencies": { - "toggle-selection": "^1.0.6" - } - }, - "node_modules/core-js": { - "version": "3.41.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.41.0.tgz", - "integrity": "sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA==", - "hasInstallScript": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-js-compat": { "version": "3.49.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", @@ -9510,22 +8510,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -9578,12 +8562,6 @@ "node": ">= 8" } }, - "node_modules/crypto-js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", - "license": "MIT" - }, "node_modules/css-in-js-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", @@ -9815,15 +8793,6 @@ } } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/decimal.js": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", @@ -10067,12 +9036,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/dijkstrajs": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", - "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==", - "license": "MIT" - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -10323,6 +9286,7 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -11612,12 +10576,6 @@ "node": ">=6" } }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "license": "MIT" - }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -12292,15 +11250,6 @@ "integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==", "license": "Unlicense" }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, "node_modules/fastq": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", @@ -12480,12 +11429,6 @@ "json5": "^2.2.3" } }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "license": "MIT" - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -13274,6 +12217,15 @@ "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", "license": "BSD-3-Clause" }, + "node_modules/iceberg-js": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz", + "integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -13286,12 +12238,6 @@ "node": ">=0.10.0" } }, - "node_modules/idb-keyval": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz", - "integrity": "sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==", - "license": "Apache-2.0" - }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -13336,20 +12282,11 @@ "node": ">=16.x" } }, - "node_modules/immer": { - "version": "11.1.8", - "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.8.tgz", - "integrity": "sha512-/tbkHMW7y10Lx6i1crLjD4/OhNkRG+Fo7byZHtah0547nIeXYcpIXaUh0IAQY6gO5459qpGGYapcEOHtFXkIuA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -13366,6 +12303,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -13432,16 +12370,6 @@ "css-in-js-utils": "^3.1.0" } }, - "node_modules/input-otp": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.4.2.tgz", - "integrity": "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" - } - }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -13513,6 +12441,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, "license": "MIT" }, "node_modules/is-async-function": { @@ -13995,21 +12924,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, - "node_modules/isows": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", - "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "peerDependencies": { - "ws": "*" - } - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -15016,12 +13930,6 @@ "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==", "license": "MIT" }, - "node_modules/js-base64": { - "version": "3.7.8", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.8.tgz", - "integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==", - "license": "BSD-3-Clause" - }, "node_modules/js-cookie": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", @@ -15124,6 +14032,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { @@ -15580,6 +14489,7 @@ "version": "4.18.1", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, "license": "MIT" }, "node_modules/lodash.debounce": { @@ -17159,47 +16069,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ox": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.6.9.tgz", - "integrity": "sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "^1.10.1", - "@noble/curves": "^1.6.0", - "@noble/hashes": "^1.5.0", - "@scure/bip32": "^1.5.0", - "@scure/bip39": "^1.4.0", - "abitype": "^1.0.6", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/ox/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", @@ -17254,6 +16123,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -17266,6 +16136,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -17398,6 +16269,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17668,16 +16540,6 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "license": "MIT" }, - "node_modules/preact": { - "version": "10.24.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.2.tgz", - "integrity": "sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -17736,7 +16598,7 @@ "version": "5.22.0", "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.22.0.tgz", "integrity": "sha512-vtpjW3XuYCSnMsNVBjLMNkTj6OZbudcPPTPYHqX0CJfpcdWciI1dM8uHETwmDxxiqEwCIE6WvXucWUetJgfu/A==", - "devOptional": true, + "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { @@ -17798,256 +16660,103 @@ "node": ">= 6" } }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", - "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/psl": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", - "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "funding": { - "url": "https://github.com/sponsors/lupomontero" - } - }, - "node_modules/pump": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT" - }, - "node_modules/qrcode": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", - "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", - "license": "MIT", - "dependencies": { - "dijkstrajs": "^1.0.1", - "pngjs": "^5.0.0", - "yargs": "^15.3.1" - }, - "bin": { - "qrcode": "bin/qrcode" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/qrcode-terminal": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz", - "integrity": "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==", - "bin": { - "qrcode-terminal": "bin/qrcode-terminal.js" - } - }, - "node_modules/qrcode.react": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.2.0.tgz", - "integrity": "sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==", - "license": "ISC", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "node_modules/qrcode/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/qrcode/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/qrcode/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/qrcode/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "license": "MIT", "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" } }, - "node_modules/qrcode/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" }, "engines": { - "node": ">=8" + "node": ">= 0.10" } }, - "node_modules/qrcode/node_modules/pngjs": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", - "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "license": "MIT", "engines": { - "node": ">=10.13.0" + "node": ">=10" } }, - "node_modules/qrcode/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "punycode": "^2.3.1" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/lupomontero" } }, - "node_modules/qrcode/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "license": "ISC" - }, - "node_modules/qrcode/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dev": true, "license": "MIT", "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "node_modules/qrcode/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "license": "ISC", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qrcode-terminal": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz", + "integrity": "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==", + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, "node_modules/qs": { "version": "6.14.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", @@ -18249,6 +16958,22 @@ "react": ">=17.0.0" } }, + "node_modules/react-hook-form": { + "version": "7.79.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.79.0.tgz", + "integrity": "sha512-mhYp/MTmXvzYX6AJcJVko0rktoIhhmRnEouObj4wF5i/tCttgJvnp1+9wRkpITZjDTqpo4IOSJqu0dBlPlV/Lw==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, "node_modules/react-is": { "version": "19.2.6", "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.6.tgz", @@ -18526,18 +17251,6 @@ "react-native-svg": ">=12.0.0" } }, - "node_modules/react-native-url-polyfill": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-2.0.0.tgz", - "integrity": "sha512-My330Do7/DvKnEvwQc0WdcBnFPploYKp9CYlefDXzIdEaA+PAhDYllkvGeEroEzvc4Kzzj2O4yVdz8v6fjRvhA==", - "license": "MIT", - "dependencies": { - "whatwg-url-without-unicode": "8.0.0-3" - }, - "peerDependencies": { - "react-native": "*" - } - }, "node_modules/react-native-web": { "version": "0.21.2", "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.2.tgz", @@ -18702,29 +17415,6 @@ "async-limiter": "~1.0.0" } }, - "node_modules/react-redux": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", - "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", - "license": "MIT", - "dependencies": { - "@types/use-sync-external-store": "^0.0.6", - "use-sync-external-store": "^1.4.0" - }, - "peerDependencies": { - "@types/react": "^18.2.25 || ^19", - "react": "^18.0 || ^19", - "redux": "^5.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "redux": { - "optional": true - } - } - }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", @@ -18838,30 +17528,6 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, - "node_modules/redux": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", - "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", - "license": "MIT" - }, - "node_modules/redux-persist": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz", - "integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==", - "license": "MIT", - "peerDependencies": { - "redux": ">4.0.0" - } - }, - "node_modules/redux-thunk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", - "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", - "license": "MIT", - "peerDependencies": { - "redux": "^5.0.0" - } - }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -18903,12 +17569,6 @@ "node": ">=4" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "license": "MIT" - }, "node_modules/regexp.prototype.flags": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", @@ -18983,12 +17643,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "license": "ISC" - }, "node_modules/requireg": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/requireg/-/requireg-0.2.2.tgz", @@ -19018,12 +17672,6 @@ "dev": true, "license": "MIT" }, - "node_modules/reselect": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", - "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", - "license": "MIT" - }, "node_modules/resolve": { "version": "1.22.12", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", @@ -19462,12 +18110,6 @@ "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==", "license": "MIT" }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "license": "ISC" - }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -20155,12 +18797,6 @@ "integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==", "license": "MIT" }, - "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", - "license": "MIT" - }, "node_modules/sucrase": { "version": "3.35.1", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", @@ -20387,12 +19023,6 @@ "dev": true, "license": "MIT" }, - "node_modules/tabbable": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", - "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", - "license": "MIT" - }, "node_modules/tar": { "version": "7.5.15", "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.15.tgz", @@ -20591,12 +19221,6 @@ "node": ">=8.0" } }, - "node_modules/toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", - "license": "MIT" - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -20987,7 +19611,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -21379,135 +20003,6 @@ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, - "node_modules/viem": { - "version": "2.48.11", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.48.11.tgz", - "integrity": "sha512-+WZ5E0dBS6GtKb+1wEk5DeYRRRW42+pFnXCo67Ydodf42sBwO+hu3wnQy66lc4MKmHz+llPVdbyehYr9oTE2iw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@noble/curves": "1.9.1", - "@noble/hashes": "1.8.0", - "@scure/bip32": "1.7.0", - "@scure/bip39": "1.6.0", - "abitype": "1.2.3", - "isows": "1.0.7", - "ox": "0.14.20", - "ws": "8.18.3" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/viem/node_modules/@noble/curves": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", - "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/viem/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/viem/node_modules/abitype": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz", - "integrity": "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/wevm" - }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3.22.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/viem/node_modules/ox": { - "version": "0.14.20", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.14.20.tgz", - "integrity": "sha512-rby38C3nDn8eQkf29Zgw4hkCZJ64Qqi0zRPWL8ENUQ7JVuoITqrVtwWQgM/He19SCMUEc7hS/Sjw0jIOSLJhOw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "^1.11.0", - "@noble/ciphers": "^1.3.0", - "@noble/curves": "1.9.1", - "@noble/hashes": "^1.8.0", - "@scure/bip32": "^1.7.0", - "@scure/bip39": "^1.6.0", - "abitype": "^1.2.3", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/viem/node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/vlq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz", @@ -21730,12 +20225,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "license": "ISC" - }, "node_modules/which-typed-array": { "version": "1.1.20", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", @@ -22000,6 +20489,7 @@ "version": "1.10.3", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", + "dev": true, "license": "ISC", "engines": { "node": ">= 6" @@ -22064,9 +20554,9 @@ } }, "node_modules/zustand": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.3.tgz", - "integrity": "sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==", + "version": "5.0.14", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.14.tgz", + "integrity": "sha512-/8tAspM5LMPr28b3fwLYrtdj77ECpfZviaP75CMTnwO8ISyaE4GDIG/9rDDYq/cH9D2Xw2A2RXglLInmVBQB/g==", "license": "MIT", "engines": { "node": ">=12.20.0"