@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.
- package/README.md +276 -123
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/useAnalytics.d.ts +96 -0
- package/dist/hooks/useAnalytics.d.ts.map +1 -0
- package/dist/hooks/useAnalytics.js +73 -0
- package/dist/hooks/useAuth.d.ts +52 -7
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +250 -3
- package/dist/hooks/useBusiness.d.ts +45 -3
- package/dist/hooks/useBusiness.d.ts.map +1 -1
- package/dist/hooks/useBusiness.js +182 -28
- package/dist/hooks/useCampaigns.d.ts +11 -4
- package/dist/hooks/useCampaigns.d.ts.map +1 -1
- package/dist/hooks/useCampaigns.js +101 -39
- package/dist/hooks/useDonations.d.ts +33 -0
- package/dist/hooks/useDonations.d.ts.map +1 -0
- package/dist/hooks/useDonations.js +62 -0
- package/dist/hooks/useFiles.d.ts +50 -0
- package/dist/hooks/useFiles.d.ts.map +1 -0
- package/dist/hooks/useFiles.js +140 -0
- package/dist/hooks/usePurchases.d.ts +9 -0
- package/dist/hooks/usePurchases.d.ts.map +1 -0
- package/dist/hooks/usePurchases.js +56 -0
- package/dist/hooks/useRedemptions.d.ts +10 -5
- package/dist/hooks/useRedemptions.d.ts.map +1 -1
- package/dist/hooks/useRedemptions.js +118 -66
- package/dist/hooks/useTenants.d.ts +10 -0
- package/dist/hooks/useTenants.d.ts.map +1 -0
- package/dist/hooks/useTenants.js +68 -0
- package/dist/hooks/useTokens.d.ts +36 -2
- package/dist/hooks/useTokens.d.ts.map +1 -1
- package/dist/hooks/useTokens.js +180 -19
- package/dist/hooks/useTransactionSigner.d.ts +73 -0
- package/dist/hooks/useTransactionSigner.d.ts.map +1 -0
- package/dist/hooks/useTransactionSigner.js +216 -0
- package/dist/hooks/useTransactions.d.ts +45 -3
- package/dist/hooks/useTransactions.d.ts.map +1 -1
- package/dist/hooks/useTransactions.js +149 -39
- package/dist/hooks/useUserStatus.d.ts +9 -0
- package/dist/hooks/useUserStatus.d.ts.map +1 -0
- package/dist/hooks/useUserStatus.js +57 -0
- package/dist/hooks/useUsers.d.ts +17 -0
- package/dist/hooks/useUsers.d.ts.map +1 -0
- package/dist/hooks/useUsers.js +120 -0
- package/dist/hooks/useWeb3.d.ts +69 -6
- package/dist/hooks/useWeb3.d.ts.map +1 -1
- package/dist/hooks/useWeb3.js +177 -17
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31540 -794
- package/dist/index.js.map +1 -1
- package/dist/polyfills/index.d.ts +1 -1
- package/dist/polyfills/index.d.ts.map +1 -1
- package/dist/polyfills/index.js +155 -9
- package/dist/polyfills/web3-polyfills.d.ts +7 -0
- package/dist/polyfills/web3-polyfills.d.ts.map +1 -0
- package/dist/polyfills/web3-polyfills.js +85 -0
- package/dist/providers/PersSDKProvider.d.ts +28 -18
- package/dist/providers/PersSDKProvider.d.ts.map +1 -1
- package/dist/providers/PersSDKProvider.js +63 -129
- package/dist/providers/react-native-auth-provider.d.ts +19 -64
- package/dist/providers/react-native-auth-provider.d.ts.map +1 -1
- package/dist/providers/react-native-auth-provider.js +57 -175
- package/package.json +177 -157
- package/src/hooks/index.ts +13 -1
- package/src/hooks/useAnalytics.ts +150 -0
- package/src/hooks/useAuth.ts +286 -27
- package/src/hooks/useBusiness.ts +193 -30
- package/src/hooks/useCampaigns.ts +121 -43
- package/src/hooks/useDonations.ts +68 -0
- package/src/hooks/useFiles.ts +160 -0
- package/src/hooks/usePurchases.ts +69 -0
- package/src/hooks/useRedemptions.ts +135 -68
- package/src/hooks/useTenants.ts +77 -0
- package/src/hooks/useTokens.ts +189 -21
- package/src/hooks/useTransactionSigner.ts +287 -0
- package/src/hooks/useTransactions.ts +163 -41
- package/src/hooks/useUserStatus.ts +65 -0
- package/src/hooks/useUsers.ts +133 -0
- package/src/hooks/useWeb3.ts +201 -21
- package/src/index.ts +22 -17
- package/src/polyfills/index.ts +163 -10
- package/src/polyfills/web3-polyfills.ts +98 -0
- package/src/providers/PersSDKProvider.tsx +114 -178
- package/src/providers/react-native-auth-provider.ts +65 -208
- package/dist/index.esm.js +0 -1057
- package/dist/index.esm.js.map +0 -1
- package/dist/polyfills/index.simple.d.ts +0 -2
- package/dist/polyfills/index.simple.d.ts.map +0 -1
- package/dist/polyfills/index.simple.js +0 -17
- package/src/polyfills/index.simple.ts +0 -22
- 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
|