@explorins/pers-sdk-react-native 1.5.30 → 1.5.32

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 (76) hide show
  1. package/README.md +9 -0
  2. package/dist/hooks/index.d.ts +2 -2
  3. package/dist/hooks/index.d.ts.map +1 -1
  4. package/dist/hooks/index.js +1 -1
  5. package/dist/hooks/useAnalytics.d.ts.map +1 -1
  6. package/dist/hooks/useAnalytics.js +0 -1
  7. package/dist/hooks/useAuth.d.ts +0 -1
  8. package/dist/hooks/useAuth.d.ts.map +1 -1
  9. package/dist/hooks/useAuth.js +5 -18
  10. package/dist/hooks/useBusiness.d.ts.map +1 -1
  11. package/dist/hooks/useBusiness.js +0 -9
  12. package/dist/hooks/useCampaigns.d.ts.map +1 -1
  13. package/dist/hooks/useCampaigns.js +0 -10
  14. package/dist/hooks/useDonations.d.ts.map +1 -1
  15. package/dist/hooks/useDonations.js +0 -1
  16. package/dist/hooks/useFiles.d.ts.map +1 -1
  17. package/dist/hooks/useFiles.js +0 -4
  18. package/dist/hooks/usePurchases.d.ts.map +1 -1
  19. package/dist/hooks/usePurchases.js +0 -3
  20. package/dist/hooks/useRedemptions.d.ts +4 -1
  21. package/dist/hooks/useRedemptions.d.ts.map +1 -1
  22. package/dist/hooks/useRedemptions.js +6 -17
  23. package/dist/hooks/useTenants.d.ts.map +1 -1
  24. package/dist/hooks/useTenants.js +0 -3
  25. package/dist/hooks/useTokens.d.ts.map +1 -1
  26. package/dist/hooks/useTokens.js +0 -6
  27. package/dist/hooks/useTransactionSigner.d.ts +13 -1
  28. package/dist/hooks/useTransactionSigner.d.ts.map +1 -1
  29. package/dist/hooks/useTransactionSigner.js +59 -2
  30. package/dist/hooks/useTransactions.d.ts +4 -1
  31. package/dist/hooks/useTransactions.d.ts.map +1 -1
  32. package/dist/hooks/useTransactions.js +9 -10
  33. package/dist/hooks/useUserStatus.d.ts.map +1 -1
  34. package/dist/hooks/useUserStatus.js +0 -3
  35. package/dist/hooks/useUsers.d.ts.map +1 -1
  36. package/dist/hooks/useUsers.js +0 -7
  37. package/dist/hooks/useWeb3.d.ts +26 -42
  38. package/dist/hooks/useWeb3.d.ts.map +1 -1
  39. package/dist/hooks/useWeb3.js +27 -53
  40. package/dist/index.d.ts +2 -1
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +330 -304
  43. package/dist/index.js.map +1 -1
  44. package/dist/providers/PersSDKProvider.d.ts +1 -3
  45. package/dist/providers/PersSDKProvider.d.ts.map +1 -1
  46. package/dist/providers/PersSDKProvider.js +14 -11
  47. package/dist/providers/react-native-auth-provider.d.ts.map +1 -1
  48. package/dist/providers/react-native-auth-provider.js +4 -0
  49. package/dist/providers/rn-dpop-provider.d.ts +2 -4
  50. package/dist/providers/rn-dpop-provider.d.ts.map +1 -1
  51. package/dist/providers/rn-dpop-provider.js +50 -23
  52. package/dist/storage/rn-secure-storage.d.ts +1 -0
  53. package/dist/storage/rn-secure-storage.d.ts.map +1 -1
  54. package/dist/storage/rn-secure-storage.js +9 -12
  55. package/package.json +2 -2
  56. package/src/hooks/index.ts +10 -2
  57. package/src/hooks/useAnalytics.ts +0 -1
  58. package/src/hooks/useAuth.ts +4 -25
  59. package/src/hooks/useBusiness.ts +0 -9
  60. package/src/hooks/useCampaigns.ts +0 -10
  61. package/src/hooks/useDonations.ts +0 -1
  62. package/src/hooks/useFiles.ts +0 -4
  63. package/src/hooks/usePurchases.ts +0 -3
  64. package/src/hooks/useRedemptions.ts +7 -21
  65. package/src/hooks/useTenants.ts +0 -3
  66. package/src/hooks/useTokens.ts +0 -6
  67. package/src/hooks/useTransactionSigner.ts +74 -4
  68. package/src/hooks/useTransactions.ts +10 -12
  69. package/src/hooks/useUserStatus.ts +0 -3
  70. package/src/hooks/useUsers.ts +0 -7
  71. package/src/hooks/useWeb3.ts +28 -68
  72. package/src/index.ts +4 -0
  73. package/src/providers/PersSDKProvider.tsx +19 -20
  74. package/src/providers/react-native-auth-provider.ts +5 -0
  75. package/src/providers/rn-dpop-provider.ts +85 -45
  76. package/src/storage/rn-secure-storage.ts +13 -13
package/dist/index.js CHANGED
@@ -32044,6 +32044,119 @@ class PersSDK {
32044
32044
  }
32045
32045
  }
32046
32046
 
32047
+ /**
32048
+ * AsyncStorage Token Storage for React Native Mobile Platforms
32049
+ *
32050
+ * Bundler-agnostic AsyncStorage implementation for mobile platforms
32051
+ */
32052
+ /**
32053
+ * Bundler-agnostic AsyncStorage wrapper
32054
+ * Handles different module resolution patterns across bundlers (Metro, Webpack, Rollup, etc.)
32055
+ */
32056
+ class BundlerAgnosticAsyncStorage {
32057
+ constructor(asyncStorageModule) {
32058
+ // Try different import patterns to handle various bundlers
32059
+ if (asyncStorageModule?.default?.getItem) {
32060
+ // Metro/Webpack pattern: { default: { getItem, setItem, ... } }
32061
+ this.storage = asyncStorageModule.default;
32062
+ }
32063
+ else if (asyncStorageModule?.getItem) {
32064
+ // Direct export pattern: { getItem, setItem, ... }
32065
+ this.storage = asyncStorageModule;
32066
+ }
32067
+ else if (typeof asyncStorageModule === 'function') {
32068
+ // Function export pattern (some bundlers)
32069
+ this.storage = asyncStorageModule();
32070
+ }
32071
+ else {
32072
+ // Log the structure for debugging
32073
+ console.error('[BundlerAgnosticAsyncStorage] Unknown AsyncStorage structure:', asyncStorageModule);
32074
+ throw new Error('AsyncStorage methods not found. Expected structure with getItem/setItem methods. ' +
32075
+ 'Make sure @react-native-async-storage/async-storage is properly installed.');
32076
+ }
32077
+ // Validate that we have the required methods
32078
+ const requiredMethods = ['getItem', 'setItem', 'removeItem', 'getAllKeys', 'multiRemove'];
32079
+ const missingMethods = requiredMethods.filter(method => typeof this.storage[method] !== 'function');
32080
+ if (missingMethods.length > 0) {
32081
+ throw new Error(`AsyncStorage missing required methods: ${missingMethods.join(', ')}. ` +
32082
+ 'Ensure @react-native-async-storage/async-storage is properly installed and compatible.');
32083
+ }
32084
+ }
32085
+ async getItem(key) {
32086
+ return this.storage.getItem(key);
32087
+ }
32088
+ async setItem(key, value) {
32089
+ return this.storage.setItem(key, value);
32090
+ }
32091
+ async removeItem(key) {
32092
+ return this.storage.removeItem(key);
32093
+ }
32094
+ async getAllKeys() {
32095
+ return this.storage.getAllKeys();
32096
+ }
32097
+ async multiRemove(keys) {
32098
+ return this.storage.multiRemove(keys);
32099
+ }
32100
+ }
32101
+ /**
32102
+ * AsyncStorage implementation for mobile platforms
32103
+ *
32104
+ * This class is only used on mobile platforms (iOS/Android).
32105
+ * Web platforms use LocalStorageTokenStorage from core SDK.
32106
+ */
32107
+ class AsyncStorageTokenStorage {
32108
+ constructor(keyPrefix = 'pers_tokens_') {
32109
+ this.keyPrefix = keyPrefix;
32110
+ try {
32111
+ // Initialize bundler-agnostic AsyncStorage wrapper
32112
+ this.asyncStorage = new BundlerAgnosticAsyncStorage(AsyncStorage);
32113
+ }
32114
+ catch (error) {
32115
+ console.error('[AsyncStorageTokenStorage] Failed to initialize:', error);
32116
+ throw new Error('Failed to initialize AsyncStorage. Make sure @react-native-async-storage/async-storage is installed and ' +
32117
+ 'this code is running on a React Native mobile platform (not web).');
32118
+ }
32119
+ }
32120
+ async set(key, value) {
32121
+ try {
32122
+ await this.asyncStorage.setItem(`${this.keyPrefix}${key}`, value);
32123
+ }
32124
+ catch (error) {
32125
+ console.error(`Failed to store token ${key}:`, error);
32126
+ throw new Error(`Token storage failed: ${error}`);
32127
+ }
32128
+ }
32129
+ async get(key) {
32130
+ try {
32131
+ return await this.asyncStorage.getItem(`${this.keyPrefix}${key}`);
32132
+ }
32133
+ catch (error) {
32134
+ console.error(`Failed to retrieve token ${key}:`, error);
32135
+ return null;
32136
+ }
32137
+ }
32138
+ async remove(key) {
32139
+ try {
32140
+ await this.asyncStorage.removeItem(`${this.keyPrefix}${key}`);
32141
+ }
32142
+ catch (error) {
32143
+ console.error(`Failed to remove token ${key}:`, error);
32144
+ }
32145
+ }
32146
+ async clear() {
32147
+ try {
32148
+ const allKeys = await this.asyncStorage.getAllKeys();
32149
+ const ourKeys = allKeys.filter(key => key.startsWith(this.keyPrefix));
32150
+ if (ourKeys.length > 0) {
32151
+ await this.asyncStorage.multiRemove(ourKeys);
32152
+ }
32153
+ }
32154
+ catch (error) {
32155
+ console.error('Failed to clear token storage:', error);
32156
+ }
32157
+ }
32158
+ }
32159
+
32047
32160
  // Conditionally require Keychain to avoid Web bundler errors
32048
32161
  let Keychain;
32049
32162
  if (reactNative.Platform.OS !== 'web') {
@@ -32070,6 +32183,7 @@ class ReactNativeSecureStorage {
32070
32183
  AUTH_STORAGE_KEYS.REFRESH_TOKEN,
32071
32184
  AUTH_STORAGE_KEYS.PROVIDER_TOKEN
32072
32185
  ]);
32186
+ this.fallbackStorage = new AsyncStorageTokenStorage(keyPrefix);
32073
32187
  }
32074
32188
  async set(key, value) {
32075
32189
  const prefixedKey = this.getKeyName(key);
@@ -32090,12 +32204,12 @@ class ReactNativeSecureStorage {
32090
32204
  catch (e) {
32091
32205
  console.warn(`[ReactNativeSecureStorage] Keychain set failed for ${key}, falling back to AsyncStorage`, e);
32092
32206
  // Fallback to AsyncStorage if Keychain fails
32093
- await AsyncStorage.setItem(prefixedKey, stringValue);
32207
+ await this.fallbackStorage.set(key, stringValue);
32094
32208
  }
32095
32209
  }
32096
32210
  else {
32097
32211
  // Store standard config/metadata in AsyncStorage
32098
- await AsyncStorage.setItem(prefixedKey, stringValue);
32212
+ await this.fallbackStorage.set(key, stringValue);
32099
32213
  }
32100
32214
  }
32101
32215
  async get(key) {
@@ -32115,7 +32229,7 @@ class ReactNativeSecureStorage {
32115
32229
  }
32116
32230
  // Fallback: Check AsyncStorage if not found in Keychain or Keychain failed
32117
32231
  try {
32118
- const val = await AsyncStorage.getItem(prefixedKey);
32232
+ const val = await this.fallbackStorage.get(key);
32119
32233
  return val ? this.tryParse(val) : null;
32120
32234
  }
32121
32235
  catch (e) {
@@ -32124,7 +32238,7 @@ class ReactNativeSecureStorage {
32124
32238
  }
32125
32239
  else {
32126
32240
  try {
32127
- const val = await AsyncStorage.getItem(prefixedKey);
32241
+ const val = await this.fallbackStorage.get(key);
32128
32242
  return val ? this.tryParse(val) : null;
32129
32243
  }
32130
32244
  catch (e) {
@@ -32145,10 +32259,10 @@ class ReactNativeSecureStorage {
32145
32259
  console.warn(`[ReactNativeSecureStorage] Failed to reset keychain for ${key}`, e);
32146
32260
  }
32147
32261
  // Always remove from fallback storage too, just in case
32148
- await AsyncStorage.removeItem(prefixedKey);
32262
+ await this.fallbackStorage.remove(key);
32149
32263
  }
32150
32264
  else {
32151
- await AsyncStorage.removeItem(prefixedKey);
32265
+ await this.fallbackStorage.remove(key);
32152
32266
  }
32153
32267
  }
32154
32268
  async clear() {
@@ -32165,11 +32279,7 @@ class ReactNativeSecureStorage {
32165
32279
  }
32166
32280
  // Clear AsyncStorage keys related to PERS
32167
32281
  try {
32168
- const allKeys = await AsyncStorage.getAllKeys();
32169
- const ourKeys = allKeys.filter(k => k.startsWith(this.keyPrefix));
32170
- if (ourKeys.length > 0) {
32171
- await AsyncStorage.multiRemove(ourKeys);
32172
- }
32282
+ await this.fallbackStorage.clear();
32173
32283
  }
32174
32284
  catch (e) {
32175
32285
  console.warn('[ReactNativeSecureStorage] Failed to clear AsyncStorage', e);
@@ -32225,6 +32335,10 @@ function createReactNativeAuthProvider(projectKey, config = {}) {
32225
32335
  enabled: dpop.enabled ?? true,
32226
32336
  cryptoProvider: dpop.cryptoProvider
32227
32337
  } : undefined;
32338
+ // DEBUG LOGGING
32339
+ if (debug) {
32340
+ console.log('[ReactNativeAuthProvider] Creating provider with DPoP config:', JSON.stringify(dpopConfig));
32341
+ }
32228
32342
  // Return DefaultAuthProvider configured with platform-appropriate storage
32229
32343
  return new DefaultAuthProvider({
32230
32344
  authType,
@@ -32234,119 +32348,6 @@ function createReactNativeAuthProvider(projectKey, config = {}) {
32234
32348
  });
32235
32349
  }
32236
32350
 
32237
- /**
32238
- * AsyncStorage Token Storage for React Native Mobile Platforms
32239
- *
32240
- * Bundler-agnostic AsyncStorage implementation for mobile platforms
32241
- */
32242
- /**
32243
- * Bundler-agnostic AsyncStorage wrapper
32244
- * Handles different module resolution patterns across bundlers (Metro, Webpack, Rollup, etc.)
32245
- */
32246
- class BundlerAgnosticAsyncStorage {
32247
- constructor(asyncStorageModule) {
32248
- // Try different import patterns to handle various bundlers
32249
- if (asyncStorageModule?.default?.getItem) {
32250
- // Metro/Webpack pattern: { default: { getItem, setItem, ... } }
32251
- this.storage = asyncStorageModule.default;
32252
- }
32253
- else if (asyncStorageModule?.getItem) {
32254
- // Direct export pattern: { getItem, setItem, ... }
32255
- this.storage = asyncStorageModule;
32256
- }
32257
- else if (typeof asyncStorageModule === 'function') {
32258
- // Function export pattern (some bundlers)
32259
- this.storage = asyncStorageModule();
32260
- }
32261
- else {
32262
- // Log the structure for debugging
32263
- console.error('[BundlerAgnosticAsyncStorage] Unknown AsyncStorage structure:', asyncStorageModule);
32264
- throw new Error('AsyncStorage methods not found. Expected structure with getItem/setItem methods. ' +
32265
- 'Make sure @react-native-async-storage/async-storage is properly installed.');
32266
- }
32267
- // Validate that we have the required methods
32268
- const requiredMethods = ['getItem', 'setItem', 'removeItem', 'getAllKeys', 'multiRemove'];
32269
- const missingMethods = requiredMethods.filter(method => typeof this.storage[method] !== 'function');
32270
- if (missingMethods.length > 0) {
32271
- throw new Error(`AsyncStorage missing required methods: ${missingMethods.join(', ')}. ` +
32272
- 'Ensure @react-native-async-storage/async-storage is properly installed and compatible.');
32273
- }
32274
- }
32275
- async getItem(key) {
32276
- return this.storage.getItem(key);
32277
- }
32278
- async setItem(key, value) {
32279
- return this.storage.setItem(key, value);
32280
- }
32281
- async removeItem(key) {
32282
- return this.storage.removeItem(key);
32283
- }
32284
- async getAllKeys() {
32285
- return this.storage.getAllKeys();
32286
- }
32287
- async multiRemove(keys) {
32288
- return this.storage.multiRemove(keys);
32289
- }
32290
- }
32291
- /**
32292
- * AsyncStorage implementation for mobile platforms
32293
- *
32294
- * This class is only used on mobile platforms (iOS/Android).
32295
- * Web platforms use LocalStorageTokenStorage from core SDK.
32296
- */
32297
- class AsyncStorageTokenStorage {
32298
- constructor(keyPrefix = 'pers_tokens_') {
32299
- this.keyPrefix = keyPrefix;
32300
- try {
32301
- // Initialize bundler-agnostic AsyncStorage wrapper
32302
- this.asyncStorage = new BundlerAgnosticAsyncStorage(AsyncStorage);
32303
- }
32304
- catch (error) {
32305
- console.error('[AsyncStorageTokenStorage] Failed to initialize:', error);
32306
- throw new Error('Failed to initialize AsyncStorage. Make sure @react-native-async-storage/async-storage is installed and ' +
32307
- 'this code is running on a React Native mobile platform (not web).');
32308
- }
32309
- }
32310
- async set(key, value) {
32311
- try {
32312
- await this.asyncStorage.setItem(`${this.keyPrefix}${key}`, value);
32313
- }
32314
- catch (error) {
32315
- console.error(`Failed to store token ${key}:`, error);
32316
- throw new Error(`Token storage failed: ${error}`);
32317
- }
32318
- }
32319
- async get(key) {
32320
- try {
32321
- return await this.asyncStorage.getItem(`${this.keyPrefix}${key}`);
32322
- }
32323
- catch (error) {
32324
- console.error(`Failed to retrieve token ${key}:`, error);
32325
- return null;
32326
- }
32327
- }
32328
- async remove(key) {
32329
- try {
32330
- await this.asyncStorage.removeItem(`${this.keyPrefix}${key}`);
32331
- }
32332
- catch (error) {
32333
- console.error(`Failed to remove token ${key}:`, error);
32334
- }
32335
- }
32336
- async clear() {
32337
- try {
32338
- const allKeys = await this.asyncStorage.getAllKeys();
32339
- const ourKeys = allKeys.filter(key => key.startsWith(this.keyPrefix));
32340
- if (ourKeys.length > 0) {
32341
- await this.asyncStorage.multiRemove(ourKeys);
32342
- }
32343
- }
32344
- catch (error) {
32345
- console.error('Failed to clear token storage:', error);
32346
- }
32347
- }
32348
- }
32349
-
32350
32351
  // Conditionally require quick-crypto for Native platforms only
32351
32352
  let crypto$1;
32352
32353
  if (reactNative.Platform.OS !== 'web') {
@@ -32359,7 +32360,6 @@ if (reactNative.Platform.OS !== 'web') {
32359
32360
  }
32360
32361
  else {
32361
32362
  // on Web, we shouldn't be using this provider anyway (Core SDK has WebDPoPProvider)
32362
- // But to be safe, we can mock or throw
32363
32363
  crypto$1 = {
32364
32364
  generateKeyPair: () => { throw new Error('ReactNativeDPoPProvider not supported on Web'); }
32365
32365
  };
@@ -32368,26 +32368,39 @@ class ReactNativeDPoPProvider {
32368
32368
  /**
32369
32369
  * Generates a new key pair (ES256 recommended)
32370
32370
  *
32371
- * Note: options.extractable is ignored because for React Native Keychain storage,
32372
- * we MUST export the keys as JWK/strings. We rely on the Keychain encryption
32373
- * for security at rest (High Security), making the key "Extractable" in memory
32374
- * but protected by hardware encryption when stored.
32371
+ * Uses WebCrypto API (crypto.subtle) for cross-platform compatibility.
32372
+ * Falls back to Node.js crypto API on iOS if needed.
32375
32373
  */
32376
32374
  async generateKeyPair(options) {
32377
- // Generate P-256 Key Pair
32375
+ // Try WebCrypto API first (works on both iOS and Android)
32376
+ if (crypto$1.subtle) {
32377
+ try {
32378
+ const keyPair = await crypto$1.subtle.generateKey({ name: 'ECDSA', namedCurve: 'P-256' }, true, // extractable - required for JWK export
32379
+ ['sign', 'verify']);
32380
+ const publicKeyJwk = await crypto$1.subtle.exportKey('jwk', keyPair.publicKey);
32381
+ const privateKeyJwk = await crypto$1.subtle.exportKey('jwk', keyPair.privateKey);
32382
+ return {
32383
+ publicKey: publicKeyJwk,
32384
+ privateKey: privateKeyJwk
32385
+ };
32386
+ }
32387
+ catch (err) {
32388
+ console.warn('[DPoP] WebCrypto API failed, trying Node.js crypto API', err);
32389
+ }
32390
+ }
32391
+ // Fallback: Node.js crypto API (works on iOS)
32378
32392
  return new Promise((resolve, reject) => {
32379
32393
  crypto$1.generateKeyPair('ec', { namedCurve: 'P-256' }, (err, publicKey, privateKey) => {
32380
32394
  if (err)
32381
32395
  return reject(err);
32382
- // Export to JWK for SDK Compatibility
32383
- // We use 'export' because supportsObjects=false in our storage forces the SDK
32384
- // to expect serializable keys.
32385
- const pubJwk = publicKey.export({ format: 'jwk' });
32386
- const privJwk = privateKey.export({ format: 'jwk' });
32387
- resolve({
32388
- publicKey: pubJwk,
32389
- privateKey: privJwk
32390
- });
32396
+ try {
32397
+ const pJwk = publicKey.export({ format: 'jwk' });
32398
+ const prJwk = privateKey.export({ format: 'jwk' });
32399
+ resolve({ publicKey: pJwk, privateKey: prJwk });
32400
+ }
32401
+ catch (exportErr) {
32402
+ reject(exportErr);
32403
+ }
32391
32404
  });
32392
32405
  });
32393
32406
  }
@@ -32408,21 +32421,37 @@ class ReactNativeDPoPProvider {
32408
32421
  const b64Header = this.base64Url(JSON.stringify(header));
32409
32422
  const b64Payload = this.base64Url(JSON.stringify(finalPayload));
32410
32423
  const signingInput = `${b64Header}.${b64Payload}`;
32411
- // 4. Sign
32424
+ // 4. Sign - try WebCrypto first, fallback to Node.js crypto
32425
+ if (crypto$1.subtle) {
32426
+ try {
32427
+ const privateKey = await crypto$1.subtle.importKey('jwk', keyPair.privateKey, { name: 'ECDSA', namedCurve: 'P-256' }, false, ['sign']);
32428
+ const signatureBuffer = await crypto$1.subtle.sign({ name: 'ECDSA', hash: 'SHA-256' }, privateKey, buffer.Buffer.from(signingInput));
32429
+ // WebCrypto returns signature in IEEE P1363 format (r || s), which is what we need for JWT
32430
+ return `${signingInput}.${this.base64UrlBuffer(buffer.Buffer.from(signatureBuffer))}`;
32431
+ }
32432
+ catch (err) {
32433
+ console.warn('[DPoP] WebCrypto sign failed, trying Node.js crypto', err);
32434
+ }
32435
+ }
32436
+ // Fallback: Node.js crypto API
32412
32437
  const sign = crypto$1.createSign('SHA256');
32413
32438
  sign.update(signingInput);
32414
- // sign.end() is not required/available in quick-crypto as it doesn't strictly follow stream interface
32415
- // Import private key back from JWK to sign
32416
- // The keyPair.privateKey is a JsonWebKey object because we exported it earlier.
32417
- // quick-crypto createPrivateKey expects jwk object if format is jwk
32418
32439
  const privateKeyObj = crypto$1.createPrivateKey({ key: keyPair.privateKey, format: 'jwk' });
32419
32440
  const signature = sign.sign(privateKeyObj);
32420
- // signature is a Buffer in quick-crypto
32421
32441
  return `${signingInput}.${this.base64UrlBuffer(signature)}`;
32422
32442
  }
32423
32443
  async hashAccessToken(accessToken) {
32444
+ // Try WebCrypto first
32445
+ if (crypto$1.subtle) {
32446
+ try {
32447
+ const hashBuffer = await crypto$1.subtle.digest('SHA-256', buffer.Buffer.from(accessToken));
32448
+ return this.base64UrlBuffer(buffer.Buffer.from(hashBuffer));
32449
+ }
32450
+ catch (err) {
32451
+ // Fallback to Node.js crypto
32452
+ }
32453
+ }
32424
32454
  const hash = crypto$1.createHash('sha256').update(accessToken).digest();
32425
- // digest returns Buffer in quick-crypto
32426
32455
  return this.base64UrlBuffer(hash);
32427
32456
  }
32428
32457
  // --- Helpers ---
@@ -32430,7 +32459,6 @@ class ReactNativeDPoPProvider {
32430
32459
  return this.base64UrlBuffer(buffer.Buffer.from(str));
32431
32460
  }
32432
32461
  base64UrlBuffer(buf) {
32433
- // Ensure we have a Buffer
32434
32462
  const buffer$1 = buffer.Buffer.isBuffer(buf) ? buf : buffer.Buffer.from(buf);
32435
32463
  return buffer$1.toString('base64')
32436
32464
  .replace(/=/g, '')
@@ -32544,7 +32572,6 @@ const PersSDKProvider = ({ children, config }) => {
32544
32572
  const [isInitialized, setIsInitialized] = react.useState(false);
32545
32573
  const [isAuthenticated, setIsAuthenticated] = react.useState(false);
32546
32574
  const [user, setUser] = react.useState(null);
32547
- const [accountAddress, setAccountAddress] = react.useState(null);
32548
32575
  const initialize = react.useCallback(async (config) => {
32549
32576
  // Prevent multiple initializations
32550
32577
  if (isInitialized || initializingRef.current) {
@@ -32554,8 +32581,7 @@ const PersSDKProvider = ({ children, config }) => {
32554
32581
  try {
32555
32582
  // Create HTTP client
32556
32583
  const httpClient = new ReactNativeHttpClient();
32557
- // Ensure DPoP is enabled by default for all platforms
32558
- const dpopConfig = config.dpop || {};
32584
+ const dpopConfig = config.dpop ?? {};
32559
32585
  const isDpopEnabled = dpopConfig.enabled ?? true;
32560
32586
  // Prepare DPoP settings for Auth Provider
32561
32587
  const dpopSettings = {
@@ -32607,9 +32633,8 @@ const PersSDKProvider = ({ children, config }) => {
32607
32633
  });
32608
32634
  }
32609
32635
  }, [config, isInitialized, initialize]);
32610
- const setAuthenticationState = react.useCallback((user, accountAddress, isAuthenticated) => {
32636
+ const setAuthenticationState = react.useCallback((user, isAuthenticated) => {
32611
32637
  setUser(user);
32612
- setAccountAddress(accountAddress);
32613
32638
  setIsAuthenticated(isAuthenticated);
32614
32639
  }, []);
32615
32640
  const refreshUserData = react.useCallback(async () => {
@@ -32625,7 +32650,7 @@ const PersSDKProvider = ({ children, config }) => {
32625
32650
  throw error;
32626
32651
  }
32627
32652
  }, [sdk, isAuthenticated, isInitialized]);
32628
- const contextValue = {
32653
+ const contextValue = react.useMemo(() => ({
32629
32654
  // Main SDK instance
32630
32655
  sdk,
32631
32656
  // Manager shortcuts for convenience
@@ -32640,20 +32665,26 @@ const PersSDKProvider = ({ children, config }) => {
32640
32665
  tenants: sdk?.tenants || null,
32641
32666
  analytics: sdk?.analytics || null,
32642
32667
  donations: sdk?.donations || null,
32643
- // Legacy support (deprecated but kept for backward compatibility)
32644
- business: sdk?.businesses || null,
32645
32668
  // Platform-specific providers
32646
32669
  authProvider,
32647
32670
  // State
32648
32671
  isInitialized,
32649
32672
  isAuthenticated,
32650
32673
  user,
32651
- accountAddress,
32652
32674
  // Methods
32653
32675
  initialize,
32654
32676
  setAuthenticationState,
32655
32677
  refreshUserData,
32656
- };
32678
+ }), [
32679
+ sdk,
32680
+ authProvider,
32681
+ isInitialized,
32682
+ isAuthenticated,
32683
+ user,
32684
+ initialize,
32685
+ setAuthenticationState,
32686
+ refreshUserData
32687
+ ]);
32657
32688
  return (jsxRuntime.jsx(SDKContext.Provider, { value: contextValue, children: children }));
32658
32689
  };
32659
32690
  // Custom hook to use the SDK context
@@ -32703,7 +32734,7 @@ const usePersSDK = () => {
32703
32734
  * ```
32704
32735
  */
32705
32736
  const useAuth = () => {
32706
- const { sdk, authProvider, isInitialized, isAuthenticated, user, accountAddress, setAuthenticationState, refreshUserData } = usePersSDK();
32737
+ const { sdk, authProvider, isInitialized, isAuthenticated, user, setAuthenticationState, refreshUserData } = usePersSDK();
32707
32738
  /**
32708
32739
  * Authenticates a user with a JWT token
32709
32740
  *
@@ -32724,18 +32755,13 @@ const useAuth = () => {
32724
32755
  throw new Error('SDK not initialized. Call initialize() first.');
32725
32756
  }
32726
32757
  try {
32727
- console.log(`Logging in as ${userType}...`);
32728
32758
  // Set token in auth provider
32729
32759
  await authProvider.setAccessToken(jwtToken);
32730
32760
  // Perform login using the manager
32731
32761
  const result = await sdk.auth.loginWithToken(jwtToken, userType);
32732
32762
  const userData = result.user || result.admin;
32733
32763
  if (userData) {
32734
- const userAccountAddress = ('accountAddress' in userData && userData.accountAddress) ||
32735
- ('wallets' in userData && userData.wallets?.[0]?.address) ||
32736
- null;
32737
- setAuthenticationState(userData, userAccountAddress, true);
32738
- console.log('Login successful');
32764
+ setAuthenticationState(userData, true);
32739
32765
  return result;
32740
32766
  }
32741
32767
  else {
@@ -32764,7 +32790,6 @@ const useAuth = () => {
32764
32790
  throw new Error('SDK not initialized. Call initialize() first.');
32765
32791
  }
32766
32792
  try {
32767
- console.log('Logging in with raw user data...');
32768
32793
  // Use the raw data login from the auth manager
32769
32794
  const result = await sdk.auth.loginWithRawData(rawUserData);
32770
32795
  // Set token from result
@@ -32773,11 +32798,7 @@ const useAuth = () => {
32773
32798
  }
32774
32799
  const userData = result.user;
32775
32800
  if (userData) {
32776
- const userAccountAddress = userData.accountAddress ||
32777
- userData?.wallets?.[0]?.address ||
32778
- null;
32779
- setAuthenticationState(userData, userAccountAddress, true);
32780
- console.log('Raw data login successful');
32801
+ setAuthenticationState(userData, true);
32781
32802
  }
32782
32803
  else {
32783
32804
  throw new Error('No user data returned from raw data login');
@@ -32802,12 +32823,10 @@ const useAuth = () => {
32802
32823
  */
32803
32824
  const logout = react.useCallback(async () => {
32804
32825
  try {
32805
- console.log('Logging out...');
32806
32826
  if (authProvider) {
32807
32827
  await authProvider.clearTokens();
32808
32828
  }
32809
- setAuthenticationState(null, null, false);
32810
- console.log('Logout successful');
32829
+ setAuthenticationState(null, false);
32811
32830
  }
32812
32831
  catch (error) {
32813
32832
  console.error('Logout failed:', error);
@@ -32888,7 +32907,7 @@ const useAuth = () => {
32888
32907
  throw new Error('SDK not initialized. Call initialize() first.');
32889
32908
  }
32890
32909
  await sdk.auth.clearAuth();
32891
- setAuthenticationState(null, null, false);
32910
+ setAuthenticationState(null, false);
32892
32911
  }, [sdk, setAuthenticationState]);
32893
32912
  /**
32894
32913
  * Checks if the current authentication is valid (non-expired)
@@ -32913,7 +32932,6 @@ const useAuth = () => {
32913
32932
  isInitialized,
32914
32933
  isAuthenticated,
32915
32934
  user,
32916
- accountAddress,
32917
32935
  // Methods
32918
32936
  login,
32919
32937
  loginWithRawData,
@@ -32979,7 +32997,6 @@ const useTokens = () => {
32979
32997
  }
32980
32998
  try {
32981
32999
  const result = await sdk.tokens.getTokens();
32982
- console.log('Tokens fetched successfully:', result);
32983
33000
  return result;
32984
33001
  }
32985
33002
  catch (error) {
@@ -33006,7 +33023,6 @@ const useTokens = () => {
33006
33023
  }
33007
33024
  try {
33008
33025
  const result = await sdk.tokens.getActiveCreditToken();
33009
- console.log('Active credit token fetched successfully:', result);
33010
33026
  return result;
33011
33027
  }
33012
33028
  catch (error) {
@@ -33033,7 +33049,6 @@ const useTokens = () => {
33033
33049
  }
33034
33050
  try {
33035
33051
  const result = await sdk.tokens.getRewardTokens();
33036
- console.log('Reward tokens fetched successfully:', result);
33037
33052
  return result;
33038
33053
  }
33039
33054
  catch (error) {
@@ -33060,7 +33075,6 @@ const useTokens = () => {
33060
33075
  }
33061
33076
  try {
33062
33077
  const result = await sdk.tokens.getTokenTypes();
33063
- console.log('Token types fetched successfully:', result);
33064
33078
  return result;
33065
33079
  }
33066
33080
  catch (error) {
@@ -33087,7 +33101,6 @@ const useTokens = () => {
33087
33101
  }
33088
33102
  try {
33089
33103
  const result = await sdk.tokens.getStatusTokens();
33090
- console.log('Status tokens fetched successfully:', result);
33091
33104
  return result;
33092
33105
  }
33093
33106
  catch (error) {
@@ -33116,7 +33129,6 @@ const useTokens = () => {
33116
33129
  }
33117
33130
  try {
33118
33131
  const result = await sdk.tokens.getTokenByContract(contractAddress, contractTokenId);
33119
- console.log('Token by contract fetched successfully:', result);
33120
33132
  return result;
33121
33133
  }
33122
33134
  catch (error) {
@@ -33135,6 +33147,45 @@ const useTokens = () => {
33135
33147
  };
33136
33148
  };
33137
33149
 
33150
+ /**
33151
+ * Transaction statuses that allow signing
33152
+ */
33153
+ [exports.TransactionStatus.PENDING_SIGNATURE, exports.TransactionStatus.CREATED];
33154
+
33155
+ /**
33156
+ * Error codes for transaction signing operations
33157
+ */
33158
+ var TransactionSigningErrorCode;
33159
+ (function (TransactionSigningErrorCode) {
33160
+ TransactionSigningErrorCode["INVALID_TOKENS"] = "INVALID_TOKENS";
33161
+ TransactionSigningErrorCode["TRANSACTION_NOT_FOUND"] = "TRANSACTION_NOT_FOUND";
33162
+ TransactionSigningErrorCode["TRANSACTION_NOT_PENDING"] = "TRANSACTION_NOT_PENDING";
33163
+ TransactionSigningErrorCode["WALLET_NOT_AVAILABLE"] = "WALLET_NOT_AVAILABLE";
33164
+ TransactionSigningErrorCode["WEBAUTHN_OPERATION_IN_PROGRESS"] = "WEBAUTHN_OPERATION_IN_PROGRESS";
33165
+ TransactionSigningErrorCode["SIGNING_CANCELLED"] = "SIGNING_CANCELLED";
33166
+ TransactionSigningErrorCode["PERS_AUTH_FAILED"] = "PERS_AUTH_FAILED";
33167
+ TransactionSigningErrorCode["AUTH_FAILED"] = "AUTH_FAILED";
33168
+ TransactionSigningErrorCode["TRANSACTION_NOT_READY"] = "TRANSACTION_NOT_READY";
33169
+ TransactionSigningErrorCode["SUBMISSION_FAILED"] = "SUBMISSION_FAILED";
33170
+ TransactionSigningErrorCode["SERVER_ERROR"] = "SERVER_ERROR";
33171
+ TransactionSigningErrorCode["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
33172
+ })(TransactionSigningErrorCode || (TransactionSigningErrorCode = {}));
33173
+
33174
+ /**
33175
+ * Signing status types for type-safe status updates
33176
+ * Using const pattern instead of enum for better bundling compatibility
33177
+ */
33178
+ const SigningStatus = {
33179
+ INITIALIZING: 'initializing',
33180
+ AUTHENTICATING: 'authenticating',
33181
+ PREPARING: 'preparing',
33182
+ SIGNING: 'signing',
33183
+ SUBMITTING: 'submitting',
33184
+ COMPLETED: 'completed',
33185
+ ERROR: 'error',
33186
+ EXPIRED: 'expired'
33187
+ };
33188
+
33138
33189
  // Dynamic import the signer SDK to avoid build issues with static dependencies
33139
33190
  let createPersSignerSDK = null;
33140
33191
  try {
@@ -33327,6 +33378,8 @@ const DEFAULT_ETHERS_PROVIDER = "https://sepolia.infura.io/v3/2781b4b5242343d5b0
33327
33378
  const useTransactionSigner = () => {
33328
33379
  // const { isInitialized, isAuthenticated, user } = usePersSDK();
33329
33380
  const [isSignerInitialized, setIsSignerInitialized] = react.useState(false);
33381
+ const [currentStatus, setCurrentStatus] = react.useState(null);
33382
+ const [statusMessage, setStatusMessage] = react.useState(null);
33330
33383
  const signerSDKRef = react.useRef(null);
33331
33384
  // Auto-initialize signer SDK when PERS SDK is ready
33332
33385
  react.useEffect(() => {
@@ -33375,6 +33428,7 @@ const useTransactionSigner = () => {
33375
33428
  *
33376
33429
  * @param {string} jwt - JWT token containing transaction ID and user information
33377
33430
  * Must include: `transactionId`, `identifierEmail`, `tenantId`
33431
+ * @param {StatusCallback} [onStatusUpdate] - Optional callback for real-time status updates
33378
33432
  * @returns {Promise<SubmissionResult>} Complete transaction result
33379
33433
  *
33380
33434
  * @throws {Error} 'Transaction signer not initialized' - Hook not ready
@@ -33397,6 +33451,15 @@ const useTransactionSigner = () => {
33397
33451
  * ```
33398
33452
  *
33399
33453
  * @example
33454
+ * **With Status Updates:**
33455
+ * ```typescript
33456
+ * const result = await signAndSubmitTransactionWithJWT(jwtToken, (status, message) => {
33457
+ * console.log(`Status: ${status} - ${message}`);
33458
+ * setStatusText(message);
33459
+ * });
33460
+ * ```
33461
+ *
33462
+ * @example
33400
33463
  * **With Error Handling:**
33401
33464
  * ```typescript
33402
33465
  * try {
@@ -33431,20 +33494,30 @@ const useTransactionSigner = () => {
33431
33494
  *
33432
33495
  * @see {@link SubmissionResult} for detailed result structure
33433
33496
  */
33434
- const signAndSubmitTransactionWithJWT = react.useCallback(async (jwt) => {
33497
+ const signAndSubmitTransactionWithJWT = react.useCallback(async (jwt, onStatusUpdate) => {
33435
33498
  if (!isSignerInitialized || !signerSDKRef.current) {
33436
33499
  throw new Error('Transaction signer not initialized');
33437
33500
  }
33438
33501
  if (!createPersSignerSDK) {
33439
33502
  throw new Error('PERS Signer SDK not available. Blockchain signing is not supported.');
33440
33503
  }
33504
+ // Create status callback wrapper that updates both hook state and calls user callback
33505
+ const statusCallback = {
33506
+ onStatusUpdate: (status, message, data) => {
33507
+ setCurrentStatus(status);
33508
+ setStatusMessage(message);
33509
+ onStatusUpdate?.(status, message, data);
33510
+ }
33511
+ };
33441
33512
  try {
33442
33513
  // Use the actual SDK method that handles the complete sign + submit flow
33443
- const submissionResult = await signerSDKRef.current.signAndSubmitPersTransaction(jwt);
33514
+ const submissionResult = await signerSDKRef.current.signAndSubmitPersTransaction(jwt, statusCallback);
33444
33515
  return submissionResult;
33445
33516
  }
33446
33517
  catch (error) {
33447
33518
  console.error('[useTransactionSigner] JWT transaction signing failed:', error);
33519
+ setCurrentStatus(SigningStatus.ERROR);
33520
+ setStatusMessage(error instanceof Error ? error.message : 'Transaction failed');
33448
33521
  throw error; // Re-throw to maintain error handling upstream
33449
33522
  }
33450
33523
  }, [isSignerInitialized]);
@@ -33456,6 +33529,7 @@ const useTransactionSigner = () => {
33456
33529
  * from authentication to blockchain submission in a single call.
33457
33530
  *
33458
33531
  * @param {string} jwt - JWT token with transaction and user data
33532
+ * @param {StatusCallback} [onStatusUpdate] - Optional callback for real-time status updates
33459
33533
  * @returns {Promise<SubmissionResult>} Transaction result with hash and status
33460
33534
  */
33461
33535
  signAndSubmitTransactionWithJWT,
@@ -33501,6 +33575,36 @@ const useTransactionSigner = () => {
33501
33575
  * ```
33502
33576
  */
33503
33577
  isSignerAvailable: isSignerInitialized && !!createPersSignerSDK,
33578
+ /**
33579
+ * Current signing status for UI feedback
33580
+ *
33581
+ * Tracks the current state of the signing process. Use this to show
33582
+ * progress indicators or status messages during transaction signing.
33583
+ *
33584
+ * Possible values: 'initializing', 'authenticating', 'preparing',
33585
+ * 'signing', 'submitting', 'completed', 'error', 'expired'
33586
+ *
33587
+ * @example
33588
+ * ```typescript
33589
+ * const { currentStatus, statusMessage } = useTransactionSigner();
33590
+ *
33591
+ * return (
33592
+ * <View>
33593
+ * {currentStatus && (
33594
+ * <Text>Status: {statusMessage}</Text>
33595
+ * )}
33596
+ * </View>
33597
+ * );
33598
+ * ```
33599
+ */
33600
+ currentStatus,
33601
+ /**
33602
+ * Human-readable status message
33603
+ *
33604
+ * Provides a user-friendly description of the current signing status.
33605
+ * Updates in real-time as the transaction progresses.
33606
+ */
33607
+ statusMessage,
33504
33608
  };
33505
33609
  };
33506
33610
 
@@ -33542,7 +33646,7 @@ const useTransactionSigner = () => {
33542
33646
  */
33543
33647
  const useTransactions = () => {
33544
33648
  const { sdk, isInitialized, isAuthenticated } = usePersSDK();
33545
- const { signAndSubmitTransactionWithJWT, isSignerAvailable } = useTransactionSigner();
33649
+ const { signAndSubmitTransactionWithJWT, isSignerAvailable, currentStatus, statusMessage } = useTransactionSigner();
33546
33650
  if (!isAuthenticated && isInitialized) {
33547
33651
  console.warn('SDK not authenticated. Some transaction operations may fail.');
33548
33652
  }
@@ -33564,29 +33668,29 @@ const useTransactions = () => {
33564
33668
  * recipient: '0x123...',
33565
33669
  * tokenId: 'token-123'
33566
33670
  * };
33567
- * const result = await createTransaction(request);
33671
+ * const result = await createTransaction(request, (status, message) => {
33672
+ * console.log(`Status: ${status} - ${message}`);
33673
+ * });
33568
33674
  * console.log('Transaction created:', result);
33569
33675
  * ```
33570
33676
  */
33571
- const createTransaction = react.useCallback(async (request) => {
33677
+ const createTransaction = react.useCallback(async (request, onStatusUpdate) => {
33572
33678
  if (!isInitialized || !sdk) {
33573
33679
  throw new Error('SDK not initialized. Call initialize() first.');
33574
33680
  }
33575
33681
  try {
33576
33682
  const result = await sdk.transactions.createTransaction(request);
33577
- console.log('Transaction created successfully:', result);
33578
33683
  // Check if transaction requires signing (contains actionable authToken)
33579
33684
  // Type assertion needed as TransactionRequestResponseDTO type may not include all dynamic properties
33580
33685
  const txToken = result?.actionable?.authToken;
33581
33686
  if (txToken) {
33582
- console.log('[useTransactions] Transaction requires signing, attempting automatic signature...');
33583
33687
  try {
33584
33688
  if (!isSignerAvailable) {
33585
33689
  console.warn('[useTransactions] Transaction signer not available, skipping automatic signing');
33586
33690
  return result;
33587
33691
  }
33588
33692
  // Automatically sign the transaction using the authToken
33589
- const signingResult = await signAndSubmitTransactionWithJWT(txToken);
33693
+ const signingResult = await signAndSubmitTransactionWithJWT(txToken, onStatusUpdate);
33590
33694
  if (signingResult.success) {
33591
33695
  console.log('[useTransactions] Transaction signed successfully:', signingResult.transactionHash);
33592
33696
  // Return the original result - the transaction is now signed and will be processed
@@ -33631,7 +33735,6 @@ const useTransactions = () => {
33631
33735
  }
33632
33736
  try {
33633
33737
  const result = await sdk.transactions.getTransactionById(transactionId);
33634
- console.log('Transaction fetched successfully:', result);
33635
33738
  return result;
33636
33739
  }
33637
33740
  catch (error) {
@@ -33659,7 +33762,6 @@ const useTransactions = () => {
33659
33762
  }
33660
33763
  try {
33661
33764
  const result = await sdk.transactions.getUserTransactionHistory(role);
33662
- console.log('Transaction history fetched successfully:', result);
33663
33765
  return result;
33664
33766
  }
33665
33767
  catch (error) {
@@ -33686,7 +33788,6 @@ const useTransactions = () => {
33686
33788
  }
33687
33789
  try {
33688
33790
  const result = await sdk.transactions.getPaginatedTransactions(params);
33689
- console.log('Paginated transactions fetched successfully:', result);
33690
33791
  return result;
33691
33792
  }
33692
33793
  catch (error) {
@@ -33700,7 +33801,6 @@ const useTransactions = () => {
33700
33801
  }
33701
33802
  try {
33702
33803
  const result = await sdk.transactions.exportTransactionsCSV();
33703
- console.log('Transactions CSV exported successfully');
33704
33804
  return result;
33705
33805
  }
33706
33806
  catch (error) {
@@ -33716,6 +33816,9 @@ const useTransactions = () => {
33716
33816
  getPaginatedTransactions,
33717
33817
  exportTransactionsCSV,
33718
33818
  isAvailable: isInitialized && !!sdk?.transactions,
33819
+ // Expose signing status for UI feedback
33820
+ signingStatus: currentStatus,
33821
+ signingStatusMessage: statusMessage,
33719
33822
  };
33720
33823
  };
33721
33824
 
@@ -33774,7 +33877,6 @@ const useBusiness = () => {
33774
33877
  }
33775
33878
  try {
33776
33879
  const result = await sdk.businesses.getActiveBusinesses();
33777
- console.log('Active businesses fetched successfully:', result);
33778
33880
  return result;
33779
33881
  }
33780
33882
  catch (error) {
@@ -33801,7 +33903,6 @@ const useBusiness = () => {
33801
33903
  }
33802
33904
  try {
33803
33905
  const result = await sdk.businesses.getBusinessTypes();
33804
- console.log('Business types fetched successfully:', result);
33805
33906
  return result;
33806
33907
  }
33807
33908
  catch (error) {
@@ -33815,7 +33916,6 @@ const useBusiness = () => {
33815
33916
  }
33816
33917
  try {
33817
33918
  const result = await sdk.businesses.getBusinessById(businessId);
33818
- console.log('Business fetched successfully:', result);
33819
33919
  return result;
33820
33920
  }
33821
33921
  catch (error) {
@@ -33829,7 +33929,6 @@ const useBusiness = () => {
33829
33929
  }
33830
33930
  try {
33831
33931
  const result = await sdk.businesses.getBusinesses();
33832
- console.log('All businesses fetched successfully:', result);
33833
33932
  return result;
33834
33933
  }
33835
33934
  catch (error) {
@@ -33843,7 +33942,6 @@ const useBusiness = () => {
33843
33942
  }
33844
33943
  try {
33845
33944
  const result = await sdk.businesses.getBusinessByAccount(accountAddress);
33846
- console.log('Business by account fetched successfully:', result);
33847
33945
  return result;
33848
33946
  }
33849
33947
  catch (error) {
@@ -33857,7 +33955,6 @@ const useBusiness = () => {
33857
33955
  }
33858
33956
  try {
33859
33957
  const result = await sdk.businesses.getBusinessesByType(typeId);
33860
- console.log('Businesses by type fetched successfully:', result);
33861
33958
  return result;
33862
33959
  }
33863
33960
  catch (error) {
@@ -33886,7 +33983,6 @@ const useBusiness = () => {
33886
33983
  }
33887
33984
  try {
33888
33985
  const result = await sdk.businesses.createBusiness(displayName);
33889
- console.log('Business created successfully:', result);
33890
33986
  return result;
33891
33987
  }
33892
33988
  catch (error) {
@@ -33900,7 +33996,6 @@ const useBusiness = () => {
33900
33996
  }
33901
33997
  try {
33902
33998
  const result = await sdk.businesses.updateBusiness(businessId, businessData);
33903
- console.log('Business updated successfully:', result);
33904
33999
  return result;
33905
34000
  }
33906
34001
  catch (error) {
@@ -33914,7 +34009,6 @@ const useBusiness = () => {
33914
34009
  }
33915
34010
  try {
33916
34011
  const result = await sdk.businesses.toggleBusinessStatus(businessId, toggleData);
33917
- console.log('Business status toggled successfully:', result);
33918
34012
  return result;
33919
34013
  }
33920
34014
  catch (error) {
@@ -33944,7 +34038,6 @@ const useCampaigns = () => {
33944
34038
  }
33945
34039
  try {
33946
34040
  const result = await sdk.campaigns.getActiveCampaigns();
33947
- console.log('Active campaigns fetched successfully:', result);
33948
34041
  return result;
33949
34042
  }
33950
34043
  catch (error) {
@@ -33958,7 +34051,6 @@ const useCampaigns = () => {
33958
34051
  }
33959
34052
  try {
33960
34053
  const result = await sdk.campaigns.getCampaignById(campaignId);
33961
- console.log('Campaign fetched successfully:', result);
33962
34054
  return result;
33963
34055
  }
33964
34056
  catch (error) {
@@ -33974,9 +34066,7 @@ const useCampaigns = () => {
33974
34066
  throw new Error('SDK not authenticated. claimCampaign requires authentication.');
33975
34067
  }
33976
34068
  try {
33977
- console.log('Claiming campaign with request:', request);
33978
34069
  const result = await sdk.campaigns.claimCampaign(request);
33979
- console.log('Campaign claimed successfully:', result);
33980
34070
  return result;
33981
34071
  }
33982
34072
  catch (error) {
@@ -33994,7 +34084,6 @@ const useCampaigns = () => {
33994
34084
  }
33995
34085
  try {
33996
34086
  const result = await sdk.campaigns.getUserClaims();
33997
- console.log('User claims fetched successfully:', result);
33998
34087
  return result;
33999
34088
  }
34000
34089
  catch (error) {
@@ -34008,7 +34097,6 @@ const useCampaigns = () => {
34008
34097
  }
34009
34098
  try {
34010
34099
  const result = await sdk.campaigns.getCampaignTriggers();
34011
- console.log('Campaign triggers fetched successfully:', result);
34012
34100
  return result;
34013
34101
  }
34014
34102
  catch (error) {
@@ -34023,7 +34111,6 @@ const useCampaigns = () => {
34023
34111
  }
34024
34112
  try {
34025
34113
  const result = await sdk.campaigns.getAllCampaigns(active);
34026
- console.log('All campaigns fetched successfully:', result);
34027
34114
  return result;
34028
34115
  }
34029
34116
  catch (error) {
@@ -34037,7 +34124,6 @@ const useCampaigns = () => {
34037
34124
  }
34038
34125
  try {
34039
34126
  const result = await sdk.campaigns.getCampaignClaims();
34040
- console.log('Campaign claims fetched successfully:', result);
34041
34127
  return result;
34042
34128
  }
34043
34129
  catch (error) {
@@ -34051,7 +34137,6 @@ const useCampaigns = () => {
34051
34137
  }
34052
34138
  try {
34053
34139
  const result = await sdk.campaigns.getCampaignClaimsByUserId(userId);
34054
- console.log('Campaign claims by user ID fetched successfully:', result);
34055
34140
  return result;
34056
34141
  }
34057
34142
  catch (error) {
@@ -34065,7 +34150,6 @@ const useCampaigns = () => {
34065
34150
  }
34066
34151
  try {
34067
34152
  const result = await sdk.campaigns.getCampaignClaimsByBusinessId(businessId);
34068
- console.log('Campaign claims by business ID fetched successfully:', result);
34069
34153
  return result;
34070
34154
  }
34071
34155
  catch (error) {
@@ -34089,14 +34173,13 @@ const useCampaigns = () => {
34089
34173
 
34090
34174
  const useRedemptions = () => {
34091
34175
  const { sdk, isInitialized, isAuthenticated } = usePersSDK();
34092
- const { signAndSubmitTransactionWithJWT, isSignerAvailable } = useTransactionSigner();
34176
+ const { signAndSubmitTransactionWithJWT, isSignerAvailable, currentStatus, statusMessage } = useTransactionSigner();
34093
34177
  const getActiveRedemptions = react.useCallback(async () => {
34094
34178
  if (!isInitialized || !sdk) {
34095
34179
  throw new Error('SDK not initialized. Call initialize() first.');
34096
34180
  }
34097
34181
  try {
34098
34182
  const result = await sdk.redemptions.getActiveRedemptions();
34099
- console.log('Active redemptions fetched successfully:', result);
34100
34183
  return result;
34101
34184
  }
34102
34185
  catch (error) {
@@ -34114,7 +34197,6 @@ const useRedemptions = () => {
34114
34197
  }
34115
34198
  try {
34116
34199
  const result = await sdk.redemptions.getUserRedemptions();
34117
- console.log('User redemptions fetched successfully:', result);
34118
34200
  return result;
34119
34201
  }
34120
34202
  catch (error) {
@@ -34122,7 +34204,7 @@ const useRedemptions = () => {
34122
34204
  throw error;
34123
34205
  }
34124
34206
  }, [sdk, isInitialized, isAuthenticated]);
34125
- const redeem = react.useCallback(async (redemptionId) => {
34207
+ const redeem = react.useCallback(async (redemptionId, onStatusUpdate) => {
34126
34208
  if (!isInitialized || !sdk) {
34127
34209
  throw new Error('SDK not initialized. Call initialize() first.');
34128
34210
  }
@@ -34130,18 +34212,12 @@ const useRedemptions = () => {
34130
34212
  throw new Error('SDK not authenticated. redeem requires authentication.');
34131
34213
  }
34132
34214
  try {
34133
- console.log('Redeeming redemption:', redemptionId);
34134
34215
  const result = await sdk.redemptions.redeem(redemptionId);
34135
- // Check if result has signing fields and sign transaction if required and signer is available
34136
- console.log('Redemption processed successfully:', result);
34137
34216
  const txToken = result.senderTransaction?.actionable?.authToken;
34138
34217
  if (txToken && isSignerAvailable) {
34139
- console.log('Transaction requires blockchain signing, processing with WebAuthn signer...');
34140
34218
  try {
34141
- const signingResult = await signAndSubmitTransactionWithJWT(txToken);
34142
- console.log('Blockchain signing result:', signingResult);
34219
+ const signingResult = await signAndSubmitTransactionWithJWT(txToken, onStatusUpdate);
34143
34220
  if (signingResult.success) {
34144
- console.log('Transaction signed successfully:', signingResult.transactionHash);
34145
34221
  // Return enhanced result with signing information
34146
34222
  return {
34147
34223
  ...result,
@@ -34179,9 +34255,7 @@ const useRedemptions = () => {
34179
34255
  throw new Error('SDK not initialized. Call initialize() first.');
34180
34256
  }
34181
34257
  try {
34182
- console.log('Creating redemption offer with data:', redemptionData);
34183
34258
  const result = await sdk.redemptions.createRedemption(redemptionData);
34184
- console.log('Redemption offer created successfully:', result);
34185
34259
  return result;
34186
34260
  }
34187
34261
  catch (error) {
@@ -34195,7 +34269,6 @@ const useRedemptions = () => {
34195
34269
  }
34196
34270
  try {
34197
34271
  const result = await sdk.redemptions.getAllRedemptions(active);
34198
- console.log('All redemptions fetched successfully:', result);
34199
34272
  return result;
34200
34273
  }
34201
34274
  catch (error) {
@@ -34209,7 +34282,6 @@ const useRedemptions = () => {
34209
34282
  }
34210
34283
  try {
34211
34284
  const result = await sdk.redemptions.getRedemptionTypes();
34212
- console.log('Redemption types fetched successfully:', result);
34213
34285
  return result;
34214
34286
  }
34215
34287
  catch (error) {
@@ -34223,7 +34295,6 @@ const useRedemptions = () => {
34223
34295
  }
34224
34296
  try {
34225
34297
  const result = await sdk.redemptions.updateRedemption(redemptionId, redemptionData);
34226
- console.log('Redemption updated successfully:', result);
34227
34298
  return result;
34228
34299
  }
34229
34300
  catch (error) {
@@ -34237,7 +34308,6 @@ const useRedemptions = () => {
34237
34308
  }
34238
34309
  try {
34239
34310
  const result = await sdk.redemptions.toggleRedemptionStatus(redemptionId);
34240
- console.log('Redemption status toggled successfully:', result);
34241
34311
  return result;
34242
34312
  }
34243
34313
  catch (error) {
@@ -34255,6 +34325,9 @@ const useRedemptions = () => {
34255
34325
  updateRedemption,
34256
34326
  toggleRedemptionStatus,
34257
34327
  isAvailable: isInitialized && !!sdk?.redemptions,
34328
+ // Expose signing status for UI feedback
34329
+ signingStatus: currentStatus,
34330
+ signingStatusMessage: statusMessage,
34258
34331
  };
34259
34332
  };
34260
34333
 
@@ -34263,56 +34336,53 @@ const useRedemptions = () => {
34263
34336
  *
34264
34337
  * Provides comprehensive Web3 functionality including token balance queries,
34265
34338
  * metadata retrieval, collection management, IPFS resolution, and blockchain
34266
- * explorer integration. Supports multi-chain operations and wallet management.
34339
+ * explorer integration. Supports multi-chain operations.
34340
+ *
34341
+ * Note: Wallet addresses should be obtained from `user.wallets` via `usePersSDK()`.
34267
34342
  *
34268
34343
  * @returns Web3 hook with methods for blockchain operations
34269
34344
  *
34270
34345
  * @example
34271
34346
  * ```typescript
34272
34347
  * function Web3Component() {
34273
- * const {
34274
- * getTokenBalance,
34275
- * getTokenMetadata,
34276
- * getWalletInfo,
34277
- * accountAddress
34278
- * } = useWeb3();
34348
+ * const { user } = usePersSDK();
34349
+ * const { getTokenBalance, getTokenMetadata } = useWeb3();
34350
+ *
34351
+ * // Get wallet address from user
34352
+ * const walletAddress = user?.wallets?.[0]?.address;
34279
34353
  *
34280
34354
  * const loadTokenData = async () => {
34281
- * try {
34282
- * if (!accountAddress) {
34283
- * console.log('No wallet connected');
34284
- * return;
34285
- * }
34355
+ * if (!walletAddress) {
34356
+ * console.log('No wallet connected');
34357
+ * return;
34358
+ * }
34286
34359
  *
34287
- * const balance = await getTokenBalance({
34288
- * walletAddress: accountAddress,
34289
- * contractAddress: '0x123...',
34290
- * chainId: 1
34291
- * });
34360
+ * const balance = await getTokenBalance({
34361
+ * walletAddress,
34362
+ * contractAddress: '0x123...',
34363
+ * chainId: 1
34364
+ * });
34292
34365
  *
34293
- * console.log('Token balance:', balance);
34294
- * } catch (error) {
34295
- * console.error('Failed to load token data:', error);
34296
- * }
34366
+ * console.log('Token balance:', balance);
34297
34367
  * };
34298
34368
  *
34299
34369
  * return (
34300
- * <div>
34301
- * {accountAddress ? (
34302
- * <div>
34303
- * <p>Wallet: {accountAddress}</p>
34304
- * <button onClick={loadTokenData}>Load Tokens</button>
34305
- * </div>
34370
+ * <View>
34371
+ * {walletAddress ? (
34372
+ * <View>
34373
+ * <Text>Wallet: {walletAddress}</Text>
34374
+ * <Button onPress={loadTokenData} title="Load Tokens" />
34375
+ * </View>
34306
34376
  * ) : (
34307
- * <p>No wallet connected</p>
34377
+ * <Text>No wallet connected</Text>
34308
34378
  * )}
34309
- * </div>
34379
+ * </View>
34310
34380
  * );
34311
34381
  * }
34312
34382
  * ```
34313
34383
  */
34314
34384
  const useWeb3 = () => {
34315
- const { sdk, isInitialized, isAuthenticated, accountAddress } = usePersSDK();
34385
+ const { sdk, isInitialized, isAuthenticated } = usePersSDK();
34316
34386
  if (!isAuthenticated && isInitialized) {
34317
34387
  console.warn('SDK not authenticated. Some web3 operations may fail.');
34318
34388
  }
@@ -34336,13 +34406,11 @@ const useWeb3 = () => {
34336
34406
  * ```
34337
34407
  */
34338
34408
  const getTokenBalance = react.useCallback(async (request) => {
34339
- console.log('[useWeb3] getTokenBalance called with request:', request);
34340
34409
  if (!isInitialized || !sdk) {
34341
34410
  throw new Error('SDK not initialized. Call initialize() first.');
34342
34411
  }
34343
34412
  try {
34344
34413
  const result = await sdk.web3.getTokenBalance(request);
34345
- console.log('Token balance fetched successfully:', result);
34346
34414
  return result;
34347
34415
  }
34348
34416
  catch (error) {
@@ -34375,7 +34443,6 @@ const useWeb3 = () => {
34375
34443
  }
34376
34444
  try {
34377
34445
  const result = await sdk.web3.getTokenMetadata(request);
34378
- console.log('Token metadata fetched successfully:', result);
34379
34446
  return result;
34380
34447
  }
34381
34448
  catch (error) {
@@ -34389,7 +34456,6 @@ const useWeb3 = () => {
34389
34456
  }
34390
34457
  try {
34391
34458
  const result = await sdk.web3.getTokenCollection(request);
34392
- console.log('Token collection fetched successfully:', result);
34393
34459
  return result;
34394
34460
  }
34395
34461
  catch (error) {
@@ -34403,7 +34469,6 @@ const useWeb3 = () => {
34403
34469
  }
34404
34470
  try {
34405
34471
  const result = await sdk.web3.resolveIPFSUrl(url, chainId);
34406
- console.log('IPFS URL resolved successfully:', result);
34407
34472
  return result;
34408
34473
  }
34409
34474
  catch (error) {
@@ -34417,7 +34482,6 @@ const useWeb3 = () => {
34417
34482
  }
34418
34483
  try {
34419
34484
  const result = await sdk.web3.fetchAndProcessMetadata(tokenUri, chainId);
34420
- console.log('Metadata fetched and processed successfully:', result);
34421
34485
  return result;
34422
34486
  }
34423
34487
  catch (error) {
@@ -34431,7 +34495,6 @@ const useWeb3 = () => {
34431
34495
  }
34432
34496
  try {
34433
34497
  const result = await sdk.web3.getChainDataById(chainId);
34434
- console.log('Chain data fetched successfully:', result);
34435
34498
  return result;
34436
34499
  }
34437
34500
  catch (error) {
@@ -34445,7 +34508,6 @@ const useWeb3 = () => {
34445
34508
  }
34446
34509
  try {
34447
34510
  const result = await sdk.web3.getExplorerUrl(chainId, address, type);
34448
- console.log('Explorer URL generated successfully:', result);
34449
34511
  return result;
34450
34512
  }
34451
34513
  catch (error) {
@@ -34453,19 +34515,6 @@ const useWeb3 = () => {
34453
34515
  throw error;
34454
34516
  }
34455
34517
  }, [sdk, isInitialized]);
34456
- const getWalletInfo = react.useCallback(async () => {
34457
- if (!isInitialized) {
34458
- throw new Error('SDK not initialized. Call initialize() first.');
34459
- }
34460
- if (!accountAddress) {
34461
- console.warn('No account address available');
34462
- return null;
34463
- }
34464
- return {
34465
- address: accountAddress,
34466
- isConnected: !!accountAddress,
34467
- };
34468
- }, [isInitialized, accountAddress]);
34469
34518
  return {
34470
34519
  getTokenBalance,
34471
34520
  getTokenMetadata,
@@ -34474,8 +34523,6 @@ const useWeb3 = () => {
34474
34523
  fetchAndProcessMetadata,
34475
34524
  getChainDataById,
34476
34525
  getExplorerUrl,
34477
- getWalletInfo,
34478
- accountAddress: isInitialized ? accountAddress : null,
34479
34526
  isAvailable: isInitialized && !!sdk?.web3,
34480
34527
  };
34481
34528
  };
@@ -34488,7 +34535,6 @@ const usePurchases = () => {
34488
34535
  }
34489
34536
  try {
34490
34537
  const result = await sdk.purchases.createPaymentIntent(amount, currency, receiptEmail, description);
34491
- console.log('Payment intent created successfully:', result);
34492
34538
  return result;
34493
34539
  }
34494
34540
  catch (error) {
@@ -34502,7 +34548,6 @@ const usePurchases = () => {
34502
34548
  }
34503
34549
  try {
34504
34550
  const result = await sdk.purchases.getActivePurchaseTokens();
34505
- console.log('Active purchase tokens fetched successfully:', result);
34506
34551
  return result;
34507
34552
  }
34508
34553
  catch (error) {
@@ -34519,7 +34564,6 @@ const usePurchases = () => {
34519
34564
  }
34520
34565
  try {
34521
34566
  const result = await sdk.purchases.getAllUserPurchases();
34522
- console.log('User purchases fetched successfully:', result);
34523
34567
  return result;
34524
34568
  }
34525
34569
  catch (error) {
@@ -34556,7 +34600,6 @@ const useTenants = () => {
34556
34600
  }
34557
34601
  try {
34558
34602
  const result = await sdk.tenants.getClientConfig();
34559
- console.log('Client config fetched successfully:', result);
34560
34603
  return result;
34561
34604
  }
34562
34605
  catch (error) {
@@ -34570,7 +34613,6 @@ const useTenants = () => {
34570
34613
  }
34571
34614
  try {
34572
34615
  const result = await sdk.tenants.getLoginToken();
34573
- console.log('Login token fetched successfully');
34574
34616
  return result;
34575
34617
  }
34576
34618
  catch (error) {
@@ -34584,7 +34626,6 @@ const useTenants = () => {
34584
34626
  }
34585
34627
  try {
34586
34628
  const result = await sdk.tenants.getAdmins();
34587
- console.log('Admins fetched successfully:', result);
34588
34629
  return result;
34589
34630
  }
34590
34631
  catch (error) {
@@ -34612,7 +34653,6 @@ const useUsers = () => {
34612
34653
  }
34613
34654
  try {
34614
34655
  const result = await sdk.users.getCurrentUser();
34615
- console.log('Current user fetched successfully:', result);
34616
34656
  return result;
34617
34657
  }
34618
34658
  catch (error) {
@@ -34629,7 +34669,6 @@ const useUsers = () => {
34629
34669
  }
34630
34670
  try {
34631
34671
  const result = await sdk.users.updateCurrentUser(userData);
34632
- console.log('Current user updated successfully:', result);
34633
34672
  return result;
34634
34673
  }
34635
34674
  catch (error) {
@@ -34643,7 +34682,6 @@ const useUsers = () => {
34643
34682
  }
34644
34683
  try {
34645
34684
  const result = await sdk.users.getUserById(userId);
34646
- console.log('User fetched successfully:', result);
34647
34685
  return result;
34648
34686
  }
34649
34687
  catch (error) {
@@ -34657,7 +34695,6 @@ const useUsers = () => {
34657
34695
  }
34658
34696
  try {
34659
34697
  const result = await sdk.users.getAllUsersPublic(filter);
34660
- console.log('Public users fetched successfully:', result);
34661
34698
  return result;
34662
34699
  }
34663
34700
  catch (error) {
@@ -34672,7 +34709,6 @@ const useUsers = () => {
34672
34709
  }
34673
34710
  try {
34674
34711
  const result = await sdk.users.getAllUsers();
34675
- console.log('All users fetched successfully:', result);
34676
34712
  return result;
34677
34713
  }
34678
34714
  catch (error) {
@@ -34686,7 +34722,6 @@ const useUsers = () => {
34686
34722
  }
34687
34723
  try {
34688
34724
  const result = await sdk.users.updateUser(userId, userData);
34689
- console.log('User updated successfully:', result);
34690
34725
  return result;
34691
34726
  }
34692
34727
  catch (error) {
@@ -34700,7 +34735,6 @@ const useUsers = () => {
34700
34735
  }
34701
34736
  try {
34702
34737
  const result = await sdk.users.toggleUserStatus(user);
34703
- console.log('User status toggled successfully:', result);
34704
34738
  return result;
34705
34739
  }
34706
34740
  catch (error) {
@@ -34728,7 +34762,6 @@ const useUserStatus = () => {
34728
34762
  }
34729
34763
  try {
34730
34764
  const result = await sdk.userStatus.getUserStatusTypes();
34731
- console.log('User status types fetched successfully:', result);
34732
34765
  return result;
34733
34766
  }
34734
34767
  catch (error) {
@@ -34745,7 +34778,6 @@ const useUserStatus = () => {
34745
34778
  }
34746
34779
  try {
34747
34780
  const result = await sdk.userStatus.getEarnedUserStatus();
34748
- console.log('Earned user status fetched successfully:', result);
34749
34781
  return result;
34750
34782
  }
34751
34783
  catch (error) {
@@ -34760,7 +34792,6 @@ const useUserStatus = () => {
34760
34792
  }
34761
34793
  try {
34762
34794
  const result = await sdk.userStatus.createUserStatusType(userStatusType);
34763
- console.log('User status type created successfully:', result);
34764
34795
  return result;
34765
34796
  }
34766
34797
  catch (error) {
@@ -34840,7 +34871,6 @@ const useFiles = () => {
34840
34871
  }
34841
34872
  try {
34842
34873
  const result = await sdk.files.getSignedPutUrl(entityId, entityType, fileExtension);
34843
- console.log('Signed put URL generated successfully:', result);
34844
34874
  return result;
34845
34875
  }
34846
34876
  catch (error) {
@@ -34870,7 +34900,6 @@ const useFiles = () => {
34870
34900
  }
34871
34901
  try {
34872
34902
  const result = await sdk.files.getSignedGetUrl(entityId, entityType, expireSeconds);
34873
- console.log('Signed get URL generated successfully:', result);
34874
34903
  return result;
34875
34904
  }
34876
34905
  catch (error) {
@@ -34884,7 +34913,6 @@ const useFiles = () => {
34884
34913
  }
34885
34914
  try {
34886
34915
  const result = await sdk.files.getSignedUrl(request);
34887
- console.log('Signed URL generated successfully:', result);
34888
34916
  return result;
34889
34917
  }
34890
34918
  catch (error) {
@@ -34898,7 +34926,6 @@ const useFiles = () => {
34898
34926
  }
34899
34927
  try {
34900
34928
  const result = await sdk.files.optimizeMedia(url, width, height);
34901
- console.log('Media optimized successfully:', result);
34902
34929
  return result;
34903
34930
  }
34904
34931
  catch (error) {
@@ -34973,7 +35000,6 @@ const useAnalytics = () => {
34973
35000
  }
34974
35001
  try {
34975
35002
  const result = await sdk.analytics.getTransactionAnalytics(request);
34976
- console.log('Transaction analytics fetched successfully:', result);
34977
35003
  return result;
34978
35004
  }
34979
35005
  catch (error) {
@@ -35034,7 +35060,6 @@ const useDonations = () => {
35034
35060
  }
35035
35061
  try {
35036
35062
  const result = await sdk.donations.getDonationTypes();
35037
- console.log('Donation types fetched successfully:', result);
35038
35063
  return result;
35039
35064
  }
35040
35065
  catch (error) {
@@ -35056,6 +35081,7 @@ exports.PersSDKProvider = PersSDKProvider;
35056
35081
  exports.ReactNativeDPoPProvider = ReactNativeDPoPProvider;
35057
35082
  exports.ReactNativeHttpClient = ReactNativeHttpClient;
35058
35083
  exports.ReactNativeSecureStorage = ReactNativeSecureStorage;
35084
+ exports.SigningStatus = SigningStatus;
35059
35085
  exports.TRANSACTION_FORMATS = TRANSACTION_FORMATS;
35060
35086
  exports.TRANSACTION_FORMAT_DESCRIPTIONS = TRANSACTION_FORMAT_DESCRIPTIONS;
35061
35087
  exports.apiPublicKeyTestPrefix = apiPublicKeyTestPrefix;