@explorins/pers-sdk-react-native 1.3.2 → 1.5.2

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 (94) hide show
  1. package/README.md +276 -123
  2. package/dist/hooks/index.d.ts +10 -0
  3. package/dist/hooks/index.d.ts.map +1 -1
  4. package/dist/hooks/index.js +8 -0
  5. package/dist/hooks/useAnalytics.d.ts +96 -0
  6. package/dist/hooks/useAnalytics.d.ts.map +1 -0
  7. package/dist/hooks/useAnalytics.js +73 -0
  8. package/dist/hooks/useAuth.d.ts +52 -7
  9. package/dist/hooks/useAuth.d.ts.map +1 -1
  10. package/dist/hooks/useAuth.js +250 -3
  11. package/dist/hooks/useBusiness.d.ts +45 -3
  12. package/dist/hooks/useBusiness.d.ts.map +1 -1
  13. package/dist/hooks/useBusiness.js +182 -28
  14. package/dist/hooks/useCampaigns.d.ts +11 -4
  15. package/dist/hooks/useCampaigns.d.ts.map +1 -1
  16. package/dist/hooks/useCampaigns.js +101 -39
  17. package/dist/hooks/useDonations.d.ts +33 -0
  18. package/dist/hooks/useDonations.d.ts.map +1 -0
  19. package/dist/hooks/useDonations.js +62 -0
  20. package/dist/hooks/useFiles.d.ts +50 -0
  21. package/dist/hooks/useFiles.d.ts.map +1 -0
  22. package/dist/hooks/useFiles.js +140 -0
  23. package/dist/hooks/usePurchases.d.ts +9 -0
  24. package/dist/hooks/usePurchases.d.ts.map +1 -0
  25. package/dist/hooks/usePurchases.js +56 -0
  26. package/dist/hooks/useRedemptions.d.ts +10 -5
  27. package/dist/hooks/useRedemptions.d.ts.map +1 -1
  28. package/dist/hooks/useRedemptions.js +118 -66
  29. package/dist/hooks/useTenants.d.ts +10 -0
  30. package/dist/hooks/useTenants.d.ts.map +1 -0
  31. package/dist/hooks/useTenants.js +68 -0
  32. package/dist/hooks/useTokens.d.ts +36 -2
  33. package/dist/hooks/useTokens.d.ts.map +1 -1
  34. package/dist/hooks/useTokens.js +180 -19
  35. package/dist/hooks/useTransactionSigner.d.ts +73 -0
  36. package/dist/hooks/useTransactionSigner.d.ts.map +1 -0
  37. package/dist/hooks/useTransactionSigner.js +216 -0
  38. package/dist/hooks/useTransactions.d.ts +45 -3
  39. package/dist/hooks/useTransactions.d.ts.map +1 -1
  40. package/dist/hooks/useTransactions.js +149 -39
  41. package/dist/hooks/useUserStatus.d.ts +9 -0
  42. package/dist/hooks/useUserStatus.d.ts.map +1 -0
  43. package/dist/hooks/useUserStatus.js +57 -0
  44. package/dist/hooks/useUsers.d.ts +17 -0
  45. package/dist/hooks/useUsers.d.ts.map +1 -0
  46. package/dist/hooks/useUsers.js +120 -0
  47. package/dist/hooks/useWeb3.d.ts +69 -6
  48. package/dist/hooks/useWeb3.d.ts.map +1 -1
  49. package/dist/hooks/useWeb3.js +177 -17
  50. package/dist/index.d.ts +6 -4
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +31540 -794
  53. package/dist/index.js.map +1 -1
  54. package/dist/polyfills/index.d.ts +1 -1
  55. package/dist/polyfills/index.d.ts.map +1 -1
  56. package/dist/polyfills/index.js +155 -9
  57. package/dist/polyfills/web3-polyfills.d.ts +7 -0
  58. package/dist/polyfills/web3-polyfills.d.ts.map +1 -0
  59. package/dist/polyfills/web3-polyfills.js +85 -0
  60. package/dist/providers/PersSDKProvider.d.ts +28 -18
  61. package/dist/providers/PersSDKProvider.d.ts.map +1 -1
  62. package/dist/providers/PersSDKProvider.js +63 -129
  63. package/dist/providers/react-native-auth-provider.d.ts +19 -64
  64. package/dist/providers/react-native-auth-provider.d.ts.map +1 -1
  65. package/dist/providers/react-native-auth-provider.js +57 -175
  66. package/package.json +177 -157
  67. package/src/hooks/index.ts +13 -1
  68. package/src/hooks/useAnalytics.ts +150 -0
  69. package/src/hooks/useAuth.ts +286 -27
  70. package/src/hooks/useBusiness.ts +193 -30
  71. package/src/hooks/useCampaigns.ts +121 -43
  72. package/src/hooks/useDonations.ts +68 -0
  73. package/src/hooks/useFiles.ts +160 -0
  74. package/src/hooks/usePurchases.ts +69 -0
  75. package/src/hooks/useRedemptions.ts +135 -68
  76. package/src/hooks/useTenants.ts +77 -0
  77. package/src/hooks/useTokens.ts +189 -21
  78. package/src/hooks/useTransactionSigner.ts +287 -0
  79. package/src/hooks/useTransactions.ts +163 -41
  80. package/src/hooks/useUserStatus.ts +65 -0
  81. package/src/hooks/useUsers.ts +133 -0
  82. package/src/hooks/useWeb3.ts +201 -21
  83. package/src/index.ts +22 -17
  84. package/src/polyfills/index.ts +163 -10
  85. package/src/polyfills/web3-polyfills.ts +98 -0
  86. package/src/providers/PersSDKProvider.tsx +114 -178
  87. package/src/providers/react-native-auth-provider.ts +65 -208
  88. package/dist/index.esm.js +0 -1057
  89. package/dist/index.esm.js.map +0 -1
  90. package/dist/polyfills/index.simple.d.ts +0 -2
  91. package/dist/polyfills/index.simple.d.ts.map +0 -1
  92. package/dist/polyfills/index.simple.js +0 -17
  93. package/src/polyfills/index.simple.ts +0 -22
  94. package/src/types/external-modules.d.ts +0 -13
package/dist/index.esm.js DELETED
@@ -1,1057 +0,0 @@
1
- import AsyncStorage from '@react-native-async-storage/async-storage';
2
- import { jsx } from 'react/jsx-runtime';
3
- import { createContext, useRef, useState, useCallback, useContext } from 'react';
4
- import { PersApiClient } from '@explorins/pers-sdk/core';
5
- import { TokenSDK } from '@explorins/pers-sdk/token';
6
- import { createTransactionSDK } from '@explorins/pers-sdk/transaction';
7
- import { createBusinessSDK } from '@explorins/pers-sdk/business';
8
- import { createCampaignSDK } from '@explorins/pers-sdk/campaign';
9
- import { createRedemptionSDK } from '@explorins/pers-sdk/redemption';
10
- import { createWeb3SDK } from '@explorins/pers-sdk/web3';
11
-
12
- // Minimal React Native environment setup
13
- // No polyfills needed - modules are disabled at Metro level
14
- // Simple initialization function for compatibility
15
- const initializeReactNativePolyfills = () => {
16
- console.log('✅ [PERS SDK] React Native environment ready (no polyfills needed)');
17
- return true;
18
- };
19
- // Platform detection
20
- const isReactNative = () => {
21
- return typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
22
- };
23
- // Auto-initialize
24
- initializeReactNativePolyfills();
25
-
26
- /**
27
- * Storage strategy for different types of data
28
- */
29
- var StorageStrategy;
30
- (function (StorageStrategy) {
31
- /** Use AsyncStorage for general app data */
32
- StorageStrategy["ASYNC_STORAGE"] = "async_storage";
33
- /** Use Keychain for sensitive tokens (when available) */
34
- StorageStrategy["KEYCHAIN"] = "keychain";
35
- /** Use in-memory storage (fallback) */
36
- StorageStrategy["MEMORY"] = "memory";
37
- })(StorageStrategy || (StorageStrategy = {}));
38
- /**
39
- * Base React Native Authentication Provider
40
- *
41
- * This serves as a blueprint for native implementations and can be extended
42
- * by consuming applications to integrate with their specific auth systems.
43
- *
44
- * Features:
45
- * - Multiple storage strategies (AsyncStorage, Keychain, Memory)
46
- * - Configurable security levels per token type
47
- * - Cross-platform compatibility (iOS/Android/Web)
48
- * - Blueprint for native iOS/Android implementations
49
- */
50
- class BaseReactNativeAuthProvider {
51
- constructor(projectKey, config = {}) {
52
- // In-memory fallback storage
53
- this.memoryStorage = new Map();
54
- // Validate projectKey
55
- if (!projectKey || typeof projectKey !== 'string') {
56
- throw new Error('ReactNativeAuthProvider: projectKey is required and must be a string');
57
- }
58
- // Set default configuration
59
- this.config = {
60
- accessTokenStrategy: StorageStrategy.ASYNC_STORAGE,
61
- refreshTokenStrategy: StorageStrategy.KEYCHAIN,
62
- keyPrefix: `pers_${projectKey.slice(0, 8)}`,
63
- debug: false,
64
- ...config
65
- };
66
- // Create storage keys
67
- this.ACCESS_TOKEN_KEY = `${this.config.keyPrefix}_access_token`;
68
- this.REFRESH_TOKEN_KEY = `${this.config.keyPrefix}_refresh_token`;
69
- this.PROJECT_KEY_KEY = `${this.config.keyPrefix}_project_key`;
70
- if (this.config.debug) {
71
- console.log('🔧 ReactNativeAuthProvider initialized with config:', this.config);
72
- }
73
- }
74
- // Core token management methods
75
- async getToken() {
76
- return this.getStoredValue(this.ACCESS_TOKEN_KEY, this.config.accessTokenStrategy);
77
- }
78
- async setAccessToken(token) {
79
- await this.storeValue(this.ACCESS_TOKEN_KEY, token, this.config.accessTokenStrategy);
80
- if (this.config.debug) {
81
- console.log('✅ Access token stored securely');
82
- }
83
- }
84
- async setRefreshToken(token) {
85
- await this.storeValue(this.REFRESH_TOKEN_KEY, token, this.config.refreshTokenStrategy);
86
- if (this.config.debug) {
87
- console.log('✅ Refresh token stored securely');
88
- }
89
- }
90
- async getRefreshToken() {
91
- return this.getStoredValue(this.REFRESH_TOKEN_KEY, this.config.refreshTokenStrategy);
92
- }
93
- async clearTokens() {
94
- await Promise.all([
95
- this.removeStoredValue(this.ACCESS_TOKEN_KEY, this.config.accessTokenStrategy),
96
- this.removeStoredValue(this.REFRESH_TOKEN_KEY, this.config.refreshTokenStrategy)
97
- ]);
98
- if (this.config.debug) {
99
- console.log('✅ All tokens cleared from storage');
100
- }
101
- }
102
- // Token validation methods
103
- hasValidToken() {
104
- // Synchronous check - for async check use hasValidTokenAsync()
105
- return true; // Actual validation happens in getToken()
106
- }
107
- hasRefreshToken() {
108
- // Synchronous check - for async check use hasRefreshTokenAsync()
109
- return true; // Actual validation happens in getRefreshToken()
110
- }
111
- // Async token validation methods
112
- async hasValidTokenAsync() {
113
- const token = await this.getToken();
114
- return !!token;
115
- }
116
- async hasRefreshTokenAsync() {
117
- const refreshToken = await this.getRefreshToken();
118
- return !!refreshToken;
119
- }
120
- // Legacy methods for backward compatibility
121
- setToken(token) {
122
- this.setAccessToken(token).catch(error => {
123
- console.error('Legacy setToken failed:', error);
124
- });
125
- }
126
- clearToken() {
127
- this.clearTokens().catch(error => {
128
- console.error('Legacy clearToken failed:', error);
129
- });
130
- }
131
- // Protected storage implementation methods
132
- async storeValue(key, value, strategy) {
133
- try {
134
- switch (strategy) {
135
- case StorageStrategy.KEYCHAIN:
136
- // Try Keychain first, fallback to AsyncStorage
137
- if (await this.isKeychainAvailable()) {
138
- await this.storeInKeychain(key, value);
139
- }
140
- else {
141
- await AsyncStorage.setItem(key, value);
142
- }
143
- break;
144
- case StorageStrategy.ASYNC_STORAGE:
145
- await AsyncStorage.setItem(key, value);
146
- break;
147
- case StorageStrategy.MEMORY:
148
- default:
149
- this.memoryStorage.set(key, value);
150
- break;
151
- }
152
- }
153
- catch (error) {
154
- console.error(`Failed to store value with strategy ${strategy}:`, error);
155
- // Fallback to memory storage
156
- this.memoryStorage.set(key, value);
157
- }
158
- }
159
- async getStoredValue(key, strategy) {
160
- try {
161
- switch (strategy) {
162
- case StorageStrategy.KEYCHAIN:
163
- // Try Keychain first, fallback to AsyncStorage
164
- if (await this.isKeychainAvailable()) {
165
- return await this.getFromKeychain(key);
166
- }
167
- else {
168
- return await AsyncStorage.getItem(key);
169
- }
170
- case StorageStrategy.ASYNC_STORAGE:
171
- return await AsyncStorage.getItem(key);
172
- case StorageStrategy.MEMORY:
173
- default:
174
- return this.memoryStorage.get(key) || null;
175
- }
176
- }
177
- catch (error) {
178
- console.warn(`Failed to get value with strategy ${strategy}:`, error);
179
- // Fallback to memory storage
180
- return this.memoryStorage.get(key) || null;
181
- }
182
- }
183
- async removeStoredValue(key, strategy) {
184
- try {
185
- switch (strategy) {
186
- case StorageStrategy.KEYCHAIN:
187
- // Try Keychain first, fallback to AsyncStorage
188
- if (await this.isKeychainAvailable()) {
189
- await this.removeFromKeychain(key);
190
- }
191
- else {
192
- await AsyncStorage.removeItem(key);
193
- }
194
- break;
195
- case StorageStrategy.ASYNC_STORAGE:
196
- await AsyncStorage.removeItem(key);
197
- break;
198
- case StorageStrategy.MEMORY:
199
- default:
200
- this.memoryStorage.delete(key);
201
- break;
202
- }
203
- }
204
- catch (error) {
205
- console.error(`Failed to remove value with strategy ${strategy}:`, error);
206
- // Ensure memory fallback is also cleared
207
- this.memoryStorage.delete(key);
208
- }
209
- }
210
- // Keychain helper methods
211
- async isKeychainAvailable() {
212
- try {
213
- // Check if react-native-keychain is available
214
- const Keychain = require('react-native-keychain');
215
- return !!Keychain && typeof Keychain.setInternetCredentials === 'function';
216
- }
217
- catch {
218
- return false;
219
- }
220
- }
221
- async storeInKeychain(key, value) {
222
- const Keychain = require('react-native-keychain');
223
- await Keychain.setInternetCredentials(key, 'pers-token', value);
224
- }
225
- async getFromKeychain(key) {
226
- const Keychain = require('react-native-keychain');
227
- const credentials = await Keychain.getInternetCredentials(key);
228
- return credentials ? credentials.password : null;
229
- }
230
- async removeFromKeychain(key) {
231
- const Keychain = require('react-native-keychain');
232
- await Keychain.resetInternetCredentials(key);
233
- }
234
- }
235
- /**
236
- * React Native Authentication Provider
237
- *
238
- * A ready-to-use implementation for basic use cases.
239
- * Uses AsyncStorage for access tokens and Keychain for refresh tokens (when available).
240
- */
241
- class ReactNativeAuthProvider extends BaseReactNativeAuthProvider {
242
- constructor(projectKey, config = {}) {
243
- // Validate projectKey
244
- if (!projectKey || typeof projectKey !== 'string') {
245
- throw new Error('ReactNativeAuthProvider: projectKey is required and must be a string');
246
- }
247
- super(projectKey, {
248
- accessTokenStrategy: StorageStrategy.ASYNC_STORAGE,
249
- refreshTokenStrategy: StorageStrategy.KEYCHAIN,
250
- debug: false,
251
- ...config
252
- });
253
- this.projectKey = projectKey;
254
- this.authType = 'user';
255
- }
256
- async getProjectKey() {
257
- return this.projectKey;
258
- }
259
- async onTokenExpired() {
260
- if (this.config.debug) {
261
- console.warn('ReactNativeAuthProvider: Token expired - no refresh logic implemented');
262
- }
263
- }
264
- }
265
- /**
266
- * Secure React Native Authentication Provider
267
- *
268
- * Maximum security implementation using Keychain for all sensitive data.
269
- */
270
- class SecureReactNativeAuthProvider extends BaseReactNativeAuthProvider {
271
- constructor(projectKey, config = {}) {
272
- // Validate projectKey
273
- if (!projectKey || typeof projectKey !== 'string') {
274
- throw new Error('SecureReactNativeAuthProvider: projectKey is required and must be a string');
275
- }
276
- super(projectKey, {
277
- ...config,
278
- accessTokenStrategy: StorageStrategy.KEYCHAIN,
279
- refreshTokenStrategy: StorageStrategy.KEYCHAIN,
280
- });
281
- this.projectKey = projectKey;
282
- this.authType = 'user';
283
- }
284
- async getProjectKey() {
285
- return this.projectKey;
286
- }
287
- async onTokenExpired() {
288
- if (this.config.debug) {
289
- console.warn('SecureReactNativeAuthProvider: Token expired - implement refresh logic');
290
- }
291
- }
292
- }
293
-
294
- /**
295
- * HTTP Client implementation for React Native
296
- *
297
- * This implementation properly implements the core SDK's HttpClient interface
298
- * and uses fetch API which is available in React Native.
299
- */
300
- class ReactNativeHttpClient {
301
- constructor(baseURL) {
302
- this.baseURL = baseURL;
303
- }
304
- async get(url, options) {
305
- return this.request('GET', url, undefined, options);
306
- }
307
- async post(url, body, options) {
308
- return this.request('POST', url, body, options);
309
- }
310
- async put(url, body, options) {
311
- return this.request('PUT', url, body, options);
312
- }
313
- async delete(url, options) {
314
- return this.request('DELETE', url, undefined, options);
315
- }
316
- async request(method, url, body, options) {
317
- const fullUrl = this.buildUrl(url, options?.params);
318
- const config = {
319
- method,
320
- headers: {
321
- 'Content-Type': 'application/json',
322
- ...options?.headers,
323
- },
324
- };
325
- // Add timeout if specified
326
- if (options?.timeout) {
327
- const controller = new AbortController();
328
- config.signal = controller.signal;
329
- setTimeout(() => controller.abort(), options.timeout);
330
- }
331
- // Add body for POST/PUT requests
332
- if (body && (method === 'POST' || method === 'PUT')) {
333
- config.body = JSON.stringify(body);
334
- }
335
- try {
336
- const response = await fetch(fullUrl, config);
337
- if (!response.ok) {
338
- // Try to get error details from response
339
- let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
340
- try {
341
- const errorBody = await response.text();
342
- if (errorBody) {
343
- errorMessage += ` - ${errorBody}`;
344
- }
345
- }
346
- catch (e) {
347
- // Ignore errors when reading error body
348
- }
349
- throw new Error(errorMessage);
350
- }
351
- // Handle different response types
352
- switch (options?.responseType) {
353
- case 'text':
354
- return response.text();
355
- case 'blob':
356
- return response.blob();
357
- case 'arraybuffer':
358
- return response.arrayBuffer();
359
- case 'json':
360
- default:
361
- // Check if response has content
362
- const contentLength = response.headers.get('content-length');
363
- if (contentLength === '0' || response.status === 204) {
364
- return undefined;
365
- }
366
- return response.json();
367
- }
368
- }
369
- catch (error) {
370
- if (error instanceof Error && error.name === 'AbortError') {
371
- throw new Error(`Request timeout after ${options?.timeout}ms`);
372
- }
373
- throw error;
374
- }
375
- }
376
- buildUrl(url, params) {
377
- const fullUrl = this.baseURL ? `${this.baseURL}${url}` : url;
378
- if (!params || Object.keys(params).length === 0) {
379
- return fullUrl;
380
- }
381
- const urlObj = new URL(fullUrl);
382
- Object.entries(params).forEach(([key, value]) => {
383
- urlObj.searchParams.append(key, value);
384
- });
385
- return urlObj.toString();
386
- }
387
- }
388
-
389
- // Create the context
390
- const SDKContext = createContext(null);
391
- // Custom auth provider for React Native
392
- class ReactNativeSDKAuthProvider extends BaseReactNativeAuthProvider {
393
- constructor(projectKey) {
394
- super(projectKey);
395
- this.projectKey = projectKey;
396
- this.authType = 'user';
397
- this._token = null;
398
- }
399
- async getToken() {
400
- return this._token;
401
- }
402
- async setToken(token) {
403
- this._token = token;
404
- }
405
- async getProjectKey() {
406
- return this.projectKey;
407
- }
408
- async onTokenExpired() {
409
- console.log('Token expired - clearing token');
410
- this._token = null;
411
- }
412
- }
413
- // Provider component
414
- const PersSDKProvider = ({ children }) => {
415
- const initializingRef = useRef(false);
416
- const [apiClient, setApiClient] = useState(null);
417
- const [authProvider, setAuthProvider] = useState(null);
418
- const [sdks, setSdks] = useState({
419
- tokens: null,
420
- transactions: null,
421
- business: null,
422
- campaigns: null,
423
- redemptions: null,
424
- web3: null,
425
- });
426
- const [isInitialized, setIsInitialized] = useState(false);
427
- const [isAuthenticated, setIsAuthenticated] = useState(false);
428
- const [user, setUser] = useState(null);
429
- const [accountAddress, setAccountAddress] = useState(null);
430
- const initialize = useCallback(async (config) => {
431
- // Prevent multiple initializations
432
- if (isInitialized || initializingRef.current) {
433
- console.log('⚠️ SDK already initialized or initializing, skipping...');
434
- return;
435
- }
436
- initializingRef.current = true;
437
- try {
438
- console.log('🚀 Initializing PERS SDK with config:', config);
439
- // Create auth provider
440
- const auth = new ReactNativeSDKAuthProvider(config.apiProjectKey);
441
- setAuthProvider(auth);
442
- // Create HTTP client
443
- const httpClient = new ReactNativeHttpClient();
444
- // Create API client
445
- const client = new PersApiClient(httpClient, {
446
- apiProjectKey: config.apiProjectKey,
447
- authProvider: auth,
448
- environment: config.environment || 'development',
449
- });
450
- setApiClient(client);
451
- // Initialize domain SDKs
452
- const domainSDKs = {
453
- tokens: new TokenSDK(client),
454
- transactions: createTransactionSDK(client),
455
- business: createBusinessSDK(client),
456
- campaigns: createCampaignSDK(client),
457
- redemptions: createRedemptionSDK(client),
458
- web3: createWeb3SDK(client),
459
- };
460
- setSdks(domainSDKs);
461
- setIsInitialized(true);
462
- console.log('✅ PERS SDK initialized successfully');
463
- }
464
- catch (error) {
465
- console.error('❌ Failed to initialize PERS SDK:', error);
466
- initializingRef.current = false;
467
- throw error;
468
- }
469
- finally {
470
- initializingRef.current = false;
471
- }
472
- }, []);
473
- const login = useCallback(async (jwtToken, userType = 'user') => {
474
- if (!apiClient || !authProvider) {
475
- throw new Error('SDK not initialized. Call initialize() first.');
476
- }
477
- try {
478
- console.log(`🔐 Logging in as ${userType}...`);
479
- // Set token in auth provider
480
- await authProvider.setToken(jwtToken);
481
- // Perform login with API client
482
- const result = userType === 'admin'
483
- ? await apiClient.loginAdmin(jwtToken)
484
- : await apiClient.loginUser(jwtToken);
485
- const userData = result.user || result.admin;
486
- const userAccountAddress = userData?.accountAddress ||
487
- userData?.wallets?.[0]?.address ||
488
- null;
489
- setUser(userData);
490
- setAccountAddress(userAccountAddress);
491
- setIsAuthenticated(true);
492
- console.log('✅ Login successful');
493
- return result;
494
- }
495
- catch (error) {
496
- console.error('❌ Login failed:', error);
497
- throw error;
498
- }
499
- }, [apiClient, authProvider]);
500
- const loginWithRawData = useCallback(async (rawUserData) => {
501
- if (!apiClient || !authProvider) {
502
- throw new Error('SDK not initialized. Call initialize() first.');
503
- }
504
- try {
505
- console.log('🔐 Logging in with raw user data...');
506
- const result = await apiClient.loginUserWithRawData(rawUserData);
507
- // Set token from result
508
- if (result.accessToken) {
509
- await authProvider.setToken(result.accessToken);
510
- }
511
- const userData = result.user;
512
- const userAccountAddress = userData?.accountAddress ||
513
- userData?.wallets?.[0]?.address ||
514
- null;
515
- setUser(userData);
516
- setAccountAddress(userAccountAddress);
517
- setIsAuthenticated(true);
518
- console.log('✅ Raw data login successful');
519
- return result;
520
- }
521
- catch (error) {
522
- console.error('❌ Raw data login failed:', error);
523
- throw error;
524
- }
525
- }, [apiClient, authProvider]);
526
- const logout = useCallback(async () => {
527
- try {
528
- console.log('🔓 Logging out...');
529
- if (authProvider) {
530
- await authProvider.setToken(null);
531
- }
532
- setUser(null);
533
- setAccountAddress(null);
534
- setIsAuthenticated(false);
535
- console.log('✅ Logout successful');
536
- }
537
- catch (error) {
538
- console.error('❌ Logout failed:', error);
539
- throw error;
540
- }
541
- }, [authProvider]);
542
- const contextValue = {
543
- // SDK instances
544
- tokens: sdks.tokens,
545
- transactions: sdks.transactions,
546
- business: sdks.business,
547
- campaigns: sdks.campaigns,
548
- redemptions: sdks.redemptions,
549
- web3: sdks.web3,
550
- apiClient,
551
- // State
552
- isInitialized,
553
- isAuthenticated,
554
- user,
555
- accountAddress,
556
- // Methods
557
- initialize,
558
- login,
559
- loginWithRawData,
560
- logout,
561
- };
562
- return (jsx(SDKContext.Provider, { value: contextValue, children: children }));
563
- };
564
- // Custom hook to use the SDK context
565
- const usePersSDK = () => {
566
- const context = useContext(SDKContext);
567
- if (!context) {
568
- throw new Error('usePersSDK must be used within a PersSDKProvider');
569
- }
570
- return context;
571
- };
572
-
573
- const useAuth = () => {
574
- const { isInitialized, isAuthenticated, user, accountAddress, initialize, login, loginWithRawData, logout, } = usePersSDK();
575
- return {
576
- // State
577
- isInitialized,
578
- isAuthenticated,
579
- user,
580
- accountAddress,
581
- // Actions
582
- initialize,
583
- login,
584
- loginWithRawData,
585
- logout,
586
- };
587
- };
588
-
589
- const useTokens = () => {
590
- const { tokens, isInitialized, isAuthenticated } = usePersSDK();
591
- if (!isAuthenticated && isInitialized) {
592
- console.warn('SDK not authenticated. Some token operations may fail.');
593
- }
594
- const getTokens = useCallback(async () => {
595
- if (!isInitialized) {
596
- throw new Error('SDK not initialized. Call initialize() first.');
597
- }
598
- if (!tokens?.getTokens) {
599
- console.warn('getTokens method not available');
600
- return [];
601
- }
602
- try {
603
- const result = await tokens.getTokens();
604
- console.log('✅ Tokens fetched successfully:', result);
605
- return result;
606
- }
607
- catch (error) {
608
- console.error('❌ Failed to fetch tokens:', error);
609
- throw error;
610
- }
611
- }, [tokens]);
612
- const getTokenById = useCallback(async (tokenId) => {
613
- if (!isInitialized) {
614
- throw new Error('SDK not initialized. Call initialize() first.');
615
- }
616
- if (!tokens?.getTokenById) {
617
- throw new Error('getTokenById method not available');
618
- }
619
- try {
620
- const result = await tokens.getTokenById(tokenId);
621
- console.log('✅ Token fetched successfully:', result);
622
- return result;
623
- }
624
- catch (error) {
625
- console.error('❌ Failed to fetch token:', error);
626
- throw error;
627
- }
628
- }, [tokens]);
629
- return {
630
- getTokens,
631
- getTokenById,
632
- isAvailable: isInitialized && !!tokens,
633
- };
634
- };
635
-
636
- const useTransactions = () => {
637
- const { transactions, isInitialized, isAuthenticated } = usePersSDK();
638
- if (!isAuthenticated && isInitialized) {
639
- console.warn('SDK not authenticated. Some transaction operations may fail.');
640
- }
641
- const createTransaction = useCallback(async (request) => {
642
- if (!isInitialized) {
643
- throw new Error('SDK not initialized. Call initialize() first.');
644
- }
645
- if (!transactions?.createTransaction) {
646
- throw new Error('createTransaction method not available');
647
- }
648
- try {
649
- console.log('🔄 Creating transaction with request:', request);
650
- const result = await transactions.createTransaction(request);
651
- // React Native specific: Handle signature URLs
652
- if (result?.actionable?.actionUrl) {
653
- try {
654
- const { Linking } = require('react-native');
655
- console.log('🔗 Opening signature URL:', result.actionable.actionUrl);
656
- await Linking.openURL(result.actionable.actionUrl);
657
- }
658
- catch (linkingError) {
659
- console.error('❌ Failed to open signature URL:', linkingError);
660
- }
661
- }
662
- console.log('✅ Transaction created successfully:', result);
663
- return result;
664
- }
665
- catch (error) {
666
- console.error('❌ Failed to create transaction:', error);
667
- throw error;
668
- }
669
- }, [transactions]);
670
- const getTransactionById = useCallback(async (transactionId) => {
671
- if (!isInitialized) {
672
- throw new Error('SDK not initialized. Call initialize() first.');
673
- }
674
- if (!transactions?.getTransactionById) {
675
- throw new Error('getTransactionById method not available');
676
- }
677
- try {
678
- const result = await transactions.getTransactionById(transactionId);
679
- console.log('✅ Transaction fetched successfully:', result);
680
- return result;
681
- }
682
- catch (error) {
683
- console.error('❌ Failed to fetch transaction:', error);
684
- throw error;
685
- }
686
- }, [transactions]);
687
- const getTransactionHistory = useCallback(async (filters) => {
688
- if (!isInitialized) {
689
- throw new Error('SDK not initialized. Call initialize() first.');
690
- }
691
- if (!transactions?.getTransactionHistory) {
692
- console.warn('getTransactionHistory method not available');
693
- return [];
694
- }
695
- try {
696
- const result = await transactions.getTransactionHistory(filters);
697
- console.log('✅ Transaction history fetched successfully:', result);
698
- return result;
699
- }
700
- catch (error) {
701
- console.error('❌ Failed to fetch transaction history:', error);
702
- throw error;
703
- }
704
- }, [transactions]);
705
- return {
706
- createTransaction,
707
- getTransactionById,
708
- getTransactionHistory,
709
- isAvailable: isInitialized && !!transactions,
710
- };
711
- };
712
-
713
- const useBusiness = () => {
714
- const { business, isInitialized } = usePersSDK();
715
- const getActiveBusinesses = useCallback(async () => {
716
- if (!isInitialized) {
717
- throw new Error('SDK not initialized. Call initialize() first.');
718
- }
719
- if (!business?.getActiveBusinesses) {
720
- console.warn('getActiveBusinesses method not available');
721
- return [];
722
- }
723
- try {
724
- const result = await business.getActiveBusinesses();
725
- console.log('✅ Active businesses fetched successfully:', result);
726
- return result;
727
- }
728
- catch (error) {
729
- console.error('❌ Failed to fetch active businesses:', error);
730
- throw error;
731
- }
732
- }, [business]);
733
- const getAllBusinessTypes = useCallback(async () => {
734
- if (!isInitialized) {
735
- throw new Error('SDK not initialized. Call initialize() first.');
736
- }
737
- if (!business?.getAllBusinessTypes) {
738
- console.warn('getAllBusinessTypes method not available');
739
- return [];
740
- }
741
- try {
742
- const result = await business.getAllBusinessTypes();
743
- console.log('✅ Business types fetched successfully:', result);
744
- return result;
745
- }
746
- catch (error) {
747
- console.error('❌ Failed to fetch business types:', error);
748
- throw error;
749
- }
750
- }, [business]);
751
- const getBusinessById = useCallback(async (businessId) => {
752
- if (!isInitialized) {
753
- throw new Error('SDK not initialized. Call initialize() first.');
754
- }
755
- if (!business?.getBusinessById) {
756
- throw new Error('getBusinessById method not available');
757
- }
758
- try {
759
- const result = await business.getBusinessById(businessId);
760
- console.log('✅ Business fetched successfully:', result);
761
- return result;
762
- }
763
- catch (error) {
764
- console.error('❌ Failed to fetch business:', error);
765
- throw error;
766
- }
767
- }, [business]);
768
- return {
769
- getActiveBusinesses,
770
- getAllBusinessTypes,
771
- getBusinessById,
772
- isAvailable: isInitialized && !!business,
773
- };
774
- };
775
-
776
- const useCampaigns = () => {
777
- const { campaigns, isInitialized, isAuthenticated } = usePersSDK();
778
- const getActiveCampaigns = useCallback(async () => {
779
- if (!isInitialized) {
780
- throw new Error('SDK not initialized. Call initialize() first.');
781
- }
782
- if (!campaigns?.getActiveCampaigns) {
783
- console.warn('getActiveCampaigns method not available');
784
- return [];
785
- }
786
- try {
787
- const result = await campaigns.getActiveCampaigns();
788
- console.log('✅ Active campaigns fetched successfully:', result);
789
- return result;
790
- }
791
- catch (error) {
792
- console.error('❌ Failed to fetch active campaigns:', error);
793
- throw error;
794
- }
795
- }, [campaigns]);
796
- const getCampaignById = useCallback(async (campaignId) => {
797
- if (!isInitialized) {
798
- throw new Error('SDK not initialized. Call initialize() first.');
799
- }
800
- if (!campaigns?.getCampaignById) {
801
- throw new Error('getCampaignById method not available');
802
- }
803
- try {
804
- const result = await campaigns.getCampaignById(campaignId);
805
- console.log('✅ Campaign fetched successfully:', result);
806
- return result;
807
- }
808
- catch (error) {
809
- console.error('❌ Failed to fetch campaign:', error);
810
- throw error;
811
- }
812
- }, [campaigns]);
813
- const claimCampaign = useCallback(async (request) => {
814
- if (!isInitialized) {
815
- throw new Error('SDK not initialized. Call initialize() first.');
816
- }
817
- if (!isAuthenticated) {
818
- throw new Error('SDK not authenticated. claimCampaign requires authentication.');
819
- }
820
- if (!campaigns?.claimCampaign) {
821
- throw new Error('claimCampaign method not available');
822
- }
823
- try {
824
- console.log('🔄 Claiming campaign with request:', request);
825
- const result = await campaigns.claimCampaign(request);
826
- console.log('✅ Campaign claimed successfully:', result);
827
- return result;
828
- }
829
- catch (error) {
830
- console.error('❌ Failed to claim campaign:', error);
831
- throw error;
832
- }
833
- }, [isInitialized, isAuthenticated, campaigns]);
834
- const getClaimsForLoggedUser = useCallback(async () => {
835
- if (!isInitialized) {
836
- throw new Error('SDK not initialized. Call initialize() first.');
837
- }
838
- if (!isAuthenticated) {
839
- console.warn('SDK not authenticated. getClaimsForLoggedUser requires authentication.');
840
- return [];
841
- }
842
- if (!campaigns?.getClaimsForLoggedUser) {
843
- console.warn('getClaimsForLoggedUser method not available');
844
- return [];
845
- }
846
- try {
847
- const result = await campaigns.getClaimsForLoggedUser();
848
- console.log('✅ User claims fetched successfully:', result);
849
- return result;
850
- }
851
- catch (error) {
852
- console.error('❌ Failed to fetch user claims:', error);
853
- throw error;
854
- }
855
- }, [isInitialized, isAuthenticated, campaigns]);
856
- return {
857
- getActiveCampaigns,
858
- getCampaignById,
859
- claimCampaign,
860
- getClaimsForLoggedUser,
861
- isAvailable: isInitialized && !!campaigns,
862
- };
863
- };
864
-
865
- const useRedemptions = () => {
866
- const { redemptions, isInitialized, isAuthenticated } = usePersSDK();
867
- // Admin method: Create new redemption offers
868
- const createRedemption = useCallback(async (redemptionData) => {
869
- if (!isInitialized) {
870
- throw new Error('SDK not initialized. Call initialize() first.');
871
- }
872
- if (!redemptions?.createRedemption) {
873
- throw new Error('createRedemption method not available - admin access required');
874
- }
875
- try {
876
- console.log('🔄 Creating redemption offer with data:', redemptionData);
877
- const result = await redemptions.createRedemption(redemptionData);
878
- console.log('✅ Redemption offer created successfully:', result);
879
- return result;
880
- }
881
- catch (error) {
882
- console.error('❌ Failed to create redemption offer:', error);
883
- throw error;
884
- }
885
- }, [redemptions]);
886
- const getActiveRedemptions = useCallback(async () => {
887
- if (!isInitialized) {
888
- throw new Error('SDK not initialized. Call initialize() first.');
889
- }
890
- if (!redemptions?.getActiveRedemptions) {
891
- console.warn('getActiveRedemptions method not available');
892
- return [];
893
- }
894
- try {
895
- const result = await redemptions.getActiveRedemptions();
896
- console.log('✅ Active redemptions fetched successfully:', result);
897
- return result;
898
- }
899
- catch (error) {
900
- console.error('❌ Failed to fetch active redemptions:', error);
901
- throw error;
902
- }
903
- }, [redemptions]);
904
- const getUserRedeems = useCallback(async () => {
905
- if (!isInitialized) {
906
- throw new Error('SDK not initialized. Call initialize() first.');
907
- }
908
- if (!isAuthenticated) {
909
- console.warn('SDK not authenticated. getUserRedeems requires authentication.');
910
- return [];
911
- }
912
- if (!redemptions?.getUserRedeems) {
913
- console.warn('getUserRedeems method not available');
914
- return [];
915
- }
916
- try {
917
- const result = await redemptions.getUserRedeems();
918
- console.log('✅ User redemptions fetched successfully:', result);
919
- return result;
920
- }
921
- catch (error) {
922
- console.error('❌ Failed to fetch user redemptions:', error);
923
- throw error;
924
- }
925
- }, [isInitialized, isAuthenticated, redemptions]);
926
- const redeemRedemption = useCallback(async (redemptionId) => {
927
- if (!isInitialized) {
928
- throw new Error('SDK not initialized. Call initialize() first.');
929
- }
930
- if (!isAuthenticated) {
931
- throw new Error('SDK not authenticated. redeemRedemption requires authentication.');
932
- }
933
- if (!redemptions?.redeemRedemption) {
934
- throw new Error('redeemRedemption method not available');
935
- }
936
- try {
937
- console.log('🔄 Redeeming redemption:', redemptionId);
938
- const result = await redemptions.redeemRedemption(redemptionId);
939
- // React Native specific: Handle signature URLs for redemptions
940
- if (result?.actionable?.actionUrl) {
941
- try {
942
- const { Linking } = require('react-native');
943
- console.log('🔗 Opening redemption signature URL:', result.actionable.actionUrl);
944
- await Linking.openURL(result.actionable.actionUrl);
945
- }
946
- catch (linkingError) {
947
- console.error('❌ Failed to open redemption signature URL:', linkingError);
948
- }
949
- }
950
- console.log('✅ Redemption processed successfully:', result);
951
- return result;
952
- }
953
- catch (error) {
954
- console.error('❌ Failed to redeem redemption:', error);
955
- throw error;
956
- }
957
- }, [isInitialized, isAuthenticated, redemptions]);
958
- const getRedemptionById = useCallback(async (redemptionId) => {
959
- if (!isInitialized) {
960
- throw new Error('SDK not initialized. Call initialize() first.');
961
- }
962
- if (!redemptions?.getRedemptionById) {
963
- throw new Error('getRedemptionById method not available');
964
- }
965
- try {
966
- const result = await redemptions.getRedemptionById(redemptionId);
967
- console.log('✅ Redemption fetched successfully:', result);
968
- return result;
969
- }
970
- catch (error) {
971
- console.error('❌ Failed to fetch redemption:', error);
972
- throw error;
973
- }
974
- }, [redemptions]);
975
- return {
976
- createRedemption,
977
- getActiveRedemptions,
978
- getUserRedeems,
979
- redeemRedemption,
980
- getRedemptionById,
981
- isAvailable: isInitialized && !!redemptions,
982
- };
983
- };
984
-
985
- const useWeb3 = () => {
986
- const { web3, isInitialized, isAuthenticated, accountAddress } = usePersSDK();
987
- if (!isAuthenticated && isInitialized) {
988
- console.warn('SDK not authenticated. Some web3 operations may fail.');
989
- }
990
- const getTokenBalance = useCallback(async (request) => {
991
- if (!isInitialized) {
992
- throw new Error('SDK not initialized. Call initialize() first.');
993
- }
994
- if (!web3?.getTokenBalance) {
995
- throw new Error('getTokenBalance method not available');
996
- }
997
- try {
998
- const result = await web3.getTokenBalance(request);
999
- console.log('✅ Token balance fetched successfully:', result);
1000
- return result;
1001
- }
1002
- catch (error) {
1003
- console.error('❌ Failed to fetch token balance:', error);
1004
- throw error;
1005
- }
1006
- }, [web3]);
1007
- const getTokenCollection = useCallback(async (request) => {
1008
- if (!isInitialized) {
1009
- throw new Error('SDK not initialized. Call initialize() first.');
1010
- }
1011
- if (!web3?.getTokenCollection) {
1012
- console.warn('getTokenCollection method not available');
1013
- return [];
1014
- }
1015
- try {
1016
- const result = await web3.getTokenCollection(request);
1017
- console.log('✅ Token collection fetched successfully:', result);
1018
- return result;
1019
- }
1020
- catch (error) {
1021
- console.error('❌ Failed to fetch token collection:', error);
1022
- throw error;
1023
- }
1024
- }, [web3]);
1025
- const getWalletInfo = useCallback(async () => {
1026
- if (!isInitialized) {
1027
- throw new Error('SDK not initialized. Call initialize() first.');
1028
- }
1029
- if (!accountAddress) {
1030
- console.warn('No account address available');
1031
- return null;
1032
- }
1033
- return {
1034
- address: accountAddress,
1035
- isConnected: !!accountAddress,
1036
- };
1037
- }, [isInitialized, accountAddress]);
1038
- return {
1039
- getTokenBalance,
1040
- getTokenCollection,
1041
- getWalletInfo,
1042
- accountAddress: isInitialized ? accountAddress : null,
1043
- isAvailable: isInitialized && !!web3,
1044
- };
1045
- };
1046
-
1047
- // Initialize React Native polyfills automatically
1048
- // TEMPORARY: Minimal exports to isolate the .from() error
1049
- console.log('🔍 [DEBUG] Loading React Native SDK...');
1050
- console.log('🔍 [DEBUG] Auth providers loaded successfully');
1051
- console.log('🔍 [DEBUG] React Native SDK loaded with full exports including useWeb3');
1052
- // Note: For types and DTOs, import directly from @explorins/pers-shared
1053
- // This maintains clean separation and avoids circular dependencies
1054
- // Example: import { TokenDTO, BusinessDTO } from '@explorins/pers-shared';
1055
-
1056
- export { BaseReactNativeAuthProvider, PersSDKProvider, ReactNativeAuthProvider, ReactNativeHttpClient, SecureReactNativeAuthProvider, StorageStrategy, initializeReactNativePolyfills, isReactNative, useAuth, useBusiness, useCampaigns, usePersSDK, useRedemptions, useTokens, useTransactions, useWeb3 };
1057
- //# sourceMappingURL=index.esm.js.map