@explorins/pers-sdk-react-native 1.5.28 → 1.5.29

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 CHANGED
@@ -376,6 +376,28 @@ function BlockchainRedemption() {
376
376
 
377
377
  ## Advanced Configuration
378
378
 
379
+ ### SDK Initialization & DPoP
380
+
381
+ The `PersSDKProvider` accepts a `config` object allowing you to customize behavior, including **DPoP (Distributed Proof of Possession)**.
382
+
383
+ **DPoP Behavior:**
384
+ - **Enabled by Default**: Automatically active on iOS/Android using a high-performance C++ crypto bridge (`react-native-quick-crypto`).
385
+ - **Web Support**: Uses standard WebCrypto API.
386
+ - **Security**: Binds access tokens to the device, preventing replay attacks.
387
+
388
+ **Customizing Initialization:**
389
+ ```typescript
390
+ <PersSDKProvider config={{
391
+ apiProjectKey: 'your-project-key',
392
+ // DPoP is enabled by default. To disable (not recommended):
393
+ dpop: {
394
+ enabled: false
395
+ }
396
+ }}>
397
+ <YourApp />
398
+ </PersSDKProvider>
399
+ ```
400
+
379
401
  ### Custom Authentication Provider
380
402
 
381
403
  The SDK automatically uses `ReactNativeSecureStorage` for React Native (iOS/Android) and `LocalStorageTokenStorage` for Web. You can customize this if needed:
package/dist/index.js CHANGED
@@ -32078,8 +32078,20 @@ class ReactNativeSecureStorage {
32078
32078
  // In runtime, 'key' is just a string, so this is safe.
32079
32079
  if (this.SECURE_KEYS.has(key)) {
32080
32080
  // Store in Keychain/Keystore
32081
- // Service name acts as the key identifier in simple usage
32082
- await Keychain.setGenericPassword(prefixedKey, stringValue, { service: prefixedKey });
32081
+ try {
32082
+ if (Keychain) {
32083
+ // Service name acts as the key identifier in simple usage
32084
+ await Keychain.setGenericPassword(prefixedKey, stringValue, { service: prefixedKey });
32085
+ }
32086
+ else {
32087
+ throw new Error('RN Keychain not available');
32088
+ }
32089
+ }
32090
+ catch (e) {
32091
+ console.warn(`[ReactNativeSecureStorage] Keychain set failed for ${key}, falling back to AsyncStorage`, e);
32092
+ // Fallback to AsyncStorage if Keychain fails
32093
+ await AsyncStorage.setItem(prefixedKey, stringValue);
32094
+ }
32083
32095
  }
32084
32096
  else {
32085
32097
  // Store standard config/metadata in AsyncStorage
@@ -32090,15 +32102,24 @@ class ReactNativeSecureStorage {
32090
32102
  const prefixedKey = this.getKeyName(key);
32091
32103
  if (this.SECURE_KEYS.has(key)) {
32092
32104
  try {
32093
- const credentials = await Keychain.getGenericPassword({ service: prefixedKey });
32094
- if (credentials) {
32095
- return this.tryParse(credentials.password);
32105
+ if (Keychain) {
32106
+ const credentials = await Keychain.getGenericPassword({ service: prefixedKey });
32107
+ if (credentials) {
32108
+ return this.tryParse(credentials.password);
32109
+ }
32096
32110
  }
32097
- return null;
32098
32111
  }
32099
32112
  catch (e) {
32100
32113
  console.warn(`[ReactNativeSecureStorage] Failed to access keychain for ${key}`, e);
32101
- return null; // Key not found or access denied
32114
+ // Continue to fallback check...
32115
+ }
32116
+ // Fallback: Check AsyncStorage if not found in Keychain or Keychain failed
32117
+ try {
32118
+ const val = await AsyncStorage.getItem(prefixedKey);
32119
+ return val ? this.tryParse(val) : null;
32120
+ }
32121
+ catch (e) {
32122
+ return null;
32102
32123
  }
32103
32124
  }
32104
32125
  else {
@@ -32115,7 +32136,16 @@ class ReactNativeSecureStorage {
32115
32136
  async remove(key) {
32116
32137
  const prefixedKey = this.getKeyName(key);
32117
32138
  if (this.SECURE_KEYS.has(key)) {
32118
- await Keychain.resetGenericPassword({ service: prefixedKey });
32139
+ try {
32140
+ if (Keychain) {
32141
+ await Keychain.resetGenericPassword({ service: prefixedKey });
32142
+ }
32143
+ }
32144
+ catch (e) {
32145
+ console.warn(`[ReactNativeSecureStorage] Failed to reset keychain for ${key}`, e);
32146
+ }
32147
+ // Always remove from fallback storage too, just in case
32148
+ await AsyncStorage.removeItem(prefixedKey);
32119
32149
  }
32120
32150
  else {
32121
32151
  await AsyncStorage.removeItem(prefixedKey);
@@ -32124,7 +32154,14 @@ class ReactNativeSecureStorage {
32124
32154
  async clear() {
32125
32155
  // Clear all known secure keys
32126
32156
  for (const key of this.SECURE_KEYS) {
32127
- await Keychain.resetGenericPassword({ service: this.getKeyName(key) });
32157
+ try {
32158
+ if (Keychain) {
32159
+ await Keychain.resetGenericPassword({ service: this.getKeyName(key) });
32160
+ }
32161
+ }
32162
+ catch (e) {
32163
+ console.warn(`[ReactNativeSecureStorage] Failed to clear keychain key ${key}`, e);
32164
+ }
32128
32165
  }
32129
32166
  // Clear AsyncStorage keys related to PERS
32130
32167
  try {
@@ -32494,7 +32531,7 @@ class ReactNativeHttpClient {
32494
32531
  // Create the context
32495
32532
  const SDKContext = react.createContext(null);
32496
32533
  // Provider component
32497
- const PersSDKProvider = ({ children }) => {
32534
+ const PersSDKProvider = ({ children, config }) => {
32498
32535
  const initializingRef = react.useRef(false);
32499
32536
  const [sdk, setSdk] = react.useState(null);
32500
32537
  const [authProvider, setAuthProvider] = react.useState(null);
@@ -32550,7 +32587,15 @@ const PersSDKProvider = ({ children }) => {
32550
32587
  finally {
32551
32588
  initializingRef.current = false;
32552
32589
  }
32553
- }, []);
32590
+ }, [isInitialized]);
32591
+ // Auto-initialize if config is provided
32592
+ react.useEffect(() => {
32593
+ if (config && !isInitialized && !initializingRef.current) {
32594
+ initialize(config).catch(err => {
32595
+ console.error('Auto-initialization failed:', err);
32596
+ });
32597
+ }
32598
+ }, [config, isInitialized, initialize]);
32554
32599
  const setAuthenticationState = react.useCallback((user, accountAddress, isAuthenticated) => {
32555
32600
  setUser(user);
32556
32601
  setAccountAddress(accountAddress);