@explorins/pers-sdk-react-native 1.5.27 → 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 +22 -0
- package/dist/index.js +83 -32
- package/dist/index.js.map +1 -1
- package/dist/providers/PersSDKProvider.d.ts +1 -0
- package/dist/providers/PersSDKProvider.d.ts.map +1 -1
- package/dist/providers/PersSDKProvider.js +11 -3
- package/dist/providers/rn-dpop-provider.d.ts.map +1 -1
- package/dist/providers/rn-dpop-provider.js +18 -1
- package/dist/storage/rn-secure-storage.d.ts.map +1 -1
- package/dist/storage/rn-secure-storage.js +57 -10
- package/package.json +2 -2
- package/src/providers/PersSDKProvider.tsx +13 -3
- package/src/providers/rn-dpop-provider.ts +17 -1
- package/src/storage/rn-secure-storage.ts +52 -9
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
|
@@ -8,31 +8,10 @@ var reactNative = require('react-native');
|
|
|
8
8
|
require('@ethereumjs/tx');
|
|
9
9
|
require('@ethereumjs/util');
|
|
10
10
|
require('@ethereumjs/common');
|
|
11
|
-
var Keychain = require('react-native-keychain');
|
|
12
11
|
var AsyncStorage = require('@react-native-async-storage/async-storage');
|
|
13
|
-
var crypto$1 = require('react-native-quick-crypto');
|
|
14
12
|
var jsxRuntime = require('react/jsx-runtime');
|
|
15
13
|
var react = require('react');
|
|
16
14
|
|
|
17
|
-
function _interopNamespaceDefault(e) {
|
|
18
|
-
var n = Object.create(null);
|
|
19
|
-
if (e) {
|
|
20
|
-
Object.keys(e).forEach(function (k) {
|
|
21
|
-
if (k !== 'default') {
|
|
22
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
23
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
24
|
-
enumerable: true,
|
|
25
|
-
get: function () { return e[k]; }
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
n.default = e;
|
|
31
|
-
return Object.freeze(n);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
var Keychain__namespace = /*#__PURE__*/_interopNamespaceDefault(Keychain);
|
|
35
|
-
|
|
36
15
|
var buffer = {};
|
|
37
16
|
|
|
38
17
|
var base64Js = {};
|
|
@@ -32065,6 +32044,16 @@ class PersSDK {
|
|
|
32065
32044
|
}
|
|
32066
32045
|
}
|
|
32067
32046
|
|
|
32047
|
+
// Conditionally require Keychain to avoid Web bundler errors
|
|
32048
|
+
let Keychain;
|
|
32049
|
+
if (reactNative.Platform.OS !== 'web') {
|
|
32050
|
+
try {
|
|
32051
|
+
Keychain = require('react-native-keychain');
|
|
32052
|
+
}
|
|
32053
|
+
catch (e) {
|
|
32054
|
+
console.warn('ReactNativeSecureStorage: Failed to load react-native-keychain', e);
|
|
32055
|
+
}
|
|
32056
|
+
}
|
|
32068
32057
|
/**
|
|
32069
32058
|
* Secure Storage implementation for React Native
|
|
32070
32059
|
* Uses Keychain/Keystore for sensitive data and AsyncStorage for non-sensitive data.
|
|
@@ -32089,8 +32078,20 @@ class ReactNativeSecureStorage {
|
|
|
32089
32078
|
// In runtime, 'key' is just a string, so this is safe.
|
|
32090
32079
|
if (this.SECURE_KEYS.has(key)) {
|
|
32091
32080
|
// Store in Keychain/Keystore
|
|
32092
|
-
|
|
32093
|
-
|
|
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
|
+
}
|
|
32094
32095
|
}
|
|
32095
32096
|
else {
|
|
32096
32097
|
// Store standard config/metadata in AsyncStorage
|
|
@@ -32101,15 +32102,24 @@ class ReactNativeSecureStorage {
|
|
|
32101
32102
|
const prefixedKey = this.getKeyName(key);
|
|
32102
32103
|
if (this.SECURE_KEYS.has(key)) {
|
|
32103
32104
|
try {
|
|
32104
|
-
|
|
32105
|
-
|
|
32106
|
-
|
|
32105
|
+
if (Keychain) {
|
|
32106
|
+
const credentials = await Keychain.getGenericPassword({ service: prefixedKey });
|
|
32107
|
+
if (credentials) {
|
|
32108
|
+
return this.tryParse(credentials.password);
|
|
32109
|
+
}
|
|
32107
32110
|
}
|
|
32108
|
-
return null;
|
|
32109
32111
|
}
|
|
32110
32112
|
catch (e) {
|
|
32111
32113
|
console.warn(`[ReactNativeSecureStorage] Failed to access keychain for ${key}`, e);
|
|
32112
|
-
|
|
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;
|
|
32113
32123
|
}
|
|
32114
32124
|
}
|
|
32115
32125
|
else {
|
|
@@ -32126,7 +32136,16 @@ class ReactNativeSecureStorage {
|
|
|
32126
32136
|
async remove(key) {
|
|
32127
32137
|
const prefixedKey = this.getKeyName(key);
|
|
32128
32138
|
if (this.SECURE_KEYS.has(key)) {
|
|
32129
|
-
|
|
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);
|
|
32130
32149
|
}
|
|
32131
32150
|
else {
|
|
32132
32151
|
await AsyncStorage.removeItem(prefixedKey);
|
|
@@ -32135,7 +32154,14 @@ class ReactNativeSecureStorage {
|
|
|
32135
32154
|
async clear() {
|
|
32136
32155
|
// Clear all known secure keys
|
|
32137
32156
|
for (const key of this.SECURE_KEYS) {
|
|
32138
|
-
|
|
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
|
+
}
|
|
32139
32165
|
}
|
|
32140
32166
|
// Clear AsyncStorage keys related to PERS
|
|
32141
32167
|
try {
|
|
@@ -32315,6 +32341,23 @@ class AsyncStorageTokenStorage {
|
|
|
32315
32341
|
}
|
|
32316
32342
|
}
|
|
32317
32343
|
|
|
32344
|
+
// Conditionally require quick-crypto for Native platforms only
|
|
32345
|
+
let crypto$1;
|
|
32346
|
+
if (reactNative.Platform.OS !== 'web') {
|
|
32347
|
+
try {
|
|
32348
|
+
crypto$1 = require('react-native-quick-crypto').default || require('react-native-quick-crypto');
|
|
32349
|
+
}
|
|
32350
|
+
catch (e) {
|
|
32351
|
+
console.warn('ReactNativeDPoPProvider: Failed to load react-native-quick-crypto', e);
|
|
32352
|
+
}
|
|
32353
|
+
}
|
|
32354
|
+
else {
|
|
32355
|
+
// on Web, we shouldn't be using this provider anyway (Core SDK has WebDPoPProvider)
|
|
32356
|
+
// But to be safe, we can mock or throw
|
|
32357
|
+
crypto$1 = {
|
|
32358
|
+
generateKeyPair: () => { throw new Error('ReactNativeDPoPProvider not supported on Web'); }
|
|
32359
|
+
};
|
|
32360
|
+
}
|
|
32318
32361
|
class ReactNativeDPoPProvider {
|
|
32319
32362
|
/**
|
|
32320
32363
|
* Generates a new key pair (ES256 recommended)
|
|
@@ -32488,7 +32531,7 @@ class ReactNativeHttpClient {
|
|
|
32488
32531
|
// Create the context
|
|
32489
32532
|
const SDKContext = react.createContext(null);
|
|
32490
32533
|
// Provider component
|
|
32491
|
-
const PersSDKProvider = ({ children }) => {
|
|
32534
|
+
const PersSDKProvider = ({ children, config }) => {
|
|
32492
32535
|
const initializingRef = react.useRef(false);
|
|
32493
32536
|
const [sdk, setSdk] = react.useState(null);
|
|
32494
32537
|
const [authProvider, setAuthProvider] = react.useState(null);
|
|
@@ -32544,7 +32587,15 @@ const PersSDKProvider = ({ children }) => {
|
|
|
32544
32587
|
finally {
|
|
32545
32588
|
initializingRef.current = false;
|
|
32546
32589
|
}
|
|
32547
|
-
}, []);
|
|
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]);
|
|
32548
32599
|
const setAuthenticationState = react.useCallback((user, accountAddress, isAuthenticated) => {
|
|
32549
32600
|
setUser(user);
|
|
32550
32601
|
setAccountAddress(accountAddress);
|