zopassport 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +407 -0
  3. package/app/.env.example +15 -0
  4. package/app/README.md +28 -0
  5. package/app/package.json +24 -0
  6. package/app/reanimated-mock.js +102 -0
  7. package/app/reanimated-mock.jsx +97 -0
  8. package/app/src/App.tsx +331 -0
  9. package/app/src/components/FounderBadge.tsx +26 -0
  10. package/app/src/components/OTPInput.tsx +149 -0
  11. package/app/src/components/PhoneInput.tsx +109 -0
  12. package/app/src/components/ZoAuth.tsx +320 -0
  13. package/app/src/components/ZoAvatar.tsx +87 -0
  14. package/app/src/components/ZoLanding.tsx +231 -0
  15. package/app/src/components/ZoOnboarding.tsx +524 -0
  16. package/app/src/components/ZoPassportCard.tsx +183 -0
  17. package/app/src/components/ZoProgressRing.tsx +57 -0
  18. package/app/src/components/index.ts +16 -0
  19. package/app/src/components/wallet/MovingShine.tsx +43 -0
  20. package/app/src/components/wallet/TransactionItem.tsx +84 -0
  21. package/app/src/components/wallet/TransactionList.tsx +65 -0
  22. package/app/src/components/wallet/WalletCard.tsx +152 -0
  23. package/app/src/components/wallet/WalletScreen.tsx +190 -0
  24. package/app/src/components/wallet/ZoToken.tsx +69 -0
  25. package/app/src/components/wallet/index.ts +8 -0
  26. package/app/src/components/wallet/styles/index.ts +4 -0
  27. package/app/src/components/wallet/styles/walletStyles.ts +210 -0
  28. package/app/src/sdk/ZoPassportSDK.ts +277 -0
  29. package/app/src/sdk/lib/api/auth.ts +223 -0
  30. package/app/src/sdk/lib/api/avatar.ts +155 -0
  31. package/app/src/sdk/lib/api/client.ts +135 -0
  32. package/app/src/sdk/lib/api/index.ts +8 -0
  33. package/app/src/sdk/lib/api/profile.ts +80 -0
  34. package/app/src/sdk/lib/api/wallet.ts +59 -0
  35. package/app/src/sdk/lib/types/auth.ts +78 -0
  36. package/app/src/sdk/lib/types/avatar.ts +22 -0
  37. package/app/src/sdk/lib/types/index.ts +8 -0
  38. package/app/src/sdk/lib/types/profile.ts +18 -0
  39. package/app/src/sdk/lib/types/wallet.ts +103 -0
  40. package/app/src/sdk/lib/types.ts +205 -0
  41. package/app/src/sdk/lib/utils/index.ts +6 -0
  42. package/app/src/sdk/lib/utils/phone.ts +71 -0
  43. package/app/src/sdk/lib/utils/storage.ts +116 -0
  44. package/app/src/sdk/lib/utils/wallet.ts +73 -0
  45. package/app/src/sdk/types.ts +205 -0
  46. package/app/src/styles.css +154 -0
  47. package/app/svg-mock.js +125 -0
  48. package/app/svg-mock.jsx +120 -0
  49. package/app/vite.config.ts +70 -0
  50. package/assets/ASSETS_MANIFEST.md +124 -0
  51. package/assets/bae.png +0 -0
  52. package/assets/bro.png +0 -0
  53. package/assets/cultural-stickers/Business.png +0 -0
  54. package/assets/cultural-stickers/Default (2).jpg +0 -0
  55. package/assets/cultural-stickers/Design.png +0 -0
  56. package/assets/cultural-stickers/FollowYourHeart.png +0 -0
  57. package/assets/cultural-stickers/Food.png +0 -0
  58. package/assets/cultural-stickers/Game.png +0 -0
  59. package/assets/cultural-stickers/Health&Fitness.png +0 -0
  60. package/assets/cultural-stickers/Home&Lifestyle.png +0 -0
  61. package/assets/cultural-stickers/Law.png +0 -0
  62. package/assets/cultural-stickers/Literature&Stories.png +0 -0
  63. package/assets/cultural-stickers/Music&Entertainment.png +0 -0
  64. package/assets/cultural-stickers/Nature&Wildlife.png +0 -0
  65. package/assets/cultural-stickers/Photography.png +0 -0
  66. package/assets/cultural-stickers/Science&Technology.png +0 -0
  67. package/assets/cultural-stickers/Spiritual.png +0 -0
  68. package/assets/cultural-stickers/Sport.png +0 -0
  69. package/assets/cultural-stickers/Stories&Journal.png +0 -0
  70. package/assets/cultural-stickers/Television&Cinema.png +0 -0
  71. package/assets/cultural-stickers/Travel&Adventure.png +0 -0
  72. package/assets/cultural-stickers/z.jpg (1).jpg +0 -0
  73. package/assets/figma-assets/landing-zo-logo.png +0 -0
  74. package/assets/images/rank1.jpeg +0 -0
  75. package/assets/index.ts +76 -0
  76. package/assets/lotties/loader.json +1216 -0
  77. package/assets/lotties/spinner.json +1 -0
  78. package/assets/videos/loading-screen-background.mp4 +0 -0
  79. package/assets/videos/opening-disks.mp4 +0 -0
  80. package/assets/wallet/constants.ts +38 -0
  81. package/assets/zo-coin.gif +0 -0
  82. package/assets/zo-fallback.png +0 -0
  83. package/dist/assets/index.d.mts +136 -0
  84. package/dist/assets/index.d.ts +136 -0
  85. package/dist/assets/index.js +133 -0
  86. package/dist/assets/index.js.map +1 -0
  87. package/dist/assets/index.mjs +100 -0
  88. package/dist/assets/index.mjs.map +1 -0
  89. package/dist/index.d.mts +789 -0
  90. package/dist/index.d.ts +789 -0
  91. package/dist/index.js +1118 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/index.mjs +1060 -0
  94. package/dist/index.mjs.map +1 -0
  95. package/dist/react-native.d.mts +537 -0
  96. package/dist/react-native.d.ts +537 -0
  97. package/dist/react-native.js +1617 -0
  98. package/dist/react-native.js.map +1 -0
  99. package/dist/react-native.mjs +1588 -0
  100. package/dist/react-native.mjs.map +1 -0
  101. package/dist/react.d.mts +824 -0
  102. package/dist/react.d.ts +824 -0
  103. package/dist/react.js +3856 -0
  104. package/dist/react.js.map +1 -0
  105. package/dist/react.mjs +3801 -0
  106. package/dist/react.mjs.map +1 -0
  107. package/package.json +112 -0
  108. package/scripts/init.js +196 -0
  109. package/scripts/postinstall.js +174 -0
  110. package/scripts/verify-build.js +121 -0
@@ -0,0 +1,155 @@
1
+ // src/lib/api/avatar.ts
2
+ // ZO API avatar generation functions
3
+
4
+ import { ZoApiClient } from './client';
5
+ import { StorageAdapter } from '../utils/storage';
6
+ import type {
7
+ ZoAvatarGenerateRequest,
8
+ ZoAvatarGenerateResponse,
9
+ ZoAvatarStatusResponse,
10
+ ZoErrorResponse,
11
+ } from '../types';
12
+
13
+ export class ZoAvatar {
14
+ constructor(
15
+ private client: ZoApiClient,
16
+ private storage: StorageAdapter
17
+ ) {}
18
+
19
+ /**
20
+ * Generate avatar for user
21
+ */
22
+ async generateAvatar(
23
+ accessToken: string,
24
+ bodyType: 'bro' | 'bae'
25
+ ): Promise<{
26
+ success: boolean;
27
+ task_id?: string;
28
+ status?: string;
29
+ error?: string;
30
+ }> {
31
+ try {
32
+ const payload: ZoAvatarGenerateRequest = {
33
+ body_type: bodyType,
34
+ };
35
+
36
+ const response = await this.client.axiosInstance.post<ZoAvatarGenerateResponse>(
37
+ '/api/v1/avatar/generate/',
38
+ payload,
39
+ {
40
+ headers: {
41
+ Authorization: `Bearer ${accessToken}`,
42
+ },
43
+ }
44
+ );
45
+
46
+ return {
47
+ success: true,
48
+ task_id: response.data.task_id,
49
+ status: response.data.status,
50
+ };
51
+ } catch (error: any) {
52
+ const errorData = error.response?.data as ZoErrorResponse;
53
+ return {
54
+ success: false,
55
+ error: errorData?.detail || errorData?.message || 'Failed to generate avatar',
56
+ };
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Check avatar generation status
62
+ */
63
+ async getAvatarStatus(
64
+ accessToken: string,
65
+ taskId: string
66
+ ): Promise<{
67
+ success: boolean;
68
+ status?: 'pending' | 'processing' | 'completed' | 'failed';
69
+ avatarUrl?: string;
70
+ error?: string;
71
+ }> {
72
+ try {
73
+ const response = await this.client.axiosInstance.get<ZoAvatarStatusResponse>(
74
+ `/api/v1/avatar/status/${taskId}/`,
75
+ {
76
+ headers: {
77
+ Authorization: `Bearer ${accessToken}`,
78
+ },
79
+ }
80
+ );
81
+
82
+ return {
83
+ success: true,
84
+ status: response.data.status,
85
+ avatarUrl: response.data.result?.avatar_url,
86
+ };
87
+ } catch (error: any) {
88
+ const errorData = error.response?.data as ZoErrorResponse;
89
+ return {
90
+ success: false,
91
+ error: errorData?.detail || errorData?.message || 'Failed to get avatar status',
92
+ };
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Poll avatar status until completion
98
+ */
99
+ async pollAvatarStatus(
100
+ accessToken: string,
101
+ taskId: string,
102
+ options: {
103
+ onProgress?: (status: string) => void;
104
+ onComplete?: (avatarUrl: string) => void;
105
+ onError?: (error: string) => void;
106
+ maxAttempts?: number;
107
+ interval?: number;
108
+ } = {}
109
+ ): Promise<void> {
110
+ const {
111
+ onProgress,
112
+ onComplete,
113
+ onError,
114
+ maxAttempts = 30,
115
+ interval = 2000,
116
+ } = options;
117
+
118
+ let attempts = 0;
119
+
120
+ const poll = async () => {
121
+ attempts++;
122
+
123
+ if (attempts > maxAttempts) {
124
+ const timeoutError = 'Avatar generation timed out';
125
+ onError?.(timeoutError);
126
+ return;
127
+ }
128
+
129
+ const result = await this.getAvatarStatus(accessToken, taskId);
130
+
131
+ if (!result.success) {
132
+ onError?.(result.error || 'Unknown error');
133
+ return;
134
+ }
135
+
136
+ onProgress?.(result.status || 'unknown');
137
+
138
+ if (result.status === 'completed' && result.avatarUrl) {
139
+ onComplete?.(result.avatarUrl);
140
+ return;
141
+ }
142
+
143
+ if (result.status === 'failed') {
144
+ onError?.('Avatar generation failed');
145
+ return;
146
+ }
147
+
148
+ // Continue polling
149
+ setTimeout(poll, interval);
150
+ };
151
+
152
+ poll();
153
+ }
154
+ }
155
+
@@ -0,0 +1,135 @@
1
+ // src/lib/api/client.ts
2
+ // ZO API HTTP client configuration
3
+
4
+ import axios, { AxiosInstance } from 'axios';
5
+ import { StorageAdapter, STORAGE_KEYS, LocalStorageAdapter } from '../utils/storage';
6
+
7
+ export interface ZoPassportConfig {
8
+ /** Your ZO client key (required) */
9
+ clientKey: string;
10
+ /** API base URL (default: https://api.io.zo.xyz) */
11
+ baseUrl?: string;
12
+ /** Request timeout in ms (default: 10000) */
13
+ timeout?: number;
14
+ /** Storage adapter for tokens (default: LocalStorageAdapter) */
15
+ storageAdapter?: StorageAdapter;
16
+ }
17
+
18
+ /**
19
+ * Generate new device credentials
20
+ */
21
+ function generateDeviceCredentials(): { deviceId: string; deviceSecret: string } {
22
+ const deviceId = `web-${Date.now()}-${Math.random().toString(36).substring(7)}`;
23
+ const deviceSecret = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
24
+ return { deviceId, deviceSecret };
25
+ }
26
+
27
+ export class ZoApiClient {
28
+ private client: AxiosInstance;
29
+ private config: ZoPassportConfig;
30
+ private storage: StorageAdapter;
31
+
32
+ constructor(config: ZoPassportConfig) {
33
+ this.config = config;
34
+ this.storage = config.storageAdapter || new LocalStorageAdapter();
35
+
36
+ this.client = axios.create({
37
+ baseURL: config.baseUrl || 'https://api.io.zo.xyz',
38
+ timeout: config.timeout || 10000,
39
+ headers: {
40
+ 'Content-Type': 'application/json',
41
+ 'Accept': 'application/json',
42
+ },
43
+ });
44
+
45
+ this.setupInterceptors();
46
+ }
47
+
48
+ private async setupInterceptors() {
49
+ // Request interceptor: Add required headers
50
+ this.client.interceptors.request.use(async (config) => {
51
+ // Always add client key
52
+ config.headers['client-key'] = this.config.clientKey;
53
+
54
+ // Get or generate device credentials
55
+ const credentials = await this.getOrCreateDeviceCredentials();
56
+ config.headers['client-device-id'] = credentials.deviceId;
57
+ config.headers['client-device-secret'] = credentials.deviceSecret;
58
+
59
+ // Add auth token if available
60
+ const token = await this.storage.getItem(STORAGE_KEYS.ACCESS_TOKEN);
61
+ if (token) {
62
+ config.headers['Authorization'] = `Bearer ${token}`;
63
+ }
64
+
65
+ return config;
66
+ });
67
+
68
+ // Response interceptor: Handle token refresh on 401
69
+ this.client.interceptors.response.use(
70
+ (response) => response,
71
+ async (error) => {
72
+ const originalRequest = error.config;
73
+
74
+ // If 401 and we haven't retried yet
75
+ if (error.response?.status === 401 && !originalRequest._retry) {
76
+ originalRequest._retry = true;
77
+
78
+ const refreshToken = await this.storage.getItem(STORAGE_KEYS.REFRESH_TOKEN);
79
+ if (refreshToken) {
80
+ try {
81
+ const response = await this.client.post('/api/v1/auth/token/refresh/', {
82
+ refresh_token: refreshToken,
83
+ });
84
+
85
+ if (response.data?.access) {
86
+ await this.storage.setItem(STORAGE_KEYS.ACCESS_TOKEN, response.data.access);
87
+ if (response.data.refresh) {
88
+ await this.storage.setItem(STORAGE_KEYS.REFRESH_TOKEN, response.data.refresh);
89
+ }
90
+
91
+ // Retry original request with new token
92
+ originalRequest.headers['Authorization'] = `Bearer ${response.data.access}`;
93
+ return this.client(originalRequest);
94
+ }
95
+ } catch (refreshError) {
96
+ // Refresh failed - clear session
97
+ await this.storage.removeItem(STORAGE_KEYS.ACCESS_TOKEN);
98
+ await this.storage.removeItem(STORAGE_KEYS.REFRESH_TOKEN);
99
+ }
100
+ }
101
+ }
102
+
103
+ return Promise.reject(error);
104
+ }
105
+ );
106
+ }
107
+
108
+ private async getOrCreateDeviceCredentials(): Promise<{ deviceId: string; deviceSecret: string }> {
109
+ // Try to get from storage
110
+ const storedId = await this.storage.getItem(STORAGE_KEYS.CLIENT_DEVICE_ID);
111
+ const storedSecret = await this.storage.getItem(STORAGE_KEYS.CLIENT_DEVICE_SECRET);
112
+
113
+ if (storedId && storedSecret) {
114
+ return { deviceId: storedId, deviceSecret: storedSecret };
115
+ }
116
+
117
+ // Generate new credentials
118
+ const credentials = generateDeviceCredentials();
119
+
120
+ // Save to storage
121
+ await this.storage.setItem(STORAGE_KEYS.CLIENT_DEVICE_ID, credentials.deviceId);
122
+ await this.storage.setItem(STORAGE_KEYS.CLIENT_DEVICE_SECRET, credentials.deviceSecret);
123
+
124
+ return credentials;
125
+ }
126
+
127
+ get axiosInstance(): AxiosInstance {
128
+ return this.client;
129
+ }
130
+
131
+ getStorage(): StorageAdapter {
132
+ return this.storage;
133
+ }
134
+ }
135
+
@@ -0,0 +1,8 @@
1
+ // src/lib/api/index.ts
2
+ // Re-export all API modules
3
+
4
+ export { ZoApiClient, type ZoPassportConfig } from './client';
5
+ export { ZoAuth } from './auth';
6
+ export { ZoProfile } from './profile';
7
+ export { ZoAvatar } from './avatar';
8
+
@@ -0,0 +1,80 @@
1
+ // src/lib/api/profile.ts
2
+ // ZO API profile functions
3
+
4
+ import { ZoApiClient } from './client';
5
+ import { StorageAdapter } from '../utils/storage';
6
+ import type { ZoProfileResponse, ZoProfileUpdatePayload, ZoErrorResponse } from '../types';
7
+
8
+ export class ZoProfile {
9
+ constructor(
10
+ private client: ZoApiClient,
11
+ private storage: StorageAdapter
12
+ ) {}
13
+
14
+ /**
15
+ * Get user profile
16
+ */
17
+ async getProfile(accessToken: string): Promise<{
18
+ success: boolean;
19
+ profile?: ZoProfileResponse;
20
+ error?: string;
21
+ }> {
22
+ try {
23
+ const response = await this.client.axiosInstance.get<ZoProfileResponse>(
24
+ '/api/v1/profile/me/',
25
+ {
26
+ headers: {
27
+ Authorization: `Bearer ${accessToken}`,
28
+ },
29
+ }
30
+ );
31
+
32
+ return {
33
+ success: true,
34
+ profile: response.data,
35
+ };
36
+ } catch (error: any) {
37
+ const errorData = error.response?.data as ZoErrorResponse;
38
+ return {
39
+ success: false,
40
+ error: errorData?.detail || errorData?.message || 'Failed to fetch profile',
41
+ };
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Update user profile (partial updates supported)
47
+ */
48
+ async updateProfile(
49
+ accessToken: string,
50
+ updates: ZoProfileUpdatePayload
51
+ ): Promise<{
52
+ success: boolean;
53
+ profile?: ZoProfileResponse;
54
+ error?: string;
55
+ }> {
56
+ try {
57
+ const response = await this.client.axiosInstance.post<ZoProfileResponse>(
58
+ '/api/v1/profile/me/',
59
+ updates,
60
+ {
61
+ headers: {
62
+ Authorization: `Bearer ${accessToken}`,
63
+ },
64
+ }
65
+ );
66
+
67
+ return {
68
+ success: true,
69
+ profile: response.data,
70
+ };
71
+ } catch (error: any) {
72
+ const errorData = error.response?.data as ZoErrorResponse;
73
+ return {
74
+ success: false,
75
+ error: errorData?.detail || errorData?.message || 'Failed to update profile',
76
+ };
77
+ }
78
+ }
79
+ }
80
+
@@ -0,0 +1,59 @@
1
+ // src/lib/api/wallet.ts
2
+ // Framework-agnostic Wallet API
3
+
4
+ import { ZoApiClient } from './client';
5
+ import type { BalanceResponse, TransactionsResponse, Transaction } from '../types/wallet';
6
+
7
+ export class ZoWallet {
8
+ private client: ZoApiClient;
9
+
10
+ constructor(client: ZoApiClient) {
11
+ this.client = client;
12
+ }
13
+
14
+ /**
15
+ * Get wallet balance
16
+ * @returns Wallet balance amount
17
+ */
18
+ async getBalance(): Promise<number> {
19
+ try {
20
+ const response = await this.client.axiosInstance.get<BalanceResponse>(
21
+ '/api/v1/web3/token/airdrops/summary'
22
+ );
23
+ return response.data?.data?.total_amount ?? 0;
24
+ } catch (error) {
25
+ console.error('[ZoWallet] Failed to fetch balance:', error);
26
+ throw error;
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Get transaction history
32
+ * @param page - Optional page number for pagination
33
+ * @returns Array of transactions
34
+ */
35
+ async getTransactions(page?: number): Promise<{
36
+ transactions: Transaction[];
37
+ next?: string;
38
+ previous?: string;
39
+ count: number;
40
+ }> {
41
+ try {
42
+ const url = page
43
+ ? `/api/v1/profile/completion-grants/claims?page=${page}`
44
+ : '/api/v1/profile/completion-grants/claims';
45
+
46
+ const response = await this.client.axiosInstance.get<TransactionsResponse>(url);
47
+
48
+ return {
49
+ transactions: response.data?.data?.results ?? [],
50
+ next: response.data?.data?.next,
51
+ previous: response.data?.data?.previous,
52
+ count: response.data?.data?.count ?? 0,
53
+ };
54
+ } catch (error) {
55
+ console.error('[ZoWallet] Failed to fetch transactions:', error);
56
+ throw error;
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,78 @@
1
+ // src/lib/types/auth.ts
2
+ // Authentication-related types
3
+
4
+ export interface ZoAuthOTPRequest {
5
+ mobile_country_code: string;
6
+ mobile_number: string;
7
+ message_channel?: string;
8
+ }
9
+
10
+ export interface ZoAuthOTPVerifyRequest {
11
+ mobile_country_code: string;
12
+ mobile_number: string;
13
+ otp: string;
14
+ }
15
+
16
+ export interface ZoAuthTokens {
17
+ access: string;
18
+ refresh: string;
19
+ access_expiry: string;
20
+ refresh_expiry: string;
21
+ }
22
+
23
+ export interface ZoAuthResponse {
24
+ // Legacy fields (for backward compatibility)
25
+ token: string; // Same as access_token
26
+ valid_till: string; // Same as access_token_expiry
27
+
28
+ // Current fields
29
+ access_token: string;
30
+ access_token_expiry: string;
31
+ refresh_token: string;
32
+ refresh_token_expiry: string;
33
+ client_key: string;
34
+ device_id: string;
35
+ device_secret: string;
36
+ device_info: Record<string, any>;
37
+ user: ZoUser;
38
+ }
39
+
40
+ export interface ZoUser {
41
+ id: string; // UUID
42
+ pid: string; // PID123
43
+ first_name: string;
44
+ last_name: string;
45
+ mobile_number: string;
46
+ email_address: string;
47
+ date_of_birth: string | null;
48
+ bio: string;
49
+ pfp_image: string;
50
+ wallet_address: string; // Auto-provisioned during auth
51
+ membership: 'founder' | 'citizen' | 'none';
52
+ body_type: 'bro' | 'bae';
53
+ place_name: string;
54
+ home_location: {
55
+ lat: number;
56
+ lng: number;
57
+ } | null;
58
+ cultures: Array<{
59
+ key: string;
60
+ name: string;
61
+ icon: string;
62
+ description: string;
63
+ }>;
64
+ founder_tokens: string[]; // Array of token IDs like ["523", "204"]
65
+ avatar?: {
66
+ image: string;
67
+ status: 'pending' | 'processing' | 'completed' | 'failed';
68
+ };
69
+ }
70
+
71
+ export interface ZoErrorResponse {
72
+ detail?: string;
73
+ error?: string;
74
+ message?: string;
75
+ errors?: string[];
76
+ success?: boolean;
77
+ }
78
+
@@ -0,0 +1,22 @@
1
+ // src/lib/types/avatar.ts
2
+ // Avatar-related types
3
+
4
+ export interface ZoAvatarGenerateRequest {
5
+ body_type: 'bro' | 'bae';
6
+ }
7
+
8
+ export interface ZoAvatarGenerateResponse {
9
+ task_id: string;
10
+ status: 'pending' | 'processing' | 'completed' | 'failed';
11
+ message: string;
12
+ }
13
+
14
+ export interface ZoAvatarStatusResponse {
15
+ task_id: string;
16
+ status: 'pending' | 'processing' | 'completed' | 'failed';
17
+ result?: {
18
+ avatar_url: string;
19
+ };
20
+ error?: string;
21
+ }
22
+
@@ -0,0 +1,8 @@
1
+ // src/lib/types/index.ts
2
+ // Re-export all types
3
+
4
+ export * from './auth';
5
+ export * from './profile';
6
+ export * from './avatar';
7
+ export * from './wallet';
8
+
@@ -0,0 +1,18 @@
1
+ // src/lib/types/profile.ts
2
+ // Profile-related types
3
+
4
+ import { ZoUser } from './auth';
5
+
6
+ export interface ZoProfileResponse extends ZoUser {
7
+ mobile_country_code: string;
8
+ }
9
+
10
+ export interface ZoProfileUpdatePayload {
11
+ first_name?: string;
12
+ last_name?: string;
13
+ bio?: string;
14
+ date_of_birth?: string;
15
+ place_name?: string;
16
+ body_type?: 'bro' | 'bae';
17
+ }
18
+
@@ -0,0 +1,103 @@
1
+ // src/lib/types/wallet.ts
2
+ // Wallet-related types
3
+
4
+ // Existing wallet types
5
+ export interface ZoWallet {
6
+ address: string;
7
+ network: 'base' | 'avalanche';
8
+ balance?: number;
9
+ }
10
+
11
+ export interface ZoTokenBalanceResponse {
12
+ balance: number;
13
+ currency: {
14
+ name: string;
15
+ symbol: string;
16
+ };
17
+ }
18
+
19
+ // Wallet balance and transaction types
20
+ export interface WalletBalance {
21
+ total_amount: number;
22
+ currency: string;
23
+ }
24
+
25
+ export interface Transaction {
26
+ id: string;
27
+ created_at: string;
28
+ updated_at: string;
29
+ amount: number;
30
+ description: string;
31
+ claimed_at: string;
32
+ grant: {
33
+ id: string;
34
+ name: string;
35
+ description: string;
36
+ };
37
+ action: 'deposit' | 'spend';
38
+ }
39
+
40
+ export interface WalletUser {
41
+ avatar?: {
42
+ image: string;
43
+ };
44
+ first_name: string;
45
+ nickname?: string;
46
+ wallet_address: string;
47
+ }
48
+
49
+ // API Response types
50
+ export interface BalanceResponse {
51
+ data: {
52
+ total_amount: number;
53
+ };
54
+ }
55
+
56
+ export interface TransactionsResponse {
57
+ data: {
58
+ results: Transaction[];
59
+ next?: string;
60
+ previous?: string;
61
+ count: number;
62
+ };
63
+ }
64
+
65
+ // Formatted types for display
66
+ export interface FormattedTransaction {
67
+ id: string;
68
+ description: string;
69
+ amount: string;
70
+ date: string;
71
+ timestamp: string;
72
+ action: 'deposit' | 'spend';
73
+ color: string;
74
+ }
75
+
76
+ // React Component Props (optional, for React components)
77
+ export interface WalletCardProps {
78
+ balance: number;
79
+ user: WalletUser;
80
+ isOpen?: boolean;
81
+ onToggle?: () => void;
82
+ isLoading?: boolean;
83
+ }
84
+
85
+ export interface TransactionItemProps {
86
+ transaction: Transaction;
87
+ showDate?: boolean;
88
+ }
89
+
90
+ export interface TransactionListProps {
91
+ transactions: Transaction[];
92
+ isLoading?: boolean;
93
+ onEndReached?: () => void;
94
+ }
95
+
96
+ export interface MovingShineProps {
97
+ duration?: number;
98
+ }
99
+
100
+ export interface WalletScreenProps {
101
+ onBack?: () => void;
102
+ }
103
+