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.
- package/LICENSE +22 -0
- package/README.md +407 -0
- package/app/.env.example +15 -0
- package/app/README.md +28 -0
- package/app/package.json +24 -0
- package/app/reanimated-mock.js +102 -0
- package/app/reanimated-mock.jsx +97 -0
- package/app/src/App.tsx +331 -0
- package/app/src/components/FounderBadge.tsx +26 -0
- package/app/src/components/OTPInput.tsx +149 -0
- package/app/src/components/PhoneInput.tsx +109 -0
- package/app/src/components/ZoAuth.tsx +320 -0
- package/app/src/components/ZoAvatar.tsx +87 -0
- package/app/src/components/ZoLanding.tsx +231 -0
- package/app/src/components/ZoOnboarding.tsx +524 -0
- package/app/src/components/ZoPassportCard.tsx +183 -0
- package/app/src/components/ZoProgressRing.tsx +57 -0
- package/app/src/components/index.ts +16 -0
- package/app/src/components/wallet/MovingShine.tsx +43 -0
- package/app/src/components/wallet/TransactionItem.tsx +84 -0
- package/app/src/components/wallet/TransactionList.tsx +65 -0
- package/app/src/components/wallet/WalletCard.tsx +152 -0
- package/app/src/components/wallet/WalletScreen.tsx +190 -0
- package/app/src/components/wallet/ZoToken.tsx +69 -0
- package/app/src/components/wallet/index.ts +8 -0
- package/app/src/components/wallet/styles/index.ts +4 -0
- package/app/src/components/wallet/styles/walletStyles.ts +210 -0
- package/app/src/sdk/ZoPassportSDK.ts +277 -0
- package/app/src/sdk/lib/api/auth.ts +223 -0
- package/app/src/sdk/lib/api/avatar.ts +155 -0
- package/app/src/sdk/lib/api/client.ts +135 -0
- package/app/src/sdk/lib/api/index.ts +8 -0
- package/app/src/sdk/lib/api/profile.ts +80 -0
- package/app/src/sdk/lib/api/wallet.ts +59 -0
- package/app/src/sdk/lib/types/auth.ts +78 -0
- package/app/src/sdk/lib/types/avatar.ts +22 -0
- package/app/src/sdk/lib/types/index.ts +8 -0
- package/app/src/sdk/lib/types/profile.ts +18 -0
- package/app/src/sdk/lib/types/wallet.ts +103 -0
- package/app/src/sdk/lib/types.ts +205 -0
- package/app/src/sdk/lib/utils/index.ts +6 -0
- package/app/src/sdk/lib/utils/phone.ts +71 -0
- package/app/src/sdk/lib/utils/storage.ts +116 -0
- package/app/src/sdk/lib/utils/wallet.ts +73 -0
- package/app/src/sdk/types.ts +205 -0
- package/app/src/styles.css +154 -0
- package/app/svg-mock.js +125 -0
- package/app/svg-mock.jsx +120 -0
- package/app/vite.config.ts +70 -0
- package/assets/ASSETS_MANIFEST.md +124 -0
- package/assets/bae.png +0 -0
- package/assets/bro.png +0 -0
- package/assets/cultural-stickers/Business.png +0 -0
- package/assets/cultural-stickers/Default (2).jpg +0 -0
- package/assets/cultural-stickers/Design.png +0 -0
- package/assets/cultural-stickers/FollowYourHeart.png +0 -0
- package/assets/cultural-stickers/Food.png +0 -0
- package/assets/cultural-stickers/Game.png +0 -0
- package/assets/cultural-stickers/Health&Fitness.png +0 -0
- package/assets/cultural-stickers/Home&Lifestyle.png +0 -0
- package/assets/cultural-stickers/Law.png +0 -0
- package/assets/cultural-stickers/Literature&Stories.png +0 -0
- package/assets/cultural-stickers/Music&Entertainment.png +0 -0
- package/assets/cultural-stickers/Nature&Wildlife.png +0 -0
- package/assets/cultural-stickers/Photography.png +0 -0
- package/assets/cultural-stickers/Science&Technology.png +0 -0
- package/assets/cultural-stickers/Spiritual.png +0 -0
- package/assets/cultural-stickers/Sport.png +0 -0
- package/assets/cultural-stickers/Stories&Journal.png +0 -0
- package/assets/cultural-stickers/Television&Cinema.png +0 -0
- package/assets/cultural-stickers/Travel&Adventure.png +0 -0
- package/assets/cultural-stickers/z.jpg (1).jpg +0 -0
- package/assets/figma-assets/landing-zo-logo.png +0 -0
- package/assets/images/rank1.jpeg +0 -0
- package/assets/index.ts +76 -0
- package/assets/lotties/loader.json +1216 -0
- package/assets/lotties/spinner.json +1 -0
- package/assets/videos/loading-screen-background.mp4 +0 -0
- package/assets/videos/opening-disks.mp4 +0 -0
- package/assets/wallet/constants.ts +38 -0
- package/assets/zo-coin.gif +0 -0
- package/assets/zo-fallback.png +0 -0
- package/dist/assets/index.d.mts +136 -0
- package/dist/assets/index.d.ts +136 -0
- package/dist/assets/index.js +133 -0
- package/dist/assets/index.js.map +1 -0
- package/dist/assets/index.mjs +100 -0
- package/dist/assets/index.mjs.map +1 -0
- package/dist/index.d.mts +789 -0
- package/dist/index.d.ts +789 -0
- package/dist/index.js +1118 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1060 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react-native.d.mts +537 -0
- package/dist/react-native.d.ts +537 -0
- package/dist/react-native.js +1617 -0
- package/dist/react-native.js.map +1 -0
- package/dist/react-native.mjs +1588 -0
- package/dist/react-native.mjs.map +1 -0
- package/dist/react.d.mts +824 -0
- package/dist/react.d.ts +824 -0
- package/dist/react.js +3856 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +3801 -0
- package/dist/react.mjs.map +1 -0
- package/package.json +112 -0
- package/scripts/init.js +196 -0
- package/scripts/postinstall.js +174 -0
- package/scripts/verify-build.js +121 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Zo World Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
# 🌍 Zo Passport SDK
|
|
2
|
+
|
|
3
|
+
> **One line reputation to rule the world**
|
|
4
|
+
>
|
|
5
|
+
> Phone OTP → Avatar → Passport → Wallet
|
|
6
|
+
|
|
7
|
+
Complete authentication, onboarding, and passport experience for Zo World applications.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 🚀 Quick Start - Get Running in 4 Commands
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# 1. Create project and install
|
|
15
|
+
mkdir my-zopassport && cd my-zopassport
|
|
16
|
+
npm install zopassport
|
|
17
|
+
|
|
18
|
+
# 2. Initialize the app
|
|
19
|
+
npx create-zopassport
|
|
20
|
+
|
|
21
|
+
# 3. Configure your client key
|
|
22
|
+
cp .env.example .env
|
|
23
|
+
# Edit .env: VITE_ZO_CLIENT_KEY=your-actual-key
|
|
24
|
+
|
|
25
|
+
# 4. Run the app
|
|
26
|
+
npm install && npm run dev
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**That's it!** 🎉 Your full Zo Passport app is running at `http://localhost:5173`
|
|
30
|
+
|
|
31
|
+
🔑 Get your client key at: **[https://zo.xyz/developers](https://zo.xyz/developers)**
|
|
32
|
+
|
|
33
|
+
📖 [**Full Installation Guide →**](./INSTALL.md)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 📦 What's Included
|
|
38
|
+
|
|
39
|
+
After `npm install zopassport`, you get:
|
|
40
|
+
|
|
41
|
+
✅ **Complete Demo App** - Full working phone → passport → wallet flow
|
|
42
|
+
✅ **All Dependencies** - React, Vite, TypeScript pre-configured
|
|
43
|
+
✅ **All Assets** - Images, videos, icons bundled
|
|
44
|
+
✅ **Environment Template** - Just add your client key
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 🎯 For Developers - Use as SDK
|
|
49
|
+
|
|
50
|
+
Want to integrate into your existing app? Use it as a library:
|
|
51
|
+
|
|
52
|
+
### 1. Initialize the SDK
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { ZoPassportSDK } from 'zopassport';
|
|
56
|
+
|
|
57
|
+
const sdk = new ZoPassportSDK({
|
|
58
|
+
clientKey: 'your-client-key',
|
|
59
|
+
autoRefresh: true,
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 2. React Integration
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { ZoPassportProvider, useZoPassport, ZoLanding, ZoOnboarding, ZoPassportCard } from 'zopassport/react';
|
|
67
|
+
|
|
68
|
+
function App() {
|
|
69
|
+
return (
|
|
70
|
+
<ZoPassportProvider clientKey="your-client-key">
|
|
71
|
+
<YourApp />
|
|
72
|
+
</ZoPassportProvider>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function YourApp() {
|
|
77
|
+
const { isAuthenticated, user, sendOTP, verifyOTP } = useZoPassport();
|
|
78
|
+
|
|
79
|
+
if (!isAuthenticated) {
|
|
80
|
+
return (
|
|
81
|
+
<ZoLanding
|
|
82
|
+
onAuthSuccess={(userId, user) => console.log('Logged in!', user)}
|
|
83
|
+
sendOTP={sendOTP}
|
|
84
|
+
verifyOTP={verifyOTP}
|
|
85
|
+
/>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<div>
|
|
91
|
+
<ZoPassportCard
|
|
92
|
+
profile={{
|
|
93
|
+
avatar: user.avatar?.image,
|
|
94
|
+
name: user.first_name,
|
|
95
|
+
isFounder: user.membership === 'founder',
|
|
96
|
+
}}
|
|
97
|
+
completion={{ done: 8, total: 10 }}
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Features
|
|
105
|
+
|
|
106
|
+
### ✅ Authentication
|
|
107
|
+
- Phone number + OTP authentication
|
|
108
|
+
- Automatic token refresh
|
|
109
|
+
- Session persistence
|
|
110
|
+
|
|
111
|
+
### ✅ Avatar Generation
|
|
112
|
+
- Choose body type (Bro/Bae)
|
|
113
|
+
- AI-powered avatar generation
|
|
114
|
+
- Polling status updates
|
|
115
|
+
|
|
116
|
+
### ✅ Passport Card
|
|
117
|
+
- Leather texture design
|
|
118
|
+
- Founder/Citizen variants
|
|
119
|
+
- Progress ring indicator
|
|
120
|
+
|
|
121
|
+
### ✅ Onboarding Flow
|
|
122
|
+
- Nickname input
|
|
123
|
+
- Location detection
|
|
124
|
+
- Avatar preview
|
|
125
|
+
|
|
126
|
+
## Components
|
|
127
|
+
|
|
128
|
+
### `<ZoLanding />`
|
|
129
|
+
Full-screen landing page with video background and auth modal.
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
<ZoLanding
|
|
133
|
+
onAuthSuccess={(userId, user) => {}}
|
|
134
|
+
sendOTP={async (code, phone) => sdk.auth.sendOTP(code, phone)}
|
|
135
|
+
verifyOTP={async (code, phone, otp) => sdk.auth.verifyOTP(code, phone, otp)}
|
|
136
|
+
videoUrl="/videos/background.mp4"
|
|
137
|
+
logoUrl="/zo-logo.png"
|
|
138
|
+
title="ZOHMMM!"
|
|
139
|
+
/>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### `<ZoOnboarding />`
|
|
143
|
+
Complete onboarding flow component.
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
<ZoOnboarding
|
|
147
|
+
onComplete={(data) => console.log(data)}
|
|
148
|
+
updateProfile={(updates) => sdk.updateProfile(updates)}
|
|
149
|
+
getProfile={() => sdk.getProfile()}
|
|
150
|
+
/>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### `<ZoPassportCard />`
|
|
154
|
+
Passport card display component.
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<ZoPassportCard
|
|
158
|
+
profile={{
|
|
159
|
+
avatar: 'https://...',
|
|
160
|
+
name: 'Samurai',
|
|
161
|
+
isFounder: true,
|
|
162
|
+
}}
|
|
163
|
+
completion={{ done: 8, total: 10 }}
|
|
164
|
+
/>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### `<ZoAuth />`
|
|
168
|
+
Standalone phone OTP authentication component.
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
<ZoAuth
|
|
172
|
+
onSuccess={(userId, user) => {}}
|
|
173
|
+
onClose={() => {}}
|
|
174
|
+
sendOTP={sendOTP}
|
|
175
|
+
verifyOTP={verifyOTP}
|
|
176
|
+
/>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### `<PhoneInput />` & `<OTPInput />`
|
|
180
|
+
Low-level input components for custom auth flows.
|
|
181
|
+
|
|
182
|
+
## Hooks
|
|
183
|
+
|
|
184
|
+
### `useZoPassport()`
|
|
185
|
+
Main hook for authentication state and operations.
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
const {
|
|
189
|
+
sdk,
|
|
190
|
+
user,
|
|
191
|
+
isAuthenticated,
|
|
192
|
+
isLoading,
|
|
193
|
+
sendOTP,
|
|
194
|
+
verifyOTP,
|
|
195
|
+
logout,
|
|
196
|
+
refreshProfile,
|
|
197
|
+
} = useZoPassport();
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### `useProfile()`
|
|
201
|
+
Profile operations and completion tracking.
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
const {
|
|
205
|
+
user,
|
|
206
|
+
completion,
|
|
207
|
+
isFounder,
|
|
208
|
+
updateProfile,
|
|
209
|
+
reload,
|
|
210
|
+
} = useProfile();
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### `useAvatar()`
|
|
214
|
+
Avatar generation operations.
|
|
215
|
+
|
|
216
|
+
```tsx
|
|
217
|
+
const {
|
|
218
|
+
avatarUrl,
|
|
219
|
+
isGenerating,
|
|
220
|
+
generateAvatar,
|
|
221
|
+
} = useAvatar();
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Assets Required
|
|
225
|
+
|
|
226
|
+
Include these assets in your `public/` folder:
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
public/
|
|
230
|
+
├── figma-assets/
|
|
231
|
+
│ └── landing-zo-logo.png # Zo logo
|
|
232
|
+
├── videos/
|
|
233
|
+
│ └── loading-screen-background.mp4 # Background video
|
|
234
|
+
├── bro.png # Bro avatar preview
|
|
235
|
+
├── bae.png # Bae avatar preview
|
|
236
|
+
├── Cultural Stickers/ # Culture icons
|
|
237
|
+
│ ├── Travel&Adventure.png
|
|
238
|
+
│ ├── Design.png
|
|
239
|
+
│ ├── Science&Technology.png
|
|
240
|
+
│ ├── Food.png
|
|
241
|
+
│ ├── Music&Entertainment.png
|
|
242
|
+
│ ├── Photography.png
|
|
243
|
+
│ ├── Health&Fitness.png
|
|
244
|
+
│ ├── Sport.png
|
|
245
|
+
│ ├── Literature&Stories.png
|
|
246
|
+
│ ├── Television&Cinema.png
|
|
247
|
+
│ ├── Spiritual.png
|
|
248
|
+
│ ├── Nature&Wildlife.png
|
|
249
|
+
│ ├── Business.png
|
|
250
|
+
│ ├── Law.png
|
|
251
|
+
│ ├── Home&Lifestyle.png
|
|
252
|
+
│ ├── Game.png
|
|
253
|
+
│ └── Stories&Journal.png
|
|
254
|
+
└── images/
|
|
255
|
+
└── rank1.jpeg # Fallback avatar
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## CDN Assets
|
|
259
|
+
|
|
260
|
+
The SDK uses these CDN URLs for passport backgrounds:
|
|
261
|
+
|
|
262
|
+
- **Founder Background**: `https://proxy.cdn.zo.xyz/gallery/media/images/a1659b07-94f0-4490-9b3c-3366715d9717_20250515053726.png`
|
|
263
|
+
- **Citizen Background**: `https://proxy.cdn.zo.xyz/gallery/media/images/bda9da5a-eefe-411d-8d90-667c80024463_20250515053805.png`
|
|
264
|
+
|
|
265
|
+
You can override these via props.
|
|
266
|
+
|
|
267
|
+
## Storage Adapters
|
|
268
|
+
|
|
269
|
+
### Web (Default)
|
|
270
|
+
Uses `localStorage` automatically.
|
|
271
|
+
|
|
272
|
+
### React Native
|
|
273
|
+
```tsx
|
|
274
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
275
|
+
import { ZoPassportSDK, AsyncStorageAdapter } from 'zopassport';
|
|
276
|
+
|
|
277
|
+
const sdk = new ZoPassportSDK({
|
|
278
|
+
clientKey: 'your-key',
|
|
279
|
+
storageAdapter: new AsyncStorageAdapter(AsyncStorage),
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Server-Side / Testing
|
|
284
|
+
```tsx
|
|
285
|
+
import { ZoPassportSDK, MemoryStorageAdapter } from 'zopassport';
|
|
286
|
+
|
|
287
|
+
const sdk = new ZoPassportSDK({
|
|
288
|
+
clientKey: 'your-key',
|
|
289
|
+
storageAdapter: new MemoryStorageAdapter(),
|
|
290
|
+
});
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## TypeScript
|
|
294
|
+
|
|
295
|
+
Full TypeScript support with exported types:
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
import type {
|
|
299
|
+
ZoUser,
|
|
300
|
+
ZoAuthResponse,
|
|
301
|
+
ZoProfileUpdatePayload,
|
|
302
|
+
ZoPassportConfig,
|
|
303
|
+
} from 'zopassport';
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## License
|
|
307
|
+
|
|
308
|
+
MIT © Zo World Team
|
|
309
|
+
|
|
310
|
+
## Wallet Integration
|
|
311
|
+
|
|
312
|
+
The SDK includes a built-in wallet system for managing Zo World assets.
|
|
313
|
+
|
|
314
|
+
### Framework-Agnostic Usage
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
// Get wallet balance
|
|
318
|
+
const balance = await sdk.wallet.getBalance();
|
|
319
|
+
console.log('Balance:', balance.total_amount);
|
|
320
|
+
|
|
321
|
+
// Get transaction history
|
|
322
|
+
const transactions = await sdk.wallet.getTransactions();
|
|
323
|
+
console.log('Transactions:', transactions);
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### React Components
|
|
327
|
+
|
|
328
|
+
The SDK provides ready-to-use wallet components:
|
|
329
|
+
|
|
330
|
+
```tsx
|
|
331
|
+
import { WalletScreen, WalletCard } from 'zopassport/react';
|
|
332
|
+
|
|
333
|
+
// Full wallet screen
|
|
334
|
+
<WalletScreen onBack={() => console.log('Back')} />
|
|
335
|
+
|
|
336
|
+
// Wallet card widget
|
|
337
|
+
<WalletCard
|
|
338
|
+
balance={100}
|
|
339
|
+
user={user}
|
|
340
|
+
isOpen={isOpen}
|
|
341
|
+
onToggle={() => setIsOpen(!isOpen)}
|
|
342
|
+
/>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### React Hooks
|
|
346
|
+
|
|
347
|
+
```tsx
|
|
348
|
+
import { useWalletBalance, useTransactions } from 'zopassport/react';
|
|
349
|
+
|
|
350
|
+
const MyWallet = () => {
|
|
351
|
+
const { balance, isLoading } = useWalletBalance(sdk.client);
|
|
352
|
+
const { transactions } = useTransactions(sdk.client);
|
|
353
|
+
|
|
354
|
+
return <div>Balance: {balance}</div>;
|
|
355
|
+
};
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Universal UI Support (Web + Mobile)
|
|
359
|
+
|
|
360
|
+
The SDK's UI components are built with React Native but can run on the web using `react-native-web`.
|
|
361
|
+
|
|
362
|
+
### Vite Configuration
|
|
363
|
+
|
|
364
|
+
To use the UI components in a Vite app, configure your `vite.config.ts`:
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
import { defineConfig } from 'vite';
|
|
368
|
+
import react from '@vitejs/plugin-react';
|
|
369
|
+
import path from 'path';
|
|
370
|
+
|
|
371
|
+
export default defineConfig({
|
|
372
|
+
plugins: [react()],
|
|
373
|
+
resolve: {
|
|
374
|
+
alias: {
|
|
375
|
+
'react-native': 'react-native-web',
|
|
376
|
+
// Mock reanimated if not using web-compatible version
|
|
377
|
+
'react-native-reanimated': path.resolve(__dirname, './reanimated-mock.js'),
|
|
378
|
+
},
|
|
379
|
+
extensions: ['.web.js', '.web.ts', '.web.tsx', '.js', '.ts', '.tsx'],
|
|
380
|
+
},
|
|
381
|
+
define: {
|
|
382
|
+
global: 'window',
|
|
383
|
+
},
|
|
384
|
+
});
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Next.js Configuration
|
|
388
|
+
|
|
389
|
+
For Next.js, use `next-transpile-modules`:
|
|
390
|
+
|
|
391
|
+
```javascript
|
|
392
|
+
const withTM = require('next-transpile-modules')([
|
|
393
|
+
'zopassport',
|
|
394
|
+
'react-native-web',
|
|
395
|
+
]);
|
|
396
|
+
|
|
397
|
+
module.exports = withTM({
|
|
398
|
+
webpack: (config) => {
|
|
399
|
+
config.resolve.alias = {
|
|
400
|
+
...(config.resolve.alias || {}),
|
|
401
|
+
'react-native$': 'react-native-web',
|
|
402
|
+
};
|
|
403
|
+
return config;
|
|
404
|
+
},
|
|
405
|
+
});
|
|
406
|
+
```
|
|
407
|
+
|
package/app/.env.example
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# ============================================
|
|
2
|
+
# ZO PASSPORT CONFIGURATION
|
|
3
|
+
# ============================================
|
|
4
|
+
# Get your client key from: https://zo.xyz/developers
|
|
5
|
+
#
|
|
6
|
+
# Copy this file to .env and add your client key:
|
|
7
|
+
# cp .env.example .env
|
|
8
|
+
#
|
|
9
|
+
# Then edit .env with your actual key
|
|
10
|
+
# ============================================
|
|
11
|
+
|
|
12
|
+
VITE_ZO_CLIENT_KEY=your-client-key-here
|
|
13
|
+
|
|
14
|
+
# Optional: Override the API base URL (default: https://api.io.zo.xyz)
|
|
15
|
+
# VITE_ZO_API_URL=https://api.io.zo.xyz
|
package/app/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Development Playground
|
|
2
|
+
|
|
3
|
+
This directory is a **local development environment** for testing Zo Passport SDK components.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
- Test React Native components in a web environment using mocks
|
|
8
|
+
- Preview UI components during development
|
|
9
|
+
- **NOT published to npm** (excluded from `files` in package.json)
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
cd app
|
|
15
|
+
npm install
|
|
16
|
+
npm run dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Mocks
|
|
20
|
+
|
|
21
|
+
- `reanimated-mock.js` - Mocks `react-native-reanimated` for web
|
|
22
|
+
- `svg-mock.js` - Mocks `react-native-svg` for web
|
|
23
|
+
|
|
24
|
+
## Note
|
|
25
|
+
|
|
26
|
+
The components here may be **out of sync** with the main `src/` directory.
|
|
27
|
+
Always develop in `src/` and use this playground for quick visual testing.
|
|
28
|
+
|
package/app/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "zo-passport-demo",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "tsc && vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"react": "^18.2.0",
|
|
13
|
+
"react-dom": "^18.2.0",
|
|
14
|
+
"zopassport": "file:.."
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/react": "^18.2.0",
|
|
18
|
+
"@types/react-dom": "^18.2.0",
|
|
19
|
+
"@vitejs/plugin-react": "^4.2.0",
|
|
20
|
+
"typescript": "^5.0.0",
|
|
21
|
+
"vite": "^5.0.0"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Mock for react-native-reanimated on web
|
|
2
|
+
// Provides basic functionality that works in browser
|
|
3
|
+
|
|
4
|
+
import { View, Text, Image, ScrollView, TouchableOpacity } from 'react-native-web';
|
|
5
|
+
|
|
6
|
+
// Create animated versions of components
|
|
7
|
+
const createAnimatedComponent = (Component) => {
|
|
8
|
+
const AnimatedComponent = ({ style, ...props }) => {
|
|
9
|
+
return <Component style={style} {...props} />;
|
|
10
|
+
};
|
|
11
|
+
AnimatedComponent.displayName = `Animated(${Component.displayName || Component.name || 'Component'})`;
|
|
12
|
+
return AnimatedComponent;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const Animated = {
|
|
16
|
+
View: createAnimatedComponent(View),
|
|
17
|
+
Text: createAnimatedComponent(Text),
|
|
18
|
+
Image: createAnimatedComponent(Image),
|
|
19
|
+
ScrollView: createAnimatedComponent(ScrollView),
|
|
20
|
+
createAnimatedComponent,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Hooks
|
|
24
|
+
export function useSharedValue(initialValue) {
|
|
25
|
+
return { value: initialValue };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function useAnimatedStyle(worklet) {
|
|
29
|
+
return worklet();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function useDerivedValue(worklet) {
|
|
33
|
+
return { value: worklet() };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function useAnimatedScrollHandler() {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Animation functions
|
|
41
|
+
export function withTiming(toValue, config, callback) {
|
|
42
|
+
return toValue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function withSpring(toValue, config, callback) {
|
|
46
|
+
return toValue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function withDelay(delay, animation) {
|
|
50
|
+
return animation;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function withRepeat(animation, numberOfReps, reverse, callback) {
|
|
54
|
+
return animation;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function withSequence(...animations) {
|
|
58
|
+
return animations[animations.length - 1];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function interpolate(value, inputRange, outputRange) {
|
|
62
|
+
return outputRange[0];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const Easing = {
|
|
66
|
+
linear: (t) => t,
|
|
67
|
+
ease: (t) => t,
|
|
68
|
+
quad: (t) => t,
|
|
69
|
+
cubic: (t) => t,
|
|
70
|
+
bezier: () => (t) => t,
|
|
71
|
+
in: (fn) => fn,
|
|
72
|
+
out: (fn) => fn,
|
|
73
|
+
inOut: (fn) => fn,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Layout animations
|
|
77
|
+
export const FadeIn = { duration: () => FadeIn };
|
|
78
|
+
export const FadeOut = { duration: () => FadeOut };
|
|
79
|
+
export const FadeInUp = { duration: () => FadeInUp };
|
|
80
|
+
export const FadeOutUp = { duration: () => FadeOutUp };
|
|
81
|
+
export const FadeInDown = { duration: () => FadeInDown };
|
|
82
|
+
export const SlideInRight = { duration: () => SlideInRight };
|
|
83
|
+
export const SlideOutLeft = { duration: () => SlideOutLeft };
|
|
84
|
+
|
|
85
|
+
// Functions
|
|
86
|
+
export function runOnJS(fn) {
|
|
87
|
+
return fn;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function runOnUI(fn) {
|
|
91
|
+
return fn;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function cancelAnimation() {}
|
|
95
|
+
|
|
96
|
+
export default Animated;
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Mock for react-native-reanimated on web
|
|
2
|
+
// Provides basic functionality that works in browser
|
|
3
|
+
|
|
4
|
+
import { View, Text, Image, ScrollView, TouchableOpacity } from 'react-native-web';
|
|
5
|
+
|
|
6
|
+
// Create animated versions of components
|
|
7
|
+
const createAnimatedComponent = (Component) => {
|
|
8
|
+
const AnimatedComponent = ({ style, ...props }) => {
|
|
9
|
+
return <Component style={style} {...props} />;
|
|
10
|
+
};
|
|
11
|
+
AnimatedComponent.displayName = `Animated(${Component.displayName || Component.name || 'Component'})`;
|
|
12
|
+
return AnimatedComponent;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const Animated = {
|
|
16
|
+
View: createAnimatedComponent(View),
|
|
17
|
+
Text: createAnimatedComponent(Text),
|
|
18
|
+
Image: createAnimatedComponent(Image),
|
|
19
|
+
ScrollView: createAnimatedComponent(ScrollView),
|
|
20
|
+
createAnimatedComponent,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Hooks
|
|
24
|
+
export function useSharedValue(initialValue) {
|
|
25
|
+
return { value: initialValue };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function useAnimatedStyle(worklet) {
|
|
29
|
+
return worklet();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function useDerivedValue(worklet) {
|
|
33
|
+
return { value: worklet() };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function useAnimatedScrollHandler() {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Animation functions
|
|
41
|
+
export function withTiming(toValue, config, callback) {
|
|
42
|
+
return toValue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function withSpring(toValue, config, callback) {
|
|
46
|
+
return toValue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function withDelay(delay, animation) {
|
|
50
|
+
return animation;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function withRepeat(animation, numberOfReps, reverse, callback) {
|
|
54
|
+
return animation;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function withSequence(...animations) {
|
|
58
|
+
return animations[animations.length - 1];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function interpolate(value, inputRange, outputRange) {
|
|
62
|
+
return outputRange[0];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const Easing = {
|
|
66
|
+
linear: (t) => t,
|
|
67
|
+
ease: (t) => t,
|
|
68
|
+
quad: (t) => t,
|
|
69
|
+
cubic: (t) => t,
|
|
70
|
+
bezier: () => (t) => t,
|
|
71
|
+
in: (fn) => fn,
|
|
72
|
+
out: (fn) => fn,
|
|
73
|
+
inOut: (fn) => fn,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Layout animations
|
|
77
|
+
export const FadeIn = { duration: () => FadeIn };
|
|
78
|
+
export const FadeOut = { duration: () => FadeOut };
|
|
79
|
+
export const FadeInUp = { duration: () => FadeInUp };
|
|
80
|
+
export const FadeOutUp = { duration: () => FadeOutUp };
|
|
81
|
+
export const FadeInDown = { duration: () => FadeInDown };
|
|
82
|
+
export const SlideInRight = { duration: () => SlideInRight };
|
|
83
|
+
export const SlideOutLeft = { duration: () => SlideOutLeft };
|
|
84
|
+
|
|
85
|
+
// Functions
|
|
86
|
+
export function runOnJS(fn) {
|
|
87
|
+
return fn;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function runOnUI(fn) {
|
|
91
|
+
return fn;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function cancelAnimation() {}
|
|
95
|
+
|
|
96
|
+
export default Animated;
|
|
97
|
+
|