@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.
Files changed (58) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1266 -1244
  3. package/dist/__tests__/PersSDKProvider.test.js +33 -0
  4. package/dist/hooks/useBusiness.d.ts +2 -2
  5. package/dist/hooks/useBusiness.d.ts.map +1 -1
  6. package/dist/hooks/useBusiness.js +2 -2
  7. package/dist/hooks/useIPFSUrl.d.ts +3 -3
  8. package/dist/hooks/useIPFSUrl.d.ts.map +1 -1
  9. package/dist/hooks/useIPFSUrl.js +7 -7
  10. package/dist/hooks/useWeb3.js +4 -4
  11. package/dist/index.js +2400 -487
  12. package/dist/index.js.map +1 -1
  13. package/dist/providers/PersSDKProvider.d.ts +4 -0
  14. package/dist/providers/PersSDKProvider.d.ts.map +1 -1
  15. package/dist/providers/PersSDKProvider.js +14 -0
  16. package/dist/providers/react-native-http-client.d.ts +2 -0
  17. package/dist/providers/react-native-http-client.d.ts.map +1 -1
  18. package/dist/providers/react-native-http-client.js +5 -2
  19. package/dist/storage/rn-secure-storage.d.ts.map +1 -1
  20. package/dist/storage/rn-secure-storage.js +21 -8
  21. package/package.json +3 -3
  22. package/src/__tests__/PersSDKProvider.test.tsx +484 -420
  23. package/src/__tests__/setup.ts +40 -40
  24. package/src/hooks/index.ts +60 -60
  25. package/src/hooks/useAnalytics.ts +327 -327
  26. package/src/hooks/useAuth.ts +265 -265
  27. package/src/hooks/useBookings.ts +191 -191
  28. package/src/hooks/useBusiness.ts +251 -251
  29. package/src/hooks/useCampaigns.ts +500 -500
  30. package/src/hooks/useDonations.ts +66 -66
  31. package/src/hooks/useEvents.ts +372 -372
  32. package/src/hooks/useFiles.ts +155 -155
  33. package/src/hooks/useIPFSUrl.ts +192 -192
  34. package/src/hooks/usePurchases.ts +65 -65
  35. package/src/hooks/useRedemptions.ts +467 -467
  36. package/src/hooks/useTenants.ts +72 -72
  37. package/src/hooks/useTokenBalances.ts +385 -385
  38. package/src/hooks/useTokens.ts +313 -313
  39. package/src/hooks/useTransactionSigner.ts +611 -611
  40. package/src/hooks/useTransactions.ts +299 -299
  41. package/src/hooks/useTriggerSources.ts +301 -301
  42. package/src/hooks/useUserStatus.ts +61 -61
  43. package/src/hooks/useUsers.ts +167 -167
  44. package/src/hooks/useWeb3.ts +355 -355
  45. package/src/index.ts +777 -777
  46. package/src/polyfills/index.ts +160 -160
  47. package/src/polyfills/web3-polyfills.ts +97 -97
  48. package/src/providers/PersSDKProvider.tsx +393 -374
  49. package/src/providers/react-native-auth-provider.ts +110 -110
  50. package/src/providers/react-native-http-client.ts +150 -145
  51. package/src/providers/rn-dpop-provider.ts +190 -190
  52. package/src/storage/async-storage-token-storage.ts +185 -185
  53. package/src/storage/rn-secure-storage.ts +182 -170
  54. package/src/types/react-native-globals.d.ts +45 -45
  55. package/src/utils/index.ts +8 -8
  56. package/src/utils/platform-detection.ts +86 -86
  57. package/dist/index-CzLxqePZ.js +0 -7717
  58. 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';