@explorins/pers-sdk-react-native 1.5.17 → 1.5.20

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 (40) hide show
  1. package/README.md +336 -234
  2. package/dist/hooks/index.d.ts +1 -1
  3. package/dist/hooks/index.d.ts.map +1 -1
  4. package/dist/hooks/useAuth.d.ts +1 -1
  5. package/dist/hooks/useAuth.d.ts.map +1 -1
  6. package/dist/hooks/useAuth.js +7 -7
  7. package/dist/hooks/useRedemptions.d.ts.map +1 -1
  8. package/dist/hooks/useRedemptions.js +4 -4
  9. package/dist/hooks/useTenants.d.ts.map +1 -1
  10. package/dist/hooks/useTenants.js +0 -1
  11. package/dist/hooks/useTransactionSigner.d.ts +186 -53
  12. package/dist/hooks/useTransactionSigner.d.ts.map +1 -1
  13. package/dist/hooks/useTransactionSigner.js +285 -102
  14. package/dist/hooks/useTransactions.d.ts +2 -2
  15. package/dist/hooks/useTransactions.d.ts.map +1 -1
  16. package/dist/hooks/useTransactions.js +38 -9
  17. package/dist/index.d.ts +211 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +21154 -18543
  20. package/dist/index.js.map +1 -1
  21. package/dist/providers/PersSDKProvider.d.ts +2 -8
  22. package/dist/providers/PersSDKProvider.d.ts.map +1 -1
  23. package/dist/providers/PersSDKProvider.js +16 -31
  24. package/dist/providers/react-native-auth-provider.d.ts +25 -36
  25. package/dist/providers/react-native-auth-provider.d.ts.map +1 -1
  26. package/dist/providers/react-native-auth-provider.js +36 -146
  27. package/dist/storage/async-storage-token-storage.d.ts +22 -0
  28. package/dist/storage/async-storage-token-storage.d.ts.map +1 -0
  29. package/dist/storage/async-storage-token-storage.js +113 -0
  30. package/package.json +16 -11
  31. package/src/hooks/index.ts +1 -1
  32. package/src/hooks/useAuth.ts +7 -7
  33. package/src/hooks/useRedemptions.ts +5 -7
  34. package/src/hooks/useTenants.ts +0 -1
  35. package/src/hooks/useTransactionSigner.ts +322 -166
  36. package/src/hooks/useTransactions.ts +44 -11
  37. package/src/index.ts +243 -7
  38. package/src/providers/PersSDKProvider.tsx +21 -40
  39. package/src/providers/react-native-auth-provider.ts +59 -176
  40. package/src/storage/async-storage-token-storage.ts +133 -0
@@ -1,9 +1,11 @@
1
1
  import { useCallback } from 'react';
2
2
  import { usePersSDK } from '../providers/PersSDKProvider';
3
+ import { useTransactionSigner } from './useTransactionSigner';
3
4
  import type {
4
5
  TransactionRequestDTO,
5
6
  TransactionRequestResponseDTO,
6
- TransactionDTO
7
+ TransactionDTO,
8
+ TransactionRole
7
9
  } from '@explorins/pers-shared';
8
10
  import type { TransactionPaginationParams } from '@explorins/pers-sdk/transaction';
9
11
 
@@ -45,6 +47,7 @@ import type { TransactionPaginationParams } from '@explorins/pers-sdk/transactio
45
47
  */
46
48
  export const useTransactions = () => {
47
49
  const { sdk, isInitialized, isAuthenticated } = usePersSDK();
50
+ const { signAndSubmitTransactionWithJWT, isSignerAvailable } = useTransactionSigner();
48
51
 
49
52
  if (!isAuthenticated && isInitialized) {
50
53
  console.warn('SDK not authenticated. Some transaction operations may fail.');
@@ -80,15 +83,45 @@ export const useTransactions = () => {
80
83
  try {
81
84
  const result = await sdk.transactions.createTransaction(request);
82
85
 
83
- // Cross-platform: Dont handle signature URLs here, leave to caller
84
-
85
86
  console.log('Transaction created successfully:', result);
87
+
88
+ // Check if transaction requires signing (contains actionable authToken)
89
+ // Type assertion needed as TransactionRequestResponseDTO type may not include all dynamic properties
90
+ const txToken = result?.actionable?.authToken;
91
+ if (txToken) {
92
+ console.log('[useTransactions] Transaction requires signing, attempting automatic signature...');
93
+
94
+ try {
95
+ if (!isSignerAvailable) {
96
+ console.warn('[useTransactions] Transaction signer not available, skipping automatic signing');
97
+ return result;
98
+ }
99
+
100
+ // Automatically sign the transaction using the authToken
101
+ const signingResult = await signAndSubmitTransactionWithJWT(txToken);
102
+
103
+ if (signingResult.success) {
104
+ console.log('[useTransactions] Transaction signed successfully:', signingResult.transactionHash);
105
+ // Return the original result - the transaction is now signed and will be processed
106
+ return result;
107
+ } else {
108
+ console.error('[useTransactions] Transaction signing failed:', signingResult.error);
109
+ // Don't throw error - return the original result so caller can handle signature URL manually
110
+ return result;
111
+ }
112
+ } catch (signingError) {
113
+ console.error('[useTransactions] Blockchain signing error:', signingError);
114
+ // Don't throw error - return the original result so caller can handle signature URL manually
115
+ return result;
116
+ }
117
+ }
118
+
86
119
  return result;
87
120
  } catch (error) {
88
121
  console.error('Failed to create transaction:', error);
89
122
  throw error;
90
123
  }
91
- }, [sdk, isInitialized]);
124
+ }, [sdk, isInitialized, signAndSubmitTransactionWithJWT, isSignerAvailable]);
92
125
 
93
126
  /**
94
127
  * Retrieves a specific transaction by its ID
@@ -120,26 +153,27 @@ export const useTransactions = () => {
120
153
  }, [sdk, isInitialized]);
121
154
 
122
155
  /**
123
- * Retrieves transaction history for the authenticated user, filtered by type
156
+ * Retrieves transaction history for the authenticated user, filtered by role
124
157
  *
125
- * @param type - Transaction type filter (defaults to 'all')
158
+ * @param role - Optional transaction role filter (TransactionRole.SENDER, TransactionRole.RECIPIENT)
126
159
  * @returns Promise resolving to array of user's transactions
127
160
  * @throws Error if SDK is not initialized
128
161
  *
129
162
  * @example
130
163
  * ```typescript
131
164
  * const { getUserTransactionHistory } = useTransactions();
132
- * const transactions = await getUserTransactionHistory('credit');
133
- * console.log('Credit transactions:', transactions);
165
+ * const sentTransactions = await getUserTransactionHistory(TransactionRole.SENDER);
166
+ * const allTransactions = await getUserTransactionHistory(); // No filter
134
167
  * ```
135
168
  */
136
- const getUserTransactionHistory = useCallback(async (type: string = 'all'): Promise<TransactionDTO[]> => {
169
+ const getUserTransactionHistory = useCallback(async (role?: TransactionRole): Promise<TransactionDTO[]> => {
170
+
137
171
  if (!isInitialized || !sdk) {
138
172
  throw new Error('SDK not initialized. Call initialize() first.');
139
173
  }
140
174
 
141
175
  try {
142
- const result = await sdk.transactions.getUserTransactionHistory(type);
176
+ const result = await sdk.transactions.getUserTransactionHistory(role);
143
177
  console.log('Transaction history fetched successfully:', result);
144
178
  return result;
145
179
  } catch (error) {
@@ -155,7 +189,6 @@ export const useTransactions = () => {
155
189
 
156
190
  try {
157
191
  const result = await sdk.transactions.getTenantTransactions();
158
- console.log('Tenant transactions fetched successfully:', result);
159
192
  return result;
160
193
  } catch (error) {
161
194
  console.error('Failed to fetch tenant transactions:', error);
package/src/index.ts CHANGED
@@ -1,13 +1,123 @@
1
+ /**
2
+ * @fileoverview PERS SDK for React Native - Tourism Loyalty System
3
+ *
4
+ * A comprehensive React Native SDK for integrating with the PERS (Phygital Experience Rewards System)
5
+ * platform. Provides complete functionality for tourism loyalty applications including user management,
6
+ * token operations, business integrations, campaign management, and blockchain transaction signing.
7
+ *
8
+ * **Key Features:**
9
+ * - Secure authentication with React Native Keychain integration
10
+ * - Token management (earn, redeem, transfer, balance checking)
11
+ * - Business and campaign management
12
+ * - Blockchain transaction signing with WebAuthn
13
+ * - React Native optimized with automatic polyfills
14
+ * - Type-safe interfaces with comprehensive TypeScript support
15
+ * - Analytics and reporting capabilities
16
+ * - Donation and charitable giving features
17
+ *
18
+ * @example
19
+ * **Quick Start:**
20
+ * ```typescript
21
+ * import { PersSDKProvider, usePersSDK, useTransactionSigner } from '@explorins/pers-sdk-react-native';
22
+ *
23
+ * // 1. Wrap your app with the provider
24
+ * function App() {
25
+ * return (
26
+ * <PersSDKProvider config={{ apiUrl: 'https://api.pers.ninja' }}>
27
+ * <YourApp />
28
+ * </PersSDKProvider>
29
+ * );
30
+ * }
31
+ *
32
+ * // 2. Use hooks in your components
33
+ * function RewardScreen() {
34
+ * const { user, isAuthenticated, earnTokens } = usePersSDK();
35
+ * const { signAndSubmitTransactionWithJWT } = useTransactionSigner();
36
+ *
37
+ * // Your reward logic here...
38
+ * }
39
+ * ```
40
+ *
41
+ * @version 1.5.19
42
+ * @author eXplorins
43
+ * @license MIT
44
+ */
45
+
1
46
  // Initialize React Native polyfills automatically
2
47
  import './polyfills';
3
48
 
4
- // Export React Native specific providers (FIRST - break circular dependency)
49
+ // ==============================================================================
50
+ // AUTHENTICATION PROVIDERS
51
+ // ==============================================================================
52
+
53
+ /**
54
+ * React Native-specific authentication provider with secure keychain integration
55
+ *
56
+ * Provides secure token storage using React Native Keychain, biometric authentication,
57
+ * and automatic token refresh capabilities.
58
+ *
59
+ * @see {@link createReactNativeAuthProvider} - Factory function for auth provider
60
+ * @see {@link ReactNativeAuthConfig} - Configuration interface
61
+ */
5
62
  export {
6
- ReactNativeAuthProvider,
63
+ createReactNativeAuthProvider,
7
64
  type ReactNativeAuthConfig
8
65
  } from './providers/react-native-auth-provider';
9
66
 
10
- // Export Provider and Context directly (avoid circular import through hooks)
67
+ // ==============================================================================
68
+ // SECURE STORAGE
69
+ // ==============================================================================
70
+
71
+ /**
72
+ * Secure token storage using React Native AsyncStorage
73
+ *
74
+ * Provides encrypted token storage with automatic cleanup and secure key management.
75
+ * Integrates with React Native Keychain for enhanced security on supported devices.
76
+ *
77
+ * @see {@link AsyncStorageTokenStorage} - Secure storage implementation
78
+ */
79
+ export {
80
+ AsyncStorageTokenStorage,
81
+ } from './storage/async-storage-token-storage';
82
+
83
+ // ==============================================================================
84
+ // CORE PROVIDER & CONTEXT
85
+ // ==============================================================================
86
+
87
+ /**
88
+ * Main PERS SDK provider and context for React Native applications
89
+ *
90
+ * The PersSDKProvider should wrap your entire app to provide PERS functionality
91
+ * throughout your component tree. Use usePersSDK hook to access SDK features.
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * import { PersSDKProvider, usePersSDK } from '@explorins/pers-sdk-react-native';
96
+ *
97
+ * function App() {
98
+ * return (
99
+ * <PersSDKProvider config={{
100
+ * apiUrl: 'https://api.pers.ninja',
101
+ * tenantId: 'your-tenant-id'
102
+ * }}>
103
+ * <NavigationContainer>
104
+ * <YourAppContent />
105
+ * </NavigationContainer>
106
+ * </PersSDKProvider>
107
+ * );
108
+ * }
109
+ *
110
+ * function YourComponent() {
111
+ * const { user, isAuthenticated, earnTokens } = usePersSDK();
112
+ * // Use PERS functionality here...
113
+ * }
114
+ * ```
115
+ *
116
+ * @see {@link PersSDKProvider} - Main provider component
117
+ * @see {@link usePersSDK} - Hook to access SDK functionality
118
+ * @see {@link PersConfig} - Provider configuration interface
119
+ * @see {@link PersSDKContext} - Context type definition
120
+ */
11
121
  export {
12
122
  PersSDKProvider,
13
123
  usePersSDK,
@@ -15,7 +125,80 @@ export {
15
125
  type PersSDKContext
16
126
  } from './providers/PersSDKProvider';
17
127
 
18
- // Export hooks (Primary Interface)
128
+ // ==============================================================================
129
+ // REACT HOOKS (Primary Interface)
130
+ // ==============================================================================
131
+
132
+ /**
133
+ * Comprehensive React hooks for PERS platform integration
134
+ *
135
+ * These hooks provide the primary interface for interacting with the PERS platform
136
+ * in React Native applications. Each hook is optimized for specific functionality
137
+ * and includes automatic error handling, loading states, and real-time updates.
138
+ *
139
+ * **Authentication & User Management:**
140
+ * - `useAuth` - User authentication, login, logout, registration
141
+ * - `useUsers` - User profile management and data operations
142
+ * - `useUserStatus` - Real-time user status and activity monitoring
143
+ *
144
+ * **Token & Financial Operations:**
145
+ * - `useTokens` - Token balance, earning, and management
146
+ * - `useTransactions` - Transaction history and monitoring
147
+ * - `useTransactionSigner` - **⭐ Blockchain transaction signing**
148
+ * - `usePurchases` - Purchase history and payment processing
149
+ * - `useDonations` - Charitable giving and donation management
150
+ *
151
+ * **Business & Campaign Management:**
152
+ * - `useBusiness` - Business profile and operations
153
+ * - `useCampaigns` - Marketing campaigns and promotions
154
+ * - `useRedemptions` - Reward redemption and fulfillment
155
+ *
156
+ * **Platform & Analytics:**
157
+ * - `useTenants` - Multi-tenant configuration and management
158
+ * - `useAnalytics` - Usage analytics and reporting
159
+ * - `useFiles` - File upload and management
160
+ * - `useWeb3` - Blockchain integration and wallet operations
161
+ *
162
+ * @example
163
+ * **Token Operations:**
164
+ * ```typescript
165
+ * import { useTokens, useTransactionSigner } from '@explorins/pers-sdk-react-native';
166
+ *
167
+ * function TokenScreen() {
168
+ * const { balance, earnTokens, redeemTokens } = useTokens();
169
+ * const { signAndSubmitTransactionWithJWT } = useTransactionSigner();
170
+ *
171
+ * const handleEarn = async (amount: number) => {
172
+ * const result = await earnTokens({ amount, source: 'reward' });
173
+ * console.log('Earned tokens:', result);
174
+ * };
175
+ *
176
+ * const handleRedeem = async (amount: number) => {
177
+ * const redemption = await redeemTokens({ amount });
178
+ * const txResult = await signAndSubmitTransactionWithJWT(redemption.jwtToken);
179
+ * console.log('Redemption completed:', txResult.transactionHash);
180
+ * };
181
+ * }
182
+ * ```
183
+ *
184
+ * @example
185
+ * **Campaign Integration:**
186
+ * ```typescript
187
+ * import { useCampaigns, useAuth } from '@explorins/pers-sdk-react-native';
188
+ *
189
+ * function CampaignScreen() {
190
+ * const { activeCampaigns, participateInCampaign } = useCampaigns();
191
+ * const { user } = useAuth();
192
+ *
193
+ * const handleParticipate = async (campaignId: string) => {
194
+ * const result = await participateInCampaign(campaignId, {
195
+ * userId: user?.id,
196
+ * participationData: { source: 'mobile_app' }
197
+ * });
198
+ * };
199
+ * }
200
+ * ```
201
+ */
19
202
  export {
20
203
  useAuth,
21
204
  useTokens,
@@ -34,19 +217,72 @@ export {
34
217
  useDonations
35
218
  } from './hooks';
36
219
 
220
+ // ==============================================================================
221
+ // PLATFORM ADAPTERS
222
+ // ==============================================================================
223
+
224
+ /**
225
+ * React Native-optimized HTTP client with automatic request/response handling
226
+ *
227
+ * Provides platform-specific networking with proper error handling, timeout management,
228
+ * and React Native compatibility. Automatically handles headers, authentication tokens,
229
+ * and response parsing.
230
+ */
37
231
  export {
38
232
  ReactNativeHttpClient
39
233
  } from './providers/react-native-http-client';
40
234
 
41
- // Export polyfill utilities for advanced usage
235
+ // ==============================================================================
236
+ // POLYFILLS & COMPATIBILITY
237
+ // ==============================================================================
238
+
239
+ /**
240
+ * React Native polyfill utilities for web compatibility
241
+ *
242
+ * Automatically initializes required polyfills for crypto, URL, and other web APIs
243
+ * that may not be available in React Native environments. These are typically
244
+ * loaded automatically, but manual initialization is available for advanced use cases.
245
+ *
246
+ * @see {@link initializeReactNativePolyfills} - Manual polyfill initialization
247
+ */
42
248
  export {
43
249
  initializeReactNativePolyfills
44
250
  } from './polyfills';
45
251
 
46
- // Re-export all types and utilities from @explorins/pers-shared
252
+ // ==============================================================================
253
+ // TYPE DEFINITIONS & SHARED UTILITIES
254
+ // ==============================================================================
255
+
256
+ /**
257
+ * Re-export all types and utilities from the shared PERS library
258
+ *
259
+ * This includes all core types, DTOs, enums, and utility functions used across
260
+ * the PERS platform. These types ensure consistency between different SDK versions
261
+ * and platform implementations.
262
+ *
263
+ * **Included Types:**
264
+ * - User and authentication types (UserDTO, AuthenticationResult, etc.)
265
+ * - Token and transaction types (TokenDTO, TransactionDTO, etc.)
266
+ * - Business and campaign types (BusinessDTO, CampaignDTO, etc.)
267
+ * - API request/response types for all endpoints
268
+ * - Error types and status enums
269
+ *
270
+ * @see {@link https://github.com/eXplorins/pers-shared} - Shared library documentation
271
+ */
47
272
  export * from '@explorins/pers-shared';
48
273
 
49
- // Re-export Web3 types from base SDK
274
+ /**
275
+ * Re-export Web3 and blockchain-related types from base SDK
276
+ *
277
+ * Provides TypeScript definitions for Web3 operations, token management,
278
+ * and blockchain interactions. These types are used by the transaction
279
+ * signing hooks and Web3 integration features.
280
+ *
281
+ * @see {@link TokenBalanceRequest} - Request structure for token balance queries
282
+ * @see {@link TokenBalance} - Token balance response data
283
+ * @see {@link TokenMetadata} - Token metadata and details
284
+ * @see {@link TokenCollection} - Collection of tokens for batch operations
285
+ */
50
286
  export type {
51
287
  TokenBalanceRequest,
52
288
  TokenBalance,
@@ -1,7 +1,7 @@
1
1
  import React, { createContext, useContext, useState, ReactNode, useCallback, useRef } from 'react';
2
- import { PersSDK, PersConfig, createAuthProvider } from '@explorins/pers-sdk/core';
2
+ import { PersSDK, PersConfig, DefaultAuthProvider } from '@explorins/pers-sdk/core';
3
3
  import { ReactNativeHttpClient } from './react-native-http-client';
4
- import { ReactNativeAuthProvider } from './react-native-auth-provider';
4
+ import { createReactNativeAuthProvider } from './react-native-auth-provider';
5
5
  import { UserDTO, AdminDTO } from '@explorins/pers-shared';
6
6
 
7
7
  // Import manager types for TypeScript
@@ -42,8 +42,8 @@ export interface PersSDKContext {
42
42
  // Legacy support (deprecated but kept for backward compatibility)
43
43
  business: BusinessManager | null;
44
44
 
45
- // Platform-specific providers
46
- authProvider: ReactNativeSDKAuthProvider | null;
45
+ // Platform-specific providers - now uses unified auth provider
46
+ authProvider: DefaultAuthProvider | null;
47
47
 
48
48
  // State
49
49
  isInitialized: boolean;
@@ -60,34 +60,13 @@ export interface PersSDKContext {
60
60
  // Create the context
61
61
  const SDKContext = createContext<PersSDKContext | null>(null);
62
62
 
63
- // Simple wrapper for SDK integration
64
- class ReactNativeSDKAuthProvider extends ReactNativeAuthProvider {
65
- constructor(projectKey: string) {
66
- super(projectKey, { debug: true });
67
- }
68
-
69
- // Override setAccessToken to provide backward compatibility
70
- async setToken(token: string | null): Promise<void> {
71
- if (token) {
72
- await this.setAccessToken(token);
73
- } else {
74
- await this.clearTokens();
75
- }
76
- }
77
-
78
- // Override getToken for backward compatibility
79
- async getToken(): Promise<string | null> {
80
- return await super.getToken();
81
- }
82
- }
83
-
84
63
  // Provider component
85
64
  export const PersSDKProvider: React.FC<{
86
65
  children: ReactNode;
87
66
  }> = ({ children }) => {
88
67
  const initializingRef = useRef(false);
89
68
  const [sdk, setSdk] = useState<PersSDK | null>(null);
90
- const [authProvider, setAuthProvider] = useState<ReactNativeSDKAuthProvider | null>(null);
69
+ const [authProvider, setAuthProvider] = useState<DefaultAuthProvider | null>(null);
91
70
 
92
71
  const [isInitialized, setIsInitialized] = useState(false);
93
72
  const [isAuthenticated, setIsAuthenticated] = useState(false);
@@ -97,34 +76,38 @@ export const PersSDKProvider: React.FC<{
97
76
  const initialize = useCallback(async (config: PersConfig) => {
98
77
  // Prevent multiple initializations
99
78
  if (isInitialized || initializingRef.current) {
100
- console.log('SDK already initialized or initializing, skipping...');
101
79
  return;
102
80
  }
103
81
 
104
82
  initializingRef.current = true;
105
83
 
106
84
  try {
107
- console.log('Initializing PERS SDK with config:', config);
108
-
109
- // Create React Native auth provider
110
- const auth = new ReactNativeSDKAuthProvider(config.apiProjectKey || 'default-project');
111
- setAuthProvider(auth);
112
-
113
85
  // Create HTTP client
114
86
  const httpClient = new ReactNativeHttpClient();
115
87
 
116
- // Create config with auth provider - use the ReactNative auth provider directly
88
+ // Create platform-aware auth provider if not provided
89
+ let authProvider: DefaultAuthProvider;
90
+ if (config.authProvider) {
91
+ authProvider = config.authProvider as DefaultAuthProvider;
92
+ } else {
93
+ // Use our platform-aware auth provider that automatically selects LocalStorage (web) or AsyncStorage (mobile)
94
+ authProvider = createReactNativeAuthProvider(config.apiProjectKey || 'default-project', {
95
+ debug: false
96
+ });
97
+ }
98
+
99
+ // Enhanced config with platform-appropriate auth provider
117
100
  const sdkConfig: PersConfig = {
118
101
  ...config,
119
- authProvider: auth
102
+ authProvider
120
103
  };
121
104
 
122
- // Initialize PersSDK with manager pattern
105
+ // Initialize PersSDK with platform-aware auth provider
123
106
  const sdkInstance = new PersSDK(httpClient, sdkConfig);
107
+
108
+ setAuthProvider(authProvider);
124
109
  setSdk(sdkInstance);
125
110
  setIsInitialized(true);
126
-
127
- console.log('PERS SDK initialized successfully');
128
111
  } catch (error) {
129
112
  console.error('Failed to initialize PERS SDK:', error);
130
113
  initializingRef.current = false;
@@ -146,10 +129,8 @@ export const PersSDKProvider: React.FC<{
146
129
  }
147
130
 
148
131
  try {
149
- console.log('Refreshing user data from remote server...');
150
132
  const freshUserData = await sdk.users.getCurrentUser();
151
133
  setUser(freshUserData);
152
- console.log('User data refreshed successfully:', freshUserData);
153
134
  } catch (error) {
154
135
  console.error('Failed to refresh user data:', error);
155
136
  throw error;