@explorins/pers-sdk-react-native 2.3.7 → 2.3.8
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 +21 -0
- package/README.md +1266 -1244
- package/dist/__tests__/PersSDKProvider.test.js +33 -0
- package/dist/hooks/useBusiness.d.ts +2 -2
- package/dist/hooks/useBusiness.d.ts.map +1 -1
- package/dist/hooks/useBusiness.js +2 -2
- package/dist/hooks/useIPFSUrl.d.ts +3 -3
- package/dist/hooks/useIPFSUrl.d.ts.map +1 -1
- package/dist/hooks/useIPFSUrl.js +7 -7
- package/dist/hooks/useWeb3.js +4 -4
- package/dist/index.js +2400 -487
- package/dist/index.js.map +1 -1
- package/dist/providers/PersSDKProvider.d.ts +4 -0
- package/dist/providers/PersSDKProvider.d.ts.map +1 -1
- package/dist/providers/PersSDKProvider.js +14 -0
- package/dist/providers/react-native-http-client.d.ts +2 -0
- package/dist/providers/react-native-http-client.d.ts.map +1 -1
- package/dist/providers/react-native-http-client.js +5 -2
- package/dist/storage/rn-secure-storage.d.ts.map +1 -1
- package/dist/storage/rn-secure-storage.js +21 -8
- package/package.json +3 -3
- package/src/__tests__/PersSDKProvider.test.tsx +484 -420
- package/src/__tests__/setup.ts +40 -40
- package/src/hooks/index.ts +60 -60
- package/src/hooks/useAnalytics.ts +327 -327
- package/src/hooks/useAuth.ts +265 -265
- package/src/hooks/useBookings.ts +191 -191
- package/src/hooks/useBusiness.ts +251 -251
- package/src/hooks/useCampaigns.ts +500 -500
- package/src/hooks/useDonations.ts +66 -66
- package/src/hooks/useEvents.ts +372 -372
- package/src/hooks/useFiles.ts +155 -155
- package/src/hooks/useIPFSUrl.ts +192 -192
- package/src/hooks/usePurchases.ts +65 -65
- package/src/hooks/useRedemptions.ts +467 -467
- package/src/hooks/useTenants.ts +72 -72
- package/src/hooks/useTokenBalances.ts +385 -385
- package/src/hooks/useTokens.ts +313 -313
- package/src/hooks/useTransactionSigner.ts +611 -611
- package/src/hooks/useTransactions.ts +299 -299
- package/src/hooks/useTriggerSources.ts +301 -301
- package/src/hooks/useUserStatus.ts +61 -61
- package/src/hooks/useUsers.ts +167 -167
- package/src/hooks/useWeb3.ts +355 -355
- package/src/index.ts +777 -777
- package/src/polyfills/index.ts +160 -160
- package/src/polyfills/web3-polyfills.ts +97 -97
- package/src/providers/PersSDKProvider.tsx +393 -374
- package/src/providers/react-native-auth-provider.ts +110 -110
- package/src/providers/react-native-http-client.ts +150 -145
- package/src/providers/rn-dpop-provider.ts +190 -190
- package/src/storage/async-storage-token-storage.ts +185 -185
- package/src/storage/rn-secure-storage.ts +182 -170
- package/src/types/react-native-globals.d.ts +45 -45
- package/src/utils/index.ts +8 -8
- package/src/utils/platform-detection.ts +86 -86
- package/dist/index-CzLxqePZ.js +0 -7717
- package/dist/index-CzLxqePZ.js.map +0 -1
package/src/index.ts
CHANGED
|
@@ -1,778 +1,778 @@
|
|
|
1
|
-
// Polyfills - must be imported first for Hermes engine compatibility
|
|
2
|
-
import 'react-native-url-polyfill/auto';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @fileoverview PERS SDK for React Native - Tourism Loyalty System
|
|
6
|
-
*
|
|
7
|
-
* A comprehensive React Native SDK for integrating with the PERS (Phygital Experience Rewards System)
|
|
8
|
-
* platform. Provides complete functionality for tourism loyalty applications including user management,
|
|
9
|
-
* token operations, business integrations, campaign management, and blockchain transaction signing.
|
|
10
|
-
*
|
|
11
|
-
* **Key Features:**
|
|
12
|
-
* - Secure authentication with React Native Keychain integration
|
|
13
|
-
* - Token management (earn, redeem, transfer, balance checking)
|
|
14
|
-
* - Business and campaign management
|
|
15
|
-
* - Blockchain transaction signing with WebAuthn
|
|
16
|
-
* - React Native optimized with automatic polyfills
|
|
17
|
-
* - Type-safe interfaces with comprehensive TypeScript support
|
|
18
|
-
* - Analytics and reporting capabilities
|
|
19
|
-
* - Donation and charitable giving features
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* **Quick Start:**
|
|
23
|
-
* ```typescript
|
|
24
|
-
* import { PersSDKProvider, usePersSDK, useTransactionSigner } from '@explorins/pers-sdk-react-native';
|
|
25
|
-
*
|
|
26
|
-
* // 1. Wrap your app with the provider
|
|
27
|
-
* function App() {
|
|
28
|
-
* return (
|
|
29
|
-
* <PersSDKProvider config={{ apiUrl: 'https://api.pers.ninja' }}>
|
|
30
|
-
* <YourApp />
|
|
31
|
-
* </PersSDKProvider>
|
|
32
|
-
* );
|
|
33
|
-
* }
|
|
34
|
-
*
|
|
35
|
-
* // 2. Use hooks in your components
|
|
36
|
-
* function RewardScreen() {
|
|
37
|
-
* const { user, isAuthenticated, earnTokens } = usePersSDK();
|
|
38
|
-
* const { signAndSubmitTransactionWithJWT } = useTransactionSigner();
|
|
39
|
-
*
|
|
40
|
-
* // Your reward logic here...
|
|
41
|
-
* }
|
|
42
|
-
* ```
|
|
43
|
-
*
|
|
44
|
-
* @version 1.5.19
|
|
45
|
-
* @author eXplorins
|
|
46
|
-
* @license MIT
|
|
47
|
-
*/
|
|
48
|
-
|
|
49
|
-
// Initialize React Native polyfills automatically
|
|
50
|
-
import './polyfills';
|
|
51
|
-
|
|
52
|
-
// ==============================================================================
|
|
53
|
-
// AUTHENTICATION PROVIDERS
|
|
54
|
-
// ==============================================================================
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* React Native-specific authentication provider with secure keychain integration
|
|
58
|
-
*
|
|
59
|
-
* Provides secure token storage using React Native Keychain, biometric authentication,
|
|
60
|
-
* and automatic token refresh capabilities.
|
|
61
|
-
*
|
|
62
|
-
* @see {@link createReactNativeAuthProvider} - Factory function for auth provider
|
|
63
|
-
* @see {@link ReactNativeAuthConfig} - Configuration interface
|
|
64
|
-
*/
|
|
65
|
-
export {
|
|
66
|
-
createReactNativeAuthProvider,
|
|
67
|
-
type ReactNativeAuthConfig
|
|
68
|
-
} from './providers/react-native-auth-provider';
|
|
69
|
-
|
|
70
|
-
// ==============================================================================
|
|
71
|
-
// SECURE STORAGE
|
|
72
|
-
// ==============================================================================
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Secure Token Storage with Keychain Integration
|
|
76
|
-
*
|
|
77
|
-
* Implements the TokenStorage interface using React Native Keychain for sensitive data
|
|
78
|
-
* (Private Keys, Access Tokens) and AsyncStorage for configuration/public data.
|
|
79
|
-
*
|
|
80
|
-
* - Encryption: Hardware-backed keystore
|
|
81
|
-
* - Persistence: Survives app uninstall (on iOS usually) or clears on uninstall (Android) if configured
|
|
82
|
-
*
|
|
83
|
-
* @see {@link ReactNativeSecureStorage} - The implementation class
|
|
84
|
-
*/
|
|
85
|
-
export { ReactNativeSecureStorage } from './storage/rn-secure-storage';
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Secure token storage using React Native AsyncStorage
|
|
89
|
-
*
|
|
90
|
-
* Provides encrypted token storage with automatic cleanup and secure key management.
|
|
91
|
-
* Integrates with React Native Keychain for enhanced security on supported devices.
|
|
92
|
-
*
|
|
93
|
-
* @see {@link AsyncStorageTokenStorage} - Secure storage implementation
|
|
94
|
-
* @deprecated Use ReactNativeSecureStorage for better security (Keychain integration)
|
|
95
|
-
*/
|
|
96
|
-
export {
|
|
97
|
-
AsyncStorageTokenStorage,
|
|
98
|
-
} from './storage/async-storage-token-storage';
|
|
99
|
-
|
|
100
|
-
// ==============================================================================
|
|
101
|
-
// DPoP PROVIDER
|
|
102
|
-
// ==============================================================================
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* React Native DPoP Crypto Provider
|
|
106
|
-
* implements DPoPCryptoProvider using react-native-quick-crypto
|
|
107
|
-
*/
|
|
108
|
-
export { ReactNativeDPoPProvider } from './providers/rn-dpop-provider';
|
|
109
|
-
|
|
110
|
-
// ==============================================================================
|
|
111
|
-
// CORE PROVIDER & CONTEXT
|
|
112
|
-
// ==============================================================================
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Main PERS SDK provider and context for React Native applications
|
|
116
|
-
*
|
|
117
|
-
* The PersSDKProvider should wrap your entire app to provide PERS functionality
|
|
118
|
-
* throughout your component tree. Use usePersSDK hook to access SDK features.
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* ```typescript
|
|
122
|
-
* import { PersSDKProvider, usePersSDK } from '@explorins/pers-sdk-react-native';
|
|
123
|
-
*
|
|
124
|
-
* function App() {
|
|
125
|
-
* return (
|
|
126
|
-
* <PersSDKProvider config={{
|
|
127
|
-
* apiUrl: 'https://api.pers.ninja',
|
|
128
|
-
* tenantId: 'your-tenant-id'
|
|
129
|
-
* }}>
|
|
130
|
-
* <NavigationContainer>
|
|
131
|
-
* <YourAppContent />
|
|
132
|
-
* </NavigationContainer>
|
|
133
|
-
* </PersSDKProvider>
|
|
134
|
-
* );
|
|
135
|
-
* }
|
|
136
|
-
*
|
|
137
|
-
* function YourComponent() {
|
|
138
|
-
* const { user, isAuthenticated, earnTokens } = usePersSDK();
|
|
139
|
-
* // Use PERS functionality here...
|
|
140
|
-
* }
|
|
141
|
-
* ```
|
|
142
|
-
*
|
|
143
|
-
* @see {@link PersSDKProvider} - Main provider component
|
|
144
|
-
* @see {@link usePersSDK} - Hook to access SDK functionality
|
|
145
|
-
* @see {@link PersConfig} - Provider configuration interface
|
|
146
|
-
* @see {@link PersSDKContext} - Context type definition
|
|
147
|
-
*/
|
|
148
|
-
export {
|
|
149
|
-
PersSDKProvider,
|
|
150
|
-
usePersSDK,
|
|
151
|
-
type PersConfig,
|
|
152
|
-
type PersSDKContext
|
|
153
|
-
} from './providers/PersSDKProvider';
|
|
154
|
-
|
|
155
|
-
// ==============================================================================
|
|
156
|
-
// REACT HOOKS (Primary Interface)
|
|
157
|
-
// ==============================================================================
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Comprehensive React hooks for PERS platform integration
|
|
161
|
-
*
|
|
162
|
-
* These hooks provide the primary interface for interacting with the PERS platform
|
|
163
|
-
* in React Native applications. Each hook is optimized for specific functionality
|
|
164
|
-
* and includes automatic error handling, loading states, and real-time updates.
|
|
165
|
-
*
|
|
166
|
-
* **Authentication & User Management:**
|
|
167
|
-
* - `useAuth` - User authentication, login, logout, registration
|
|
168
|
-
* - `useUsers` - User profile management and data operations
|
|
169
|
-
* - `useUserStatus` - Real-time user status and activity monitoring
|
|
170
|
-
*
|
|
171
|
-
* **Token & Financial Operations:**
|
|
172
|
-
* - `useTokens` - Token balance, earning, and management
|
|
173
|
-
* - `useTransactions` - Transaction history and monitoring
|
|
174
|
-
* - `useTransactionSigner` - **⭐ Blockchain transaction signing**
|
|
175
|
-
* - `usePurchases` - Purchase history and payment processing
|
|
176
|
-
* - `useDonations` - Charitable giving and donation management
|
|
177
|
-
*
|
|
178
|
-
* **Business & Campaign Management:**
|
|
179
|
-
* - `useBusiness` - Business profile and operations
|
|
180
|
-
* - `useBookings` - Booking management with status validation
|
|
181
|
-
* - `useCampaigns` - Marketing campaigns and promotions
|
|
182
|
-
* - `useRedemptions` - Reward redemption and fulfillment
|
|
183
|
-
*
|
|
184
|
-
* **Platform & Analytics:**
|
|
185
|
-
* - `useTenants` - Multi-tenant configuration and management
|
|
186
|
-
* - `useAnalytics` - Usage analytics and reporting
|
|
187
|
-
* - `useFiles` - File upload and management
|
|
188
|
-
* - `useWeb3` - Blockchain integration and wallet operations
|
|
189
|
-
* - `useEvents` - ** SDK event subscriptions for notifications**
|
|
190
|
-
*
|
|
191
|
-
* @example
|
|
192
|
-
* **Token Operations:**
|
|
193
|
-
* ```typescript
|
|
194
|
-
* import { useTokens, useTransactionSigner } from '@explorins/pers-sdk-react-native';
|
|
195
|
-
*
|
|
196
|
-
* function TokenScreen() {
|
|
197
|
-
* const { balance, earnTokens, redeemTokens } = useTokens();
|
|
198
|
-
* const { signAndSubmitTransactionWithJWT } = useTransactionSigner();
|
|
199
|
-
*
|
|
200
|
-
* const handleEarn = async (amount: number) => {
|
|
201
|
-
* const result = await earnTokens({ amount, source: 'reward' });
|
|
202
|
-
* console.log('Earned tokens:', result);
|
|
203
|
-
* };
|
|
204
|
-
*
|
|
205
|
-
* const handleRedeem = async (amount: number) => {
|
|
206
|
-
* const redemption = await redeemTokens({ amount });
|
|
207
|
-
* const txResult = await signAndSubmitTransactionWithJWT(redemption.jwtToken);
|
|
208
|
-
* console.log('Redemption completed:', txResult.transactionHash);
|
|
209
|
-
* };
|
|
210
|
-
* }
|
|
211
|
-
* ```
|
|
212
|
-
*
|
|
213
|
-
* @example
|
|
214
|
-
* **Campaign Integration:**
|
|
215
|
-
* ```typescript
|
|
216
|
-
* import { useCampaigns, useAuth } from '@explorins/pers-sdk-react-native';
|
|
217
|
-
*
|
|
218
|
-
* function CampaignScreen() {
|
|
219
|
-
* const { activeCampaigns, participateInCampaign } = useCampaigns();
|
|
220
|
-
* const { user } = useAuth();
|
|
221
|
-
*
|
|
222
|
-
* const handleParticipate = async (campaignId: string) => {
|
|
223
|
-
* const result = await participateInCampaign(campaignId, {
|
|
224
|
-
* userId: user?.id,
|
|
225
|
-
* participationData: { source: 'mobile_app' }
|
|
226
|
-
* });
|
|
227
|
-
* };
|
|
228
|
-
* }
|
|
229
|
-
* ```
|
|
230
|
-
*
|
|
231
|
-
* @example
|
|
232
|
-
* **Event Subscriptions:**
|
|
233
|
-
* ```typescript
|
|
234
|
-
* import { useEvents, useEffect } from '@explorins/pers-sdk-react-native';
|
|
235
|
-
*
|
|
236
|
-
* function NotificationHandler() {
|
|
237
|
-
* const { subscribe, isAvailable } = useEvents();
|
|
238
|
-
*
|
|
239
|
-
* useEffect(() => {
|
|
240
|
-
* if (!isAvailable) return;
|
|
241
|
-
*
|
|
242
|
-
* const unsubscribe = subscribe((event) => {
|
|
243
|
-
* showNotification(event.userMessage, event.level);
|
|
244
|
-
* });
|
|
245
|
-
*
|
|
246
|
-
* return () => unsubscribe();
|
|
247
|
-
* }, [subscribe, isAvailable]);
|
|
248
|
-
* }
|
|
249
|
-
* ```
|
|
250
|
-
*/
|
|
251
|
-
export {
|
|
252
|
-
useAuth,
|
|
253
|
-
useTokens,
|
|
254
|
-
useTokenBalances,
|
|
255
|
-
useTransactions,
|
|
256
|
-
useTransactionSigner,
|
|
257
|
-
SigningStatus,
|
|
258
|
-
useBusiness,
|
|
259
|
-
useBookings,
|
|
260
|
-
useCampaigns,
|
|
261
|
-
useRedemptions,
|
|
262
|
-
useWeb3,
|
|
263
|
-
usePurchases,
|
|
264
|
-
useTenants,
|
|
265
|
-
useUsers,
|
|
266
|
-
useUserStatus,
|
|
267
|
-
useFiles,
|
|
268
|
-
useAnalytics,
|
|
269
|
-
useDonations,
|
|
270
|
-
useEvents,
|
|
271
|
-
useTriggerSources,
|
|
272
|
-
// IPFS hooks - for resolving ipfs:// URLs and loading metadata
|
|
273
|
-
useResolvedUrl,
|
|
274
|
-
useMetadata,
|
|
275
|
-
useIPFSUrl, // alias for useResolvedUrl
|
|
276
|
-
useTransactionMetadata // convenience for transaction items
|
|
277
|
-
} from './hooks';
|
|
278
|
-
|
|
279
|
-
// Re-export signing status types for convenience
|
|
280
|
-
export type {
|
|
281
|
-
TransactionSignerHook,
|
|
282
|
-
OnStatusUpdateFn,
|
|
283
|
-
StatusUpdateData,
|
|
284
|
-
SigningStatusType,
|
|
285
|
-
TransactionSigningResult,
|
|
286
|
-
SubmissionResult,
|
|
287
|
-
AuthenticatedUser
|
|
288
|
-
} from './hooks';
|
|
289
|
-
|
|
290
|
-
// Re-export event types for convenience
|
|
291
|
-
export type { EventsHook, PersEvent, EventHandler, EventFilter, Unsubscribe } from './hooks';
|
|
292
|
-
|
|
293
|
-
// Re-export token balance types for convenience
|
|
294
|
-
export type { TokenBalanceWithToken, UseTokenBalancesOptions, UseTokenBalancesResult } from './hooks';
|
|
295
|
-
|
|
296
|
-
// Re-export campaign types for convenience
|
|
297
|
-
export type { CampaignClaimFilters, CampaignFilterOptions, CampaignHook, GetCampaignsOptions } from './hooks';
|
|
298
|
-
|
|
299
|
-
// Re-export redemption types for convenience
|
|
300
|
-
export type { RedemptionRedeemFilters, RedemptionFilterOptions, RedemptionHook, GetRedemptionsOptions } from './hooks';
|
|
301
|
-
|
|
302
|
-
// Re-export business types for convenience
|
|
303
|
-
export type { BusinessFilterOptions, BusinessHook } from './hooks';
|
|
304
|
-
|
|
305
|
-
// Re-export transaction types for convenience
|
|
306
|
-
export type { TransactionQueryOptions, TransactionHook } from './hooks';
|
|
307
|
-
|
|
308
|
-
// Re-export trigger source types for convenience
|
|
309
|
-
export type { TriggerSourceQueryOptions, TriggerSourceHook } from './hooks';
|
|
310
|
-
|
|
311
|
-
// Re-export analytics types for convenience
|
|
312
|
-
export type { AnalyticsHook } from './hooks';
|
|
313
|
-
|
|
314
|
-
// Re-export booking types for convenience
|
|
315
|
-
export type { BookingHook, BookingQueryOptions, BookingValidationOptions } from './hooks';
|
|
316
|
-
|
|
317
|
-
// ==============================================================================
|
|
318
|
-
// PLATFORM ADAPTERS
|
|
319
|
-
// ==============================================================================
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* React Native-optimized HTTP client with automatic request/response handling
|
|
323
|
-
*
|
|
324
|
-
* Provides platform-specific networking with proper error handling, timeout management,
|
|
325
|
-
* and React Native compatibility. Automatically handles headers, authentication tokens,
|
|
326
|
-
* and response parsing.
|
|
327
|
-
*
|
|
328
|
-
* @see {@link ReactNativeHttpClient} - The HTTP client implementation
|
|
329
|
-
* @see {@link HttpClient} - The HTTP client interface
|
|
330
|
-
* @see {@link RequestOptions} - Request configuration options
|
|
331
|
-
*/
|
|
332
|
-
export {
|
|
333
|
-
ReactNativeHttpClient,
|
|
334
|
-
type HttpClient,
|
|
335
|
-
type RequestOptions
|
|
336
|
-
} from './providers/react-native-http-client';
|
|
337
|
-
|
|
338
|
-
// ==============================================================================
|
|
339
|
-
// POLYFILLS & COMPATIBILITY
|
|
340
|
-
// ==============================================================================
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* React Native polyfill utilities for web compatibility
|
|
344
|
-
*
|
|
345
|
-
* Automatically initializes required polyfills for crypto, URL, and other web APIs
|
|
346
|
-
* that may not be available in React Native environments. These are typically
|
|
347
|
-
* loaded automatically, but manual initialization is available for advanced use cases.
|
|
348
|
-
*
|
|
349
|
-
* @see {@link initializeReactNativePolyfills} - Manual polyfill initialization
|
|
350
|
-
*/
|
|
351
|
-
export {
|
|
352
|
-
initializeReactNativePolyfills
|
|
353
|
-
} from './polyfills';
|
|
354
|
-
|
|
355
|
-
// ==============================================================================
|
|
356
|
-
// TYPE DEFINITIONS & SHARED UTILITIES
|
|
357
|
-
// ==============================================================================
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Re-export all types and utilities from the shared PERS library
|
|
361
|
-
*
|
|
362
|
-
* This includes all core types, DTOs, enums, and utility functions used across
|
|
363
|
-
* the PERS platform. These types ensure consistency between different SDK versions
|
|
364
|
-
* and platform implementations.
|
|
365
|
-
*
|
|
366
|
-
* **Included Types:**
|
|
367
|
-
* - User and authentication types (UserDTO, AuthenticationResult, etc.)
|
|
368
|
-
* - Token and transaction types (TokenDTO, TransactionDTO, etc.)
|
|
369
|
-
* - Business and campaign types (BusinessDTO, CampaignDTO, etc.)
|
|
370
|
-
* - API request/response types for all endpoints
|
|
371
|
-
* - Error types and status enums
|
|
372
|
-
* - Utility functions for pagination, token display, etc.
|
|
373
|
-
*
|
|
374
|
-
* @see {@link https://github.com/eXplorins/pers-shared} - Shared library documentation
|
|
375
|
-
*/
|
|
376
|
-
export * from '@explorins/pers-sdk';
|
|
377
|
-
|
|
378
|
-
/**
|
|
379
|
-
* Token utilities re-exported from token module
|
|
380
|
-
*
|
|
381
|
-
* @see {@link getMetadataFromTokenUnitResponse} - Get full metadata object from token unit
|
|
382
|
-
*/
|
|
383
|
-
export { getMetadataFromTokenUnitResponse } from '@explorins/pers-sdk/token';
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Shared SDK utilities re-exported from base SDK
|
|
387
|
-
*
|
|
388
|
-
* Includes helper functions for:
|
|
389
|
-
* - Pagination utilities (buildPaginationParams, extractData, etc.)
|
|
390
|
-
*/
|
|
391
|
-
export {
|
|
392
|
-
// Pagination utilities
|
|
393
|
-
buildPaginationParams,
|
|
394
|
-
extractData,
|
|
395
|
-
extractPagination,
|
|
396
|
-
isPaginatedResponse,
|
|
397
|
-
normalizeToPaginated,
|
|
398
|
-
fetchAllPages,
|
|
399
|
-
type PaginationOptions,
|
|
400
|
-
type PaginationWithFilters,
|
|
401
|
-
type ListResponse
|
|
402
|
-
} from '@explorins/pers-sdk';
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* Re-export Web3 and blockchain-related types from base SDK
|
|
406
|
-
*
|
|
407
|
-
* Provides TypeScript definitions for Web3 operations, token management,
|
|
408
|
-
* and blockchain interactions. These types are used by the transaction
|
|
409
|
-
* signing hooks and Web3 integration features.
|
|
410
|
-
*
|
|
411
|
-
* @see {@link TokenBalanceRequest} - Request structure for token balance queries
|
|
412
|
-
* @see {@link TokenBalance} - Token balance response data
|
|
413
|
-
* @see {@link TokenMetadata} - Token metadata and details
|
|
414
|
-
* @see {@link TokenCollection} - Collection of tokens for batch operations
|
|
415
|
-
*/
|
|
416
|
-
export type {
|
|
417
|
-
TokenBalanceRequest,
|
|
418
|
-
TokenBalance,
|
|
419
|
-
TokenMetadata,
|
|
420
|
-
TokenCollection,
|
|
421
|
-
TokenCollectionRequest
|
|
422
|
-
} from '@explorins/pers-sdk/web3';
|
|
423
|
-
|
|
424
|
-
// ==============================================================================
|
|
425
|
-
// TRANSACTION REQUEST FACTORY FUNCTIONS
|
|
426
|
-
// ==============================================================================
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* Transaction Request Factory Functions
|
|
430
|
-
*
|
|
431
|
-
* Factory functions for creating properly structured transaction DTOs.
|
|
432
|
-
* Prioritizes accountId/accountType over raw addresses for security and consistency.
|
|
433
|
-
*
|
|
434
|
-
* @example
|
|
435
|
-
* ```typescript
|
|
436
|
-
* import {
|
|
437
|
-
* buildMintRequest,
|
|
438
|
-
* buildTransferRequest,
|
|
439
|
-
* buildBurnRequest,
|
|
440
|
-
* useTransactions,
|
|
441
|
-
* AccountOwnerType
|
|
442
|
-
* } from '@explorins/pers-sdk-react-native';
|
|
443
|
-
*
|
|
444
|
-
* function TokenOperations() {
|
|
445
|
-
* const { createTransaction } = useTransactions();
|
|
446
|
-
*
|
|
447
|
-
* const handleMint = async () => {
|
|
448
|
-
* const request = buildMintRequest({
|
|
449
|
-
* amount: 100,
|
|
450
|
-
* contractAddress: '0x...',
|
|
451
|
-
* chainId: 137,
|
|
452
|
-
* recipientAccountType: AccountOwnerType.USER,
|
|
453
|
-
* recipientAccountId: 'user-123'
|
|
454
|
-
* });
|
|
455
|
-
* await createTransaction(request);
|
|
456
|
-
* };
|
|
457
|
-
* }
|
|
458
|
-
* ```
|
|
459
|
-
*
|
|
460
|
-
* @see {@link buildMintRequest} - Create mint transaction requests
|
|
461
|
-
* @see {@link buildBurnRequest} - Create burn transaction requests
|
|
462
|
-
* @see {@link buildTransferRequest} - Create transfer transaction requests
|
|
463
|
-
* @see {@link buildPOSTransferRequest} - Create POS transfer requests (business submits on behalf of user)
|
|
464
|
-
* @see {@link buildPOSBurnRequest} - Create POS burn requests (business submits burn on behalf of user)
|
|
465
|
-
* @see {@link buildSubmissionRequest} - Create submission requests from QR/signature data
|
|
466
|
-
*/
|
|
467
|
-
export {
|
|
468
|
-
buildMintRequest,
|
|
469
|
-
buildBurnRequest,
|
|
470
|
-
buildTransferRequest,
|
|
471
|
-
buildPOSTransferRequest,
|
|
472
|
-
buildPOSBurnRequest,
|
|
473
|
-
buildSubmissionRequest,
|
|
474
|
-
ClientTransactionType,
|
|
475
|
-
extractDeadlineFromSigningData,
|
|
476
|
-
buildPendingTransactionData,
|
|
477
|
-
needsSubmission,
|
|
478
|
-
needsExternalSigning,
|
|
479
|
-
getSigningUrl
|
|
480
|
-
} from '@explorins/pers-sdk/transaction';
|
|
481
|
-
|
|
482
|
-
export type { POSAuthorizationOptions, PendingTransactionParams } from '@explorins/pers-sdk/transaction';
|
|
483
|
-
|
|
484
|
-
// ==============================================================================
|
|
485
|
-
// ERROR CLASSES (for instanceof checks)
|
|
486
|
-
// ==============================================================================
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
* Structured error handling for PERS SDK
|
|
490
|
-
*
|
|
491
|
-
* The SDK provides comprehensive error classes and utilities for consistent error handling
|
|
492
|
-
* across all operations. Errors follow the StructuredError pattern from @explorins/pers-shared.
|
|
493
|
-
*
|
|
494
|
-
* **Error Classes:**
|
|
495
|
-
* - `PersApiError` - API errors with structured backend details
|
|
496
|
-
* - `AuthenticationError` - Authentication/authorization failures (401)
|
|
497
|
-
*
|
|
498
|
-
* **Error Utilities:**
|
|
499
|
-
* - `ErrorUtils.getMessage(error)` - Extract user-friendly message
|
|
500
|
-
* - `ErrorUtils.getStatus(error)` - Get HTTP status code
|
|
501
|
-
* - `ErrorUtils.isRetryable(error)` - Check if operation should be retried
|
|
502
|
-
* - `ErrorUtils.isTokenExpiredError(error)` - Detect token expiration
|
|
503
|
-
*
|
|
504
|
-
* @example
|
|
505
|
-
* **Basic Error Handling:**
|
|
506
|
-
* ```typescript
|
|
507
|
-
* import { PersApiError, ErrorUtils } from '@explorins/pers-sdk-react-native';
|
|
508
|
-
*
|
|
509
|
-
* try {
|
|
510
|
-
* await sdk.campaigns.claimCampaign({ campaignId });
|
|
511
|
-
* } catch (error) {
|
|
512
|
-
* if (error instanceof PersApiError) {
|
|
513
|
-
* // Structured error with backend details
|
|
514
|
-
* console.log('Error code:', error.code); // 'CAMPAIGN_BUSINESS_REQUIRED'
|
|
515
|
-
* console.log('Status:', error.status); // 400
|
|
516
|
-
* console.log('Message:', error.message); // Backend error message
|
|
517
|
-
* console.log('User message:', error.userMessage); // User-friendly message
|
|
518
|
-
* console.log('Retryable:', error.retryable); // false
|
|
519
|
-
* } else {
|
|
520
|
-
* // Generic error fallback
|
|
521
|
-
* const message = ErrorUtils.getMessage(error);
|
|
522
|
-
* console.error('Operation failed:', message);
|
|
523
|
-
* }
|
|
524
|
-
* }
|
|
525
|
-
* ```
|
|
526
|
-
*
|
|
527
|
-
* @example
|
|
528
|
-
* **Error Utilities:**
|
|
529
|
-
* ```typescript
|
|
530
|
-
* import { ErrorUtils } from '@explorins/pers-sdk-react-native';
|
|
531
|
-
*
|
|
532
|
-
* try {
|
|
533
|
-
* await someOperation();
|
|
534
|
-
* } catch (error) {
|
|
535
|
-
* const status = ErrorUtils.getStatus(error); // Extract status code
|
|
536
|
-
* const message = ErrorUtils.getMessage(error); // Extract message
|
|
537
|
-
* const retryable = ErrorUtils.isRetryable(error); // Check if retryable
|
|
538
|
-
*
|
|
539
|
-
* if (ErrorUtils.isTokenExpiredError(error)) {
|
|
540
|
-
* // Handle token expiration
|
|
541
|
-
* await refreshToken();
|
|
542
|
-
* } else if (retryable) {
|
|
543
|
-
* // Retry operation
|
|
544
|
-
* await retry(someOperation);
|
|
545
|
-
* } else {
|
|
546
|
-
* // Show error to user
|
|
547
|
-
* showError(message);
|
|
548
|
-
* }
|
|
549
|
-
* }
|
|
550
|
-
* ```
|
|
551
|
-
*
|
|
552
|
-
* @example
|
|
553
|
-
* **React Native Error Display:**
|
|
554
|
-
* ```typescript
|
|
555
|
-
* import { PersApiError, ErrorUtils } from '@explorins/pers-sdk-react-native';
|
|
556
|
-
* import { Alert } from 'react-native';
|
|
557
|
-
*
|
|
558
|
-
* const handleError = (error: unknown) => {
|
|
559
|
-
* if (error instanceof PersApiError) {
|
|
560
|
-
* // Show structured error
|
|
561
|
-
* Alert.alert(
|
|
562
|
-
* 'Error',
|
|
563
|
-
* error.userMessage || error.message,
|
|
564
|
-
* [
|
|
565
|
-
* { text: 'OK' },
|
|
566
|
-
* error.retryable && { text: 'Retry', onPress: retry }
|
|
567
|
-
* ].filter(Boolean)
|
|
568
|
-
* );
|
|
569
|
-
* } else {
|
|
570
|
-
* // Show generic error
|
|
571
|
-
* Alert.alert('Error', ErrorUtils.getMessage(error));
|
|
572
|
-
* }
|
|
573
|
-
* };
|
|
574
|
-
* ```
|
|
575
|
-
*/
|
|
576
|
-
export {
|
|
577
|
-
PersApiError,
|
|
578
|
-
AuthenticationError,
|
|
579
|
-
ErrorUtils
|
|
580
|
-
} from '@explorins/pers-sdk/core';
|
|
581
|
-
|
|
582
|
-
// ==============================================================================
|
|
583
|
-
// DATA SOURCE TRACKING
|
|
584
|
-
// ==============================================================================
|
|
585
|
-
|
|
586
|
-
/**
|
|
587
|
-
* Data source tracking utilities for attribution analytics
|
|
588
|
-
*
|
|
589
|
-
* Native apps MUST configure data source and platform info for proper attribution.
|
|
590
|
-
* Web apps benefit from auto-detection, but can still set explicit values.
|
|
591
|
-
*
|
|
592
|
-
* @example
|
|
593
|
-
* **React Native Setup:**
|
|
594
|
-
* ```typescript
|
|
595
|
-
* import { usePersSDK, detectReactNativePlatform } from '@explorins/pers-sdk-react-native';
|
|
596
|
-
*
|
|
597
|
-
* const { sdk } = usePersSDK();
|
|
598
|
-
*
|
|
599
|
-
* // Set platform info (call once on app start)
|
|
600
|
-
* sdk.setPlatform(detectReactNativePlatform());
|
|
601
|
-
*
|
|
602
|
-
* // Set data source (call once, update on deep links/push)
|
|
603
|
-
* sdk.setDataSource({
|
|
604
|
-
* channel: 'mobile',
|
|
605
|
-
* source: 'app_store',
|
|
606
|
-
* });
|
|
607
|
-
* ```
|
|
608
|
-
*
|
|
609
|
-
* @example
|
|
610
|
-
* **Handle Deep Links:**
|
|
611
|
-
* ```typescript
|
|
612
|
-
* import { parseUtmParams } from '@explorins/pers-sdk-react-native';
|
|
613
|
-
*
|
|
614
|
-
* function handleDeepLink(url: string) {
|
|
615
|
-
* const utm = parseUtmParams(url);
|
|
616
|
-
* sdk.updateDataSource({
|
|
617
|
-
* medium: utm.medium,
|
|
618
|
-
* campaign: utm.campaign,
|
|
619
|
-
* source: utm.source || 'deep_link',
|
|
620
|
-
* });
|
|
621
|
-
* }
|
|
622
|
-
* ```
|
|
623
|
-
*
|
|
624
|
-
* @example
|
|
625
|
-
* **Handle Push Notifications:**
|
|
626
|
-
* ```typescript
|
|
627
|
-
* function handlePushNotification(notification: PushNotification) {
|
|
628
|
-
* sdk.updateDataSource({
|
|
629
|
-
* medium: 'push',
|
|
630
|
-
* source: 'push_notification',
|
|
631
|
-
* campaign: notification.campaignId,
|
|
632
|
-
* });
|
|
633
|
-
* }
|
|
634
|
-
* ```
|
|
635
|
-
*/
|
|
636
|
-
export {
|
|
637
|
-
// Types
|
|
638
|
-
type Platform,
|
|
639
|
-
type DataSource,
|
|
640
|
-
type UtmParams,
|
|
641
|
-
type WebDataSourceConfig,
|
|
642
|
-
type NativeDataSourceConfig,
|
|
643
|
-
|
|
644
|
-
// Utilities
|
|
645
|
-
parseUtmParams,
|
|
646
|
-
detectSourceFromReferrer,
|
|
647
|
-
detectWebPlatform,
|
|
648
|
-
} from '@explorins/pers-sdk/core';
|
|
649
|
-
|
|
650
|
-
// React Native specific platform detection
|
|
651
|
-
export { detectReactNativePlatform } from './utils/platform-detection';
|
|
652
|
-
|
|
653
|
-
// ==============================================================================
|
|
654
|
-
// FIELD VALIDATION UTILITIES
|
|
655
|
-
// ==============================================================================
|
|
656
|
-
|
|
657
|
-
/**
|
|
658
|
-
* Field validation utilities for custom fields and forms
|
|
659
|
-
*
|
|
660
|
-
* These functions are re-exported from @explorins/pers-shared for convenience.
|
|
661
|
-
* Use them for client-side validation before submitting data to the backend.
|
|
662
|
-
*
|
|
663
|
-
* @example
|
|
664
|
-
* **Single Field Validation:**
|
|
665
|
-
* ```typescript
|
|
666
|
-
* import { validateFieldValue, FieldType, FieldValidationRules } from '@explorins/pers-sdk-react-native';
|
|
667
|
-
*
|
|
668
|
-
* const rules: FieldValidationRules = { minLength: 3 };
|
|
669
|
-
* const error = validateFieldValue('ab', rules, 'text');
|
|
670
|
-
* // error: { message: 'Must be at least 3 characters' }
|
|
671
|
-
* ```
|
|
672
|
-
*
|
|
673
|
-
* @example
|
|
674
|
-
* **Form Validation:**
|
|
675
|
-
* ```typescript
|
|
676
|
-
* import { validateAllFields, FieldDefinition } from '@explorins/pers-sdk-react-native';
|
|
677
|
-
*
|
|
678
|
-
* const definitions: FieldDefinition[] = [
|
|
679
|
-
* { key: 'email', fieldType: 'email', label: 'Email', validation: { minLength: 1 } },
|
|
680
|
-
* { key: 'phone', fieldType: 'phone', label: 'Phone', validation: {} }
|
|
681
|
-
* ];
|
|
682
|
-
*
|
|
683
|
-
* const formData = { email: 'invalid', phone: '123' };
|
|
684
|
-
* const errors = validateAllFields(formData, definitions);
|
|
685
|
-
* // errors: [{ field: 'email', message: 'Invalid email format' }]
|
|
686
|
-
* ```
|
|
687
|
-
*
|
|
688
|
-
* @see {@link validateFieldValue} - Validate a single field value
|
|
689
|
-
* @see {@link validateAllFields} - Validate all fields against definitions
|
|
690
|
-
* @see {@link FieldDefinition} - Field definition structure
|
|
691
|
-
* @see {@link FieldValidationRules} - Available validation rules
|
|
692
|
-
*/
|
|
693
|
-
export {
|
|
694
|
-
validateFieldValue,
|
|
695
|
-
validateAllFields,
|
|
696
|
-
validateFieldComparisons,
|
|
697
|
-
compareValues,
|
|
698
|
-
type FieldDefinition,
|
|
699
|
-
type FieldValidationRules,
|
|
700
|
-
type ValidationErrorDetail,
|
|
701
|
-
type FieldType,
|
|
702
|
-
type FieldComparison,
|
|
703
|
-
type ComparisonOperator,
|
|
704
|
-
} from '@explorins/pers-sdk';
|
|
705
|
-
|
|
706
|
-
// ==============================================================================
|
|
707
|
-
// BOOKING STATUS VALIDATION
|
|
708
|
-
// ==============================================================================
|
|
709
|
-
|
|
710
|
-
/**
|
|
711
|
-
* Booking status types and validation utilities for eligibility checks
|
|
712
|
-
*
|
|
713
|
-
* Use these to validate if a user's booking status meets requirements
|
|
714
|
-
* for redemptions, campaigns, or other booking-dependent features.
|
|
715
|
-
*
|
|
716
|
-
* **BookingStatus:** 'past' | 'active' | 'future'
|
|
717
|
-
* - `past`: User's stay has ended (checkOut ≤ now)
|
|
718
|
-
* - `active`: User is currently staying (checkIn ≤ now < checkOut)
|
|
719
|
-
* - `future`: Upcoming booking (checkIn > now)
|
|
720
|
-
*
|
|
721
|
-
* **BookingRequirementType:** 'active' | 'future' | 'past' | 'active_future' | 'any'
|
|
722
|
-
* - `active`: Only active bookings allowed
|
|
723
|
-
* - `future`: Only future bookings allowed
|
|
724
|
-
* - `past`: Only past bookings allowed
|
|
725
|
-
* - `active_future`: Active OR future bookings allowed
|
|
726
|
-
* - `any`: Any booking status allowed
|
|
727
|
-
*
|
|
728
|
-
* @example
|
|
729
|
-
* **Basic Validation:**
|
|
730
|
-
* ```typescript
|
|
731
|
-
* import {
|
|
732
|
-
* isBookingStatusValid,
|
|
733
|
-
* BookingStatus,
|
|
734
|
-
* BookingRequirementType
|
|
735
|
-
* } from '@explorins/pers-sdk-react-native';
|
|
736
|
-
*
|
|
737
|
-
* const userBookingStatus: BookingStatus = booking.status;
|
|
738
|
-
* const requirement: BookingRequirementType = redemption.bookingRequirement;
|
|
739
|
-
* const canRedeem = isBookingStatusValid(userBookingStatus, requirement);
|
|
740
|
-
* ```
|
|
741
|
-
*
|
|
742
|
-
* @example
|
|
743
|
-
* **Redemption Screen:**
|
|
744
|
-
* ```typescript
|
|
745
|
-
* function RedemptionCard({ redemption, userBooking }) {
|
|
746
|
-
* const isEligible = redemption.bookingRequirement
|
|
747
|
-
* ? isBookingStatusValid(userBooking?.status ?? 'past', redemption.bookingRequirement)
|
|
748
|
-
* : true;
|
|
749
|
-
*
|
|
750
|
-
* return (
|
|
751
|
-
* <View style={[styles.card, !isEligible && styles.disabled]}>
|
|
752
|
-
* <Text>{redemption.name}</Text>
|
|
753
|
-
* {!isEligible && (
|
|
754
|
-
* <Text style={styles.warning}>
|
|
755
|
-
* Requires {redemption.bookingRequirement} booking
|
|
756
|
-
* </Text>
|
|
757
|
-
* )}
|
|
758
|
-
* </View>
|
|
759
|
-
* );
|
|
760
|
-
* }
|
|
761
|
-
* ```
|
|
762
|
-
*
|
|
763
|
-
* @example
|
|
764
|
-
* **Validation Results:**
|
|
765
|
-
* ```typescript
|
|
766
|
-
* isBookingStatusValid('active', 'active'); // true
|
|
767
|
-
* isBookingStatusValid('future', 'active'); // false
|
|
768
|
-
* isBookingStatusValid('active', 'active_future'); // true
|
|
769
|
-
* isBookingStatusValid('future', 'active_future'); // true
|
|
770
|
-
* isBookingStatusValid('past', 'active_future'); // false
|
|
771
|
-
* isBookingStatusValid('past', 'any'); // true
|
|
772
|
-
* ```
|
|
773
|
-
*/
|
|
774
|
-
export {
|
|
775
|
-
isBookingStatusValid,
|
|
776
|
-
type BookingStatus,
|
|
777
|
-
type BookingRequirementType
|
|
1
|
+
// Polyfills - must be imported first for Hermes engine compatibility
|
|
2
|
+
import 'react-native-url-polyfill/auto';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @fileoverview PERS SDK for React Native - Tourism Loyalty System
|
|
6
|
+
*
|
|
7
|
+
* A comprehensive React Native SDK for integrating with the PERS (Phygital Experience Rewards System)
|
|
8
|
+
* platform. Provides complete functionality for tourism loyalty applications including user management,
|
|
9
|
+
* token operations, business integrations, campaign management, and blockchain transaction signing.
|
|
10
|
+
*
|
|
11
|
+
* **Key Features:**
|
|
12
|
+
* - Secure authentication with React Native Keychain integration
|
|
13
|
+
* - Token management (earn, redeem, transfer, balance checking)
|
|
14
|
+
* - Business and campaign management
|
|
15
|
+
* - Blockchain transaction signing with WebAuthn
|
|
16
|
+
* - React Native optimized with automatic polyfills
|
|
17
|
+
* - Type-safe interfaces with comprehensive TypeScript support
|
|
18
|
+
* - Analytics and reporting capabilities
|
|
19
|
+
* - Donation and charitable giving features
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* **Quick Start:**
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { PersSDKProvider, usePersSDK, useTransactionSigner } from '@explorins/pers-sdk-react-native';
|
|
25
|
+
*
|
|
26
|
+
* // 1. Wrap your app with the provider
|
|
27
|
+
* function App() {
|
|
28
|
+
* return (
|
|
29
|
+
* <PersSDKProvider config={{ apiUrl: 'https://api.pers.ninja' }}>
|
|
30
|
+
* <YourApp />
|
|
31
|
+
* </PersSDKProvider>
|
|
32
|
+
* );
|
|
33
|
+
* }
|
|
34
|
+
*
|
|
35
|
+
* // 2. Use hooks in your components
|
|
36
|
+
* function RewardScreen() {
|
|
37
|
+
* const { user, isAuthenticated, earnTokens } = usePersSDK();
|
|
38
|
+
* const { signAndSubmitTransactionWithJWT } = useTransactionSigner();
|
|
39
|
+
*
|
|
40
|
+
* // Your reward logic here...
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @version 1.5.19
|
|
45
|
+
* @author eXplorins
|
|
46
|
+
* @license MIT
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
// Initialize React Native polyfills automatically
|
|
50
|
+
import './polyfills';
|
|
51
|
+
|
|
52
|
+
// ==============================================================================
|
|
53
|
+
// AUTHENTICATION PROVIDERS
|
|
54
|
+
// ==============================================================================
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* React Native-specific authentication provider with secure keychain integration
|
|
58
|
+
*
|
|
59
|
+
* Provides secure token storage using React Native Keychain, biometric authentication,
|
|
60
|
+
* and automatic token refresh capabilities.
|
|
61
|
+
*
|
|
62
|
+
* @see {@link createReactNativeAuthProvider} - Factory function for auth provider
|
|
63
|
+
* @see {@link ReactNativeAuthConfig} - Configuration interface
|
|
64
|
+
*/
|
|
65
|
+
export {
|
|
66
|
+
createReactNativeAuthProvider,
|
|
67
|
+
type ReactNativeAuthConfig
|
|
68
|
+
} from './providers/react-native-auth-provider';
|
|
69
|
+
|
|
70
|
+
// ==============================================================================
|
|
71
|
+
// SECURE STORAGE
|
|
72
|
+
// ==============================================================================
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Secure Token Storage with Keychain Integration
|
|
76
|
+
*
|
|
77
|
+
* Implements the TokenStorage interface using React Native Keychain for sensitive data
|
|
78
|
+
* (Private Keys, Access Tokens) and AsyncStorage for configuration/public data.
|
|
79
|
+
*
|
|
80
|
+
* - Encryption: Hardware-backed keystore
|
|
81
|
+
* - Persistence: Survives app uninstall (on iOS usually) or clears on uninstall (Android) if configured
|
|
82
|
+
*
|
|
83
|
+
* @see {@link ReactNativeSecureStorage} - The implementation class
|
|
84
|
+
*/
|
|
85
|
+
export { ReactNativeSecureStorage } from './storage/rn-secure-storage';
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Secure token storage using React Native AsyncStorage
|
|
89
|
+
*
|
|
90
|
+
* Provides encrypted token storage with automatic cleanup and secure key management.
|
|
91
|
+
* Integrates with React Native Keychain for enhanced security on supported devices.
|
|
92
|
+
*
|
|
93
|
+
* @see {@link AsyncStorageTokenStorage} - Secure storage implementation
|
|
94
|
+
* @deprecated Use ReactNativeSecureStorage for better security (Keychain integration)
|
|
95
|
+
*/
|
|
96
|
+
export {
|
|
97
|
+
AsyncStorageTokenStorage,
|
|
98
|
+
} from './storage/async-storage-token-storage';
|
|
99
|
+
|
|
100
|
+
// ==============================================================================
|
|
101
|
+
// DPoP PROVIDER
|
|
102
|
+
// ==============================================================================
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* React Native DPoP Crypto Provider
|
|
106
|
+
* implements DPoPCryptoProvider using react-native-quick-crypto
|
|
107
|
+
*/
|
|
108
|
+
export { ReactNativeDPoPProvider } from './providers/rn-dpop-provider';
|
|
109
|
+
|
|
110
|
+
// ==============================================================================
|
|
111
|
+
// CORE PROVIDER & CONTEXT
|
|
112
|
+
// ==============================================================================
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Main PERS SDK provider and context for React Native applications
|
|
116
|
+
*
|
|
117
|
+
* The PersSDKProvider should wrap your entire app to provide PERS functionality
|
|
118
|
+
* throughout your component tree. Use usePersSDK hook to access SDK features.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* import { PersSDKProvider, usePersSDK } from '@explorins/pers-sdk-react-native';
|
|
123
|
+
*
|
|
124
|
+
* function App() {
|
|
125
|
+
* return (
|
|
126
|
+
* <PersSDKProvider config={{
|
|
127
|
+
* apiUrl: 'https://api.pers.ninja',
|
|
128
|
+
* tenantId: 'your-tenant-id'
|
|
129
|
+
* }}>
|
|
130
|
+
* <NavigationContainer>
|
|
131
|
+
* <YourAppContent />
|
|
132
|
+
* </NavigationContainer>
|
|
133
|
+
* </PersSDKProvider>
|
|
134
|
+
* );
|
|
135
|
+
* }
|
|
136
|
+
*
|
|
137
|
+
* function YourComponent() {
|
|
138
|
+
* const { user, isAuthenticated, earnTokens } = usePersSDK();
|
|
139
|
+
* // Use PERS functionality here...
|
|
140
|
+
* }
|
|
141
|
+
* ```
|
|
142
|
+
*
|
|
143
|
+
* @see {@link PersSDKProvider} - Main provider component
|
|
144
|
+
* @see {@link usePersSDK} - Hook to access SDK functionality
|
|
145
|
+
* @see {@link PersConfig} - Provider configuration interface
|
|
146
|
+
* @see {@link PersSDKContext} - Context type definition
|
|
147
|
+
*/
|
|
148
|
+
export {
|
|
149
|
+
PersSDKProvider,
|
|
150
|
+
usePersSDK,
|
|
151
|
+
type PersConfig,
|
|
152
|
+
type PersSDKContext
|
|
153
|
+
} from './providers/PersSDKProvider';
|
|
154
|
+
|
|
155
|
+
// ==============================================================================
|
|
156
|
+
// REACT HOOKS (Primary Interface)
|
|
157
|
+
// ==============================================================================
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Comprehensive React hooks for PERS platform integration
|
|
161
|
+
*
|
|
162
|
+
* These hooks provide the primary interface for interacting with the PERS platform
|
|
163
|
+
* in React Native applications. Each hook is optimized for specific functionality
|
|
164
|
+
* and includes automatic error handling, loading states, and real-time updates.
|
|
165
|
+
*
|
|
166
|
+
* **Authentication & User Management:**
|
|
167
|
+
* - `useAuth` - User authentication, login, logout, registration
|
|
168
|
+
* - `useUsers` - User profile management and data operations
|
|
169
|
+
* - `useUserStatus` - Real-time user status and activity monitoring
|
|
170
|
+
*
|
|
171
|
+
* **Token & Financial Operations:**
|
|
172
|
+
* - `useTokens` - Token balance, earning, and management
|
|
173
|
+
* - `useTransactions` - Transaction history and monitoring
|
|
174
|
+
* - `useTransactionSigner` - **⭐ Blockchain transaction signing**
|
|
175
|
+
* - `usePurchases` - Purchase history and payment processing
|
|
176
|
+
* - `useDonations` - Charitable giving and donation management
|
|
177
|
+
*
|
|
178
|
+
* **Business & Campaign Management:**
|
|
179
|
+
* - `useBusiness` - Business profile and operations
|
|
180
|
+
* - `useBookings` - Booking management with status validation
|
|
181
|
+
* - `useCampaigns` - Marketing campaigns and promotions
|
|
182
|
+
* - `useRedemptions` - Reward redemption and fulfillment
|
|
183
|
+
*
|
|
184
|
+
* **Platform & Analytics:**
|
|
185
|
+
* - `useTenants` - Multi-tenant configuration and management
|
|
186
|
+
* - `useAnalytics` - Usage analytics and reporting
|
|
187
|
+
* - `useFiles` - File upload and management
|
|
188
|
+
* - `useWeb3` - Blockchain integration and wallet operations
|
|
189
|
+
* - `useEvents` - ** SDK event subscriptions for notifications**
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* **Token Operations:**
|
|
193
|
+
* ```typescript
|
|
194
|
+
* import { useTokens, useTransactionSigner } from '@explorins/pers-sdk-react-native';
|
|
195
|
+
*
|
|
196
|
+
* function TokenScreen() {
|
|
197
|
+
* const { balance, earnTokens, redeemTokens } = useTokens();
|
|
198
|
+
* const { signAndSubmitTransactionWithJWT } = useTransactionSigner();
|
|
199
|
+
*
|
|
200
|
+
* const handleEarn = async (amount: number) => {
|
|
201
|
+
* const result = await earnTokens({ amount, source: 'reward' });
|
|
202
|
+
* console.log('Earned tokens:', result);
|
|
203
|
+
* };
|
|
204
|
+
*
|
|
205
|
+
* const handleRedeem = async (amount: number) => {
|
|
206
|
+
* const redemption = await redeemTokens({ amount });
|
|
207
|
+
* const txResult = await signAndSubmitTransactionWithJWT(redemption.jwtToken);
|
|
208
|
+
* console.log('Redemption completed:', txResult.transactionHash);
|
|
209
|
+
* };
|
|
210
|
+
* }
|
|
211
|
+
* ```
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* **Campaign Integration:**
|
|
215
|
+
* ```typescript
|
|
216
|
+
* import { useCampaigns, useAuth } from '@explorins/pers-sdk-react-native';
|
|
217
|
+
*
|
|
218
|
+
* function CampaignScreen() {
|
|
219
|
+
* const { activeCampaigns, participateInCampaign } = useCampaigns();
|
|
220
|
+
* const { user } = useAuth();
|
|
221
|
+
*
|
|
222
|
+
* const handleParticipate = async (campaignId: string) => {
|
|
223
|
+
* const result = await participateInCampaign(campaignId, {
|
|
224
|
+
* userId: user?.id,
|
|
225
|
+
* participationData: { source: 'mobile_app' }
|
|
226
|
+
* });
|
|
227
|
+
* };
|
|
228
|
+
* }
|
|
229
|
+
* ```
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* **Event Subscriptions:**
|
|
233
|
+
* ```typescript
|
|
234
|
+
* import { useEvents, useEffect } from '@explorins/pers-sdk-react-native';
|
|
235
|
+
*
|
|
236
|
+
* function NotificationHandler() {
|
|
237
|
+
* const { subscribe, isAvailable } = useEvents();
|
|
238
|
+
*
|
|
239
|
+
* useEffect(() => {
|
|
240
|
+
* if (!isAvailable) return;
|
|
241
|
+
*
|
|
242
|
+
* const unsubscribe = subscribe((event) => {
|
|
243
|
+
* showNotification(event.userMessage, event.level);
|
|
244
|
+
* });
|
|
245
|
+
*
|
|
246
|
+
* return () => unsubscribe();
|
|
247
|
+
* }, [subscribe, isAvailable]);
|
|
248
|
+
* }
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
export {
|
|
252
|
+
useAuth,
|
|
253
|
+
useTokens,
|
|
254
|
+
useTokenBalances,
|
|
255
|
+
useTransactions,
|
|
256
|
+
useTransactionSigner,
|
|
257
|
+
SigningStatus,
|
|
258
|
+
useBusiness,
|
|
259
|
+
useBookings,
|
|
260
|
+
useCampaigns,
|
|
261
|
+
useRedemptions,
|
|
262
|
+
useWeb3,
|
|
263
|
+
usePurchases,
|
|
264
|
+
useTenants,
|
|
265
|
+
useUsers,
|
|
266
|
+
useUserStatus,
|
|
267
|
+
useFiles,
|
|
268
|
+
useAnalytics,
|
|
269
|
+
useDonations,
|
|
270
|
+
useEvents,
|
|
271
|
+
useTriggerSources,
|
|
272
|
+
// IPFS hooks - for resolving ipfs:// URLs and loading metadata
|
|
273
|
+
useResolvedUrl,
|
|
274
|
+
useMetadata,
|
|
275
|
+
useIPFSUrl, // alias for useResolvedUrl
|
|
276
|
+
useTransactionMetadata // convenience for transaction items
|
|
277
|
+
} from './hooks';
|
|
278
|
+
|
|
279
|
+
// Re-export signing status types for convenience
|
|
280
|
+
export type {
|
|
281
|
+
TransactionSignerHook,
|
|
282
|
+
OnStatusUpdateFn,
|
|
283
|
+
StatusUpdateData,
|
|
284
|
+
SigningStatusType,
|
|
285
|
+
TransactionSigningResult,
|
|
286
|
+
SubmissionResult,
|
|
287
|
+
AuthenticatedUser
|
|
288
|
+
} from './hooks';
|
|
289
|
+
|
|
290
|
+
// Re-export event types for convenience
|
|
291
|
+
export type { EventsHook, PersEvent, EventHandler, EventFilter, Unsubscribe } from './hooks';
|
|
292
|
+
|
|
293
|
+
// Re-export token balance types for convenience
|
|
294
|
+
export type { TokenBalanceWithToken, UseTokenBalancesOptions, UseTokenBalancesResult } from './hooks';
|
|
295
|
+
|
|
296
|
+
// Re-export campaign types for convenience
|
|
297
|
+
export type { CampaignClaimFilters, CampaignFilterOptions, CampaignHook, GetCampaignsOptions } from './hooks';
|
|
298
|
+
|
|
299
|
+
// Re-export redemption types for convenience
|
|
300
|
+
export type { RedemptionRedeemFilters, RedemptionFilterOptions, RedemptionHook, GetRedemptionsOptions } from './hooks';
|
|
301
|
+
|
|
302
|
+
// Re-export business types for convenience
|
|
303
|
+
export type { BusinessFilterOptions, BusinessHook } from './hooks';
|
|
304
|
+
|
|
305
|
+
// Re-export transaction types for convenience
|
|
306
|
+
export type { TransactionQueryOptions, TransactionHook } from './hooks';
|
|
307
|
+
|
|
308
|
+
// Re-export trigger source types for convenience
|
|
309
|
+
export type { TriggerSourceQueryOptions, TriggerSourceHook } from './hooks';
|
|
310
|
+
|
|
311
|
+
// Re-export analytics types for convenience
|
|
312
|
+
export type { AnalyticsHook } from './hooks';
|
|
313
|
+
|
|
314
|
+
// Re-export booking types for convenience
|
|
315
|
+
export type { BookingHook, BookingQueryOptions, BookingValidationOptions } from './hooks';
|
|
316
|
+
|
|
317
|
+
// ==============================================================================
|
|
318
|
+
// PLATFORM ADAPTERS
|
|
319
|
+
// ==============================================================================
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* React Native-optimized HTTP client with automatic request/response handling
|
|
323
|
+
*
|
|
324
|
+
* Provides platform-specific networking with proper error handling, timeout management,
|
|
325
|
+
* and React Native compatibility. Automatically handles headers, authentication tokens,
|
|
326
|
+
* and response parsing.
|
|
327
|
+
*
|
|
328
|
+
* @see {@link ReactNativeHttpClient} - The HTTP client implementation
|
|
329
|
+
* @see {@link HttpClient} - The HTTP client interface
|
|
330
|
+
* @see {@link RequestOptions} - Request configuration options
|
|
331
|
+
*/
|
|
332
|
+
export {
|
|
333
|
+
ReactNativeHttpClient,
|
|
334
|
+
type HttpClient,
|
|
335
|
+
type RequestOptions
|
|
336
|
+
} from './providers/react-native-http-client';
|
|
337
|
+
|
|
338
|
+
// ==============================================================================
|
|
339
|
+
// POLYFILLS & COMPATIBILITY
|
|
340
|
+
// ==============================================================================
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* React Native polyfill utilities for web compatibility
|
|
344
|
+
*
|
|
345
|
+
* Automatically initializes required polyfills for crypto, URL, and other web APIs
|
|
346
|
+
* that may not be available in React Native environments. These are typically
|
|
347
|
+
* loaded automatically, but manual initialization is available for advanced use cases.
|
|
348
|
+
*
|
|
349
|
+
* @see {@link initializeReactNativePolyfills} - Manual polyfill initialization
|
|
350
|
+
*/
|
|
351
|
+
export {
|
|
352
|
+
initializeReactNativePolyfills
|
|
353
|
+
} from './polyfills';
|
|
354
|
+
|
|
355
|
+
// ==============================================================================
|
|
356
|
+
// TYPE DEFINITIONS & SHARED UTILITIES
|
|
357
|
+
// ==============================================================================
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Re-export all types and utilities from the shared PERS library
|
|
361
|
+
*
|
|
362
|
+
* This includes all core types, DTOs, enums, and utility functions used across
|
|
363
|
+
* the PERS platform. These types ensure consistency between different SDK versions
|
|
364
|
+
* and platform implementations.
|
|
365
|
+
*
|
|
366
|
+
* **Included Types:**
|
|
367
|
+
* - User and authentication types (UserDTO, AuthenticationResult, etc.)
|
|
368
|
+
* - Token and transaction types (TokenDTO, TransactionDTO, etc.)
|
|
369
|
+
* - Business and campaign types (BusinessDTO, CampaignDTO, etc.)
|
|
370
|
+
* - API request/response types for all endpoints
|
|
371
|
+
* - Error types and status enums
|
|
372
|
+
* - Utility functions for pagination, token display, etc.
|
|
373
|
+
*
|
|
374
|
+
* @see {@link https://github.com/eXplorins/pers-shared} - Shared library documentation
|
|
375
|
+
*/
|
|
376
|
+
export * from '@explorins/pers-sdk';
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Token utilities re-exported from token module
|
|
380
|
+
*
|
|
381
|
+
* @see {@link getMetadataFromTokenUnitResponse} - Get full metadata object from token unit
|
|
382
|
+
*/
|
|
383
|
+
export { getMetadataFromTokenUnitResponse } from '@explorins/pers-sdk/token';
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Shared SDK utilities re-exported from base SDK
|
|
387
|
+
*
|
|
388
|
+
* Includes helper functions for:
|
|
389
|
+
* - Pagination utilities (buildPaginationParams, extractData, etc.)
|
|
390
|
+
*/
|
|
391
|
+
export {
|
|
392
|
+
// Pagination utilities
|
|
393
|
+
buildPaginationParams,
|
|
394
|
+
extractData,
|
|
395
|
+
extractPagination,
|
|
396
|
+
isPaginatedResponse,
|
|
397
|
+
normalizeToPaginated,
|
|
398
|
+
fetchAllPages,
|
|
399
|
+
type PaginationOptions,
|
|
400
|
+
type PaginationWithFilters,
|
|
401
|
+
type ListResponse
|
|
402
|
+
} from '@explorins/pers-sdk';
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Re-export Web3 and blockchain-related types from base SDK
|
|
406
|
+
*
|
|
407
|
+
* Provides TypeScript definitions for Web3 operations, token management,
|
|
408
|
+
* and blockchain interactions. These types are used by the transaction
|
|
409
|
+
* signing hooks and Web3 integration features.
|
|
410
|
+
*
|
|
411
|
+
* @see {@link TokenBalanceRequest} - Request structure for token balance queries
|
|
412
|
+
* @see {@link TokenBalance} - Token balance response data
|
|
413
|
+
* @see {@link TokenMetadata} - Token metadata and details
|
|
414
|
+
* @see {@link TokenCollection} - Collection of tokens for batch operations
|
|
415
|
+
*/
|
|
416
|
+
export type {
|
|
417
|
+
TokenBalanceRequest,
|
|
418
|
+
TokenBalance,
|
|
419
|
+
TokenMetadata,
|
|
420
|
+
TokenCollection,
|
|
421
|
+
TokenCollectionRequest
|
|
422
|
+
} from '@explorins/pers-sdk/web3';
|
|
423
|
+
|
|
424
|
+
// ==============================================================================
|
|
425
|
+
// TRANSACTION REQUEST FACTORY FUNCTIONS
|
|
426
|
+
// ==============================================================================
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Transaction Request Factory Functions
|
|
430
|
+
*
|
|
431
|
+
* Factory functions for creating properly structured transaction DTOs.
|
|
432
|
+
* Prioritizes accountId/accountType over raw addresses for security and consistency.
|
|
433
|
+
*
|
|
434
|
+
* @example
|
|
435
|
+
* ```typescript
|
|
436
|
+
* import {
|
|
437
|
+
* buildMintRequest,
|
|
438
|
+
* buildTransferRequest,
|
|
439
|
+
* buildBurnRequest,
|
|
440
|
+
* useTransactions,
|
|
441
|
+
* AccountOwnerType
|
|
442
|
+
* } from '@explorins/pers-sdk-react-native';
|
|
443
|
+
*
|
|
444
|
+
* function TokenOperations() {
|
|
445
|
+
* const { createTransaction } = useTransactions();
|
|
446
|
+
*
|
|
447
|
+
* const handleMint = async () => {
|
|
448
|
+
* const request = buildMintRequest({
|
|
449
|
+
* amount: 100,
|
|
450
|
+
* contractAddress: '0x...',
|
|
451
|
+
* chainId: 137,
|
|
452
|
+
* recipientAccountType: AccountOwnerType.USER,
|
|
453
|
+
* recipientAccountId: 'user-123'
|
|
454
|
+
* });
|
|
455
|
+
* await createTransaction(request);
|
|
456
|
+
* };
|
|
457
|
+
* }
|
|
458
|
+
* ```
|
|
459
|
+
*
|
|
460
|
+
* @see {@link buildMintRequest} - Create mint transaction requests
|
|
461
|
+
* @see {@link buildBurnRequest} - Create burn transaction requests
|
|
462
|
+
* @see {@link buildTransferRequest} - Create transfer transaction requests
|
|
463
|
+
* @see {@link buildPOSTransferRequest} - Create POS transfer requests (business submits on behalf of user)
|
|
464
|
+
* @see {@link buildPOSBurnRequest} - Create POS burn requests (business submits burn on behalf of user)
|
|
465
|
+
* @see {@link buildSubmissionRequest} - Create submission requests from QR/signature data
|
|
466
|
+
*/
|
|
467
|
+
export {
|
|
468
|
+
buildMintRequest,
|
|
469
|
+
buildBurnRequest,
|
|
470
|
+
buildTransferRequest,
|
|
471
|
+
buildPOSTransferRequest,
|
|
472
|
+
buildPOSBurnRequest,
|
|
473
|
+
buildSubmissionRequest,
|
|
474
|
+
ClientTransactionType,
|
|
475
|
+
extractDeadlineFromSigningData,
|
|
476
|
+
buildPendingTransactionData,
|
|
477
|
+
needsSubmission,
|
|
478
|
+
needsExternalSigning,
|
|
479
|
+
getSigningUrl
|
|
480
|
+
} from '@explorins/pers-sdk/transaction';
|
|
481
|
+
|
|
482
|
+
export type { POSAuthorizationOptions, PendingTransactionParams } from '@explorins/pers-sdk/transaction';
|
|
483
|
+
|
|
484
|
+
// ==============================================================================
|
|
485
|
+
// ERROR CLASSES (for instanceof checks)
|
|
486
|
+
// ==============================================================================
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Structured error handling for PERS SDK
|
|
490
|
+
*
|
|
491
|
+
* The SDK provides comprehensive error classes and utilities for consistent error handling
|
|
492
|
+
* across all operations. Errors follow the StructuredError pattern from @explorins/pers-shared.
|
|
493
|
+
*
|
|
494
|
+
* **Error Classes:**
|
|
495
|
+
* - `PersApiError` - API errors with structured backend details
|
|
496
|
+
* - `AuthenticationError` - Authentication/authorization failures (401)
|
|
497
|
+
*
|
|
498
|
+
* **Error Utilities:**
|
|
499
|
+
* - `ErrorUtils.getMessage(error)` - Extract user-friendly message
|
|
500
|
+
* - `ErrorUtils.getStatus(error)` - Get HTTP status code
|
|
501
|
+
* - `ErrorUtils.isRetryable(error)` - Check if operation should be retried
|
|
502
|
+
* - `ErrorUtils.isTokenExpiredError(error)` - Detect token expiration
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* **Basic Error Handling:**
|
|
506
|
+
* ```typescript
|
|
507
|
+
* import { PersApiError, ErrorUtils } from '@explorins/pers-sdk-react-native';
|
|
508
|
+
*
|
|
509
|
+
* try {
|
|
510
|
+
* await sdk.campaigns.claimCampaign({ campaignId });
|
|
511
|
+
* } catch (error) {
|
|
512
|
+
* if (error instanceof PersApiError) {
|
|
513
|
+
* // Structured error with backend details
|
|
514
|
+
* console.log('Error code:', error.code); // 'CAMPAIGN_BUSINESS_REQUIRED'
|
|
515
|
+
* console.log('Status:', error.status); // 400
|
|
516
|
+
* console.log('Message:', error.message); // Backend error message
|
|
517
|
+
* console.log('User message:', error.userMessage); // User-friendly message
|
|
518
|
+
* console.log('Retryable:', error.retryable); // false
|
|
519
|
+
* } else {
|
|
520
|
+
* // Generic error fallback
|
|
521
|
+
* const message = ErrorUtils.getMessage(error);
|
|
522
|
+
* console.error('Operation failed:', message);
|
|
523
|
+
* }
|
|
524
|
+
* }
|
|
525
|
+
* ```
|
|
526
|
+
*
|
|
527
|
+
* @example
|
|
528
|
+
* **Error Utilities:**
|
|
529
|
+
* ```typescript
|
|
530
|
+
* import { ErrorUtils } from '@explorins/pers-sdk-react-native';
|
|
531
|
+
*
|
|
532
|
+
* try {
|
|
533
|
+
* await someOperation();
|
|
534
|
+
* } catch (error) {
|
|
535
|
+
* const status = ErrorUtils.getStatus(error); // Extract status code
|
|
536
|
+
* const message = ErrorUtils.getMessage(error); // Extract message
|
|
537
|
+
* const retryable = ErrorUtils.isRetryable(error); // Check if retryable
|
|
538
|
+
*
|
|
539
|
+
* if (ErrorUtils.isTokenExpiredError(error)) {
|
|
540
|
+
* // Handle token expiration
|
|
541
|
+
* await refreshToken();
|
|
542
|
+
* } else if (retryable) {
|
|
543
|
+
* // Retry operation
|
|
544
|
+
* await retry(someOperation);
|
|
545
|
+
* } else {
|
|
546
|
+
* // Show error to user
|
|
547
|
+
* showError(message);
|
|
548
|
+
* }
|
|
549
|
+
* }
|
|
550
|
+
* ```
|
|
551
|
+
*
|
|
552
|
+
* @example
|
|
553
|
+
* **React Native Error Display:**
|
|
554
|
+
* ```typescript
|
|
555
|
+
* import { PersApiError, ErrorUtils } from '@explorins/pers-sdk-react-native';
|
|
556
|
+
* import { Alert } from 'react-native';
|
|
557
|
+
*
|
|
558
|
+
* const handleError = (error: unknown) => {
|
|
559
|
+
* if (error instanceof PersApiError) {
|
|
560
|
+
* // Show structured error
|
|
561
|
+
* Alert.alert(
|
|
562
|
+
* 'Error',
|
|
563
|
+
* error.userMessage || error.message,
|
|
564
|
+
* [
|
|
565
|
+
* { text: 'OK' },
|
|
566
|
+
* error.retryable && { text: 'Retry', onPress: retry }
|
|
567
|
+
* ].filter(Boolean)
|
|
568
|
+
* );
|
|
569
|
+
* } else {
|
|
570
|
+
* // Show generic error
|
|
571
|
+
* Alert.alert('Error', ErrorUtils.getMessage(error));
|
|
572
|
+
* }
|
|
573
|
+
* };
|
|
574
|
+
* ```
|
|
575
|
+
*/
|
|
576
|
+
export {
|
|
577
|
+
PersApiError,
|
|
578
|
+
AuthenticationError,
|
|
579
|
+
ErrorUtils
|
|
580
|
+
} from '@explorins/pers-sdk/core';
|
|
581
|
+
|
|
582
|
+
// ==============================================================================
|
|
583
|
+
// DATA SOURCE TRACKING
|
|
584
|
+
// ==============================================================================
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Data source tracking utilities for attribution analytics
|
|
588
|
+
*
|
|
589
|
+
* Native apps MUST configure data source and platform info for proper attribution.
|
|
590
|
+
* Web apps benefit from auto-detection, but can still set explicit values.
|
|
591
|
+
*
|
|
592
|
+
* @example
|
|
593
|
+
* **React Native Setup:**
|
|
594
|
+
* ```typescript
|
|
595
|
+
* import { usePersSDK, detectReactNativePlatform } from '@explorins/pers-sdk-react-native';
|
|
596
|
+
*
|
|
597
|
+
* const { sdk } = usePersSDK();
|
|
598
|
+
*
|
|
599
|
+
* // Set platform info (call once on app start)
|
|
600
|
+
* sdk.setPlatform(detectReactNativePlatform());
|
|
601
|
+
*
|
|
602
|
+
* // Set data source (call once, update on deep links/push)
|
|
603
|
+
* sdk.setDataSource({
|
|
604
|
+
* channel: 'mobile',
|
|
605
|
+
* source: 'app_store',
|
|
606
|
+
* });
|
|
607
|
+
* ```
|
|
608
|
+
*
|
|
609
|
+
* @example
|
|
610
|
+
* **Handle Deep Links:**
|
|
611
|
+
* ```typescript
|
|
612
|
+
* import { parseUtmParams } from '@explorins/pers-sdk-react-native';
|
|
613
|
+
*
|
|
614
|
+
* function handleDeepLink(url: string) {
|
|
615
|
+
* const utm = parseUtmParams(url);
|
|
616
|
+
* sdk.updateDataSource({
|
|
617
|
+
* medium: utm.medium,
|
|
618
|
+
* campaign: utm.campaign,
|
|
619
|
+
* source: utm.source || 'deep_link',
|
|
620
|
+
* });
|
|
621
|
+
* }
|
|
622
|
+
* ```
|
|
623
|
+
*
|
|
624
|
+
* @example
|
|
625
|
+
* **Handle Push Notifications:**
|
|
626
|
+
* ```typescript
|
|
627
|
+
* function handlePushNotification(notification: PushNotification) {
|
|
628
|
+
* sdk.updateDataSource({
|
|
629
|
+
* medium: 'push',
|
|
630
|
+
* source: 'push_notification',
|
|
631
|
+
* campaign: notification.campaignId,
|
|
632
|
+
* });
|
|
633
|
+
* }
|
|
634
|
+
* ```
|
|
635
|
+
*/
|
|
636
|
+
export {
|
|
637
|
+
// Types
|
|
638
|
+
type Platform,
|
|
639
|
+
type DataSource,
|
|
640
|
+
type UtmParams,
|
|
641
|
+
type WebDataSourceConfig,
|
|
642
|
+
type NativeDataSourceConfig,
|
|
643
|
+
|
|
644
|
+
// Utilities
|
|
645
|
+
parseUtmParams,
|
|
646
|
+
detectSourceFromReferrer,
|
|
647
|
+
detectWebPlatform,
|
|
648
|
+
} from '@explorins/pers-sdk/core';
|
|
649
|
+
|
|
650
|
+
// React Native specific platform detection
|
|
651
|
+
export { detectReactNativePlatform } from './utils/platform-detection';
|
|
652
|
+
|
|
653
|
+
// ==============================================================================
|
|
654
|
+
// FIELD VALIDATION UTILITIES
|
|
655
|
+
// ==============================================================================
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Field validation utilities for custom fields and forms
|
|
659
|
+
*
|
|
660
|
+
* These functions are re-exported from @explorins/pers-shared for convenience.
|
|
661
|
+
* Use them for client-side validation before submitting data to the backend.
|
|
662
|
+
*
|
|
663
|
+
* @example
|
|
664
|
+
* **Single Field Validation:**
|
|
665
|
+
* ```typescript
|
|
666
|
+
* import { validateFieldValue, FieldType, FieldValidationRules } from '@explorins/pers-sdk-react-native';
|
|
667
|
+
*
|
|
668
|
+
* const rules: FieldValidationRules = { minLength: 3 };
|
|
669
|
+
* const error = validateFieldValue('ab', rules, 'text');
|
|
670
|
+
* // error: { message: 'Must be at least 3 characters' }
|
|
671
|
+
* ```
|
|
672
|
+
*
|
|
673
|
+
* @example
|
|
674
|
+
* **Form Validation:**
|
|
675
|
+
* ```typescript
|
|
676
|
+
* import { validateAllFields, FieldDefinition } from '@explorins/pers-sdk-react-native';
|
|
677
|
+
*
|
|
678
|
+
* const definitions: FieldDefinition[] = [
|
|
679
|
+
* { key: 'email', fieldType: 'email', label: 'Email', validation: { minLength: 1 } },
|
|
680
|
+
* { key: 'phone', fieldType: 'phone', label: 'Phone', validation: {} }
|
|
681
|
+
* ];
|
|
682
|
+
*
|
|
683
|
+
* const formData = { email: 'invalid', phone: '123' };
|
|
684
|
+
* const errors = validateAllFields(formData, definitions);
|
|
685
|
+
* // errors: [{ field: 'email', message: 'Invalid email format' }]
|
|
686
|
+
* ```
|
|
687
|
+
*
|
|
688
|
+
* @see {@link validateFieldValue} - Validate a single field value
|
|
689
|
+
* @see {@link validateAllFields} - Validate all fields against definitions
|
|
690
|
+
* @see {@link FieldDefinition} - Field definition structure
|
|
691
|
+
* @see {@link FieldValidationRules} - Available validation rules
|
|
692
|
+
*/
|
|
693
|
+
export {
|
|
694
|
+
validateFieldValue,
|
|
695
|
+
validateAllFields,
|
|
696
|
+
validateFieldComparisons,
|
|
697
|
+
compareValues,
|
|
698
|
+
type FieldDefinition,
|
|
699
|
+
type FieldValidationRules,
|
|
700
|
+
type ValidationErrorDetail,
|
|
701
|
+
type FieldType,
|
|
702
|
+
type FieldComparison,
|
|
703
|
+
type ComparisonOperator,
|
|
704
|
+
} from '@explorins/pers-sdk';
|
|
705
|
+
|
|
706
|
+
// ==============================================================================
|
|
707
|
+
// BOOKING STATUS VALIDATION
|
|
708
|
+
// ==============================================================================
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* Booking status types and validation utilities for eligibility checks
|
|
712
|
+
*
|
|
713
|
+
* Use these to validate if a user's booking status meets requirements
|
|
714
|
+
* for redemptions, campaigns, or other booking-dependent features.
|
|
715
|
+
*
|
|
716
|
+
* **BookingStatus:** 'past' | 'active' | 'future'
|
|
717
|
+
* - `past`: User's stay has ended (checkOut ≤ now)
|
|
718
|
+
* - `active`: User is currently staying (checkIn ≤ now < checkOut)
|
|
719
|
+
* - `future`: Upcoming booking (checkIn > now)
|
|
720
|
+
*
|
|
721
|
+
* **BookingRequirementType:** 'active' | 'future' | 'past' | 'active_future' | 'any'
|
|
722
|
+
* - `active`: Only active bookings allowed
|
|
723
|
+
* - `future`: Only future bookings allowed
|
|
724
|
+
* - `past`: Only past bookings allowed
|
|
725
|
+
* - `active_future`: Active OR future bookings allowed
|
|
726
|
+
* - `any`: Any booking status allowed
|
|
727
|
+
*
|
|
728
|
+
* @example
|
|
729
|
+
* **Basic Validation:**
|
|
730
|
+
* ```typescript
|
|
731
|
+
* import {
|
|
732
|
+
* isBookingStatusValid,
|
|
733
|
+
* BookingStatus,
|
|
734
|
+
* BookingRequirementType
|
|
735
|
+
* } from '@explorins/pers-sdk-react-native';
|
|
736
|
+
*
|
|
737
|
+
* const userBookingStatus: BookingStatus = booking.status;
|
|
738
|
+
* const requirement: BookingRequirementType = redemption.bookingRequirement;
|
|
739
|
+
* const canRedeem = isBookingStatusValid(userBookingStatus, requirement);
|
|
740
|
+
* ```
|
|
741
|
+
*
|
|
742
|
+
* @example
|
|
743
|
+
* **Redemption Screen:**
|
|
744
|
+
* ```typescript
|
|
745
|
+
* function RedemptionCard({ redemption, userBooking }) {
|
|
746
|
+
* const isEligible = redemption.bookingRequirement
|
|
747
|
+
* ? isBookingStatusValid(userBooking?.status ?? 'past', redemption.bookingRequirement)
|
|
748
|
+
* : true;
|
|
749
|
+
*
|
|
750
|
+
* return (
|
|
751
|
+
* <View style={[styles.card, !isEligible && styles.disabled]}>
|
|
752
|
+
* <Text>{redemption.name}</Text>
|
|
753
|
+
* {!isEligible && (
|
|
754
|
+
* <Text style={styles.warning}>
|
|
755
|
+
* Requires {redemption.bookingRequirement} booking
|
|
756
|
+
* </Text>
|
|
757
|
+
* )}
|
|
758
|
+
* </View>
|
|
759
|
+
* );
|
|
760
|
+
* }
|
|
761
|
+
* ```
|
|
762
|
+
*
|
|
763
|
+
* @example
|
|
764
|
+
* **Validation Results:**
|
|
765
|
+
* ```typescript
|
|
766
|
+
* isBookingStatusValid('active', 'active'); // true
|
|
767
|
+
* isBookingStatusValid('future', 'active'); // false
|
|
768
|
+
* isBookingStatusValid('active', 'active_future'); // true
|
|
769
|
+
* isBookingStatusValid('future', 'active_future'); // true
|
|
770
|
+
* isBookingStatusValid('past', 'active_future'); // false
|
|
771
|
+
* isBookingStatusValid('past', 'any'); // true
|
|
772
|
+
* ```
|
|
773
|
+
*/
|
|
774
|
+
export {
|
|
775
|
+
isBookingStatusValid,
|
|
776
|
+
type BookingStatus,
|
|
777
|
+
type BookingRequirementType
|
|
778
778
|
} from '@explorins/pers-sdk';
|