@explorins/pers-sdk-react-native 1.5.31 → 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.
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/useAnalytics.d.ts.map +1 -1
- package/dist/hooks/useAnalytics.js +0 -1
- package/dist/hooks/useAuth.d.ts +0 -1
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +5 -18
- package/dist/hooks/useBusiness.d.ts.map +1 -1
- package/dist/hooks/useBusiness.js +0 -9
- package/dist/hooks/useCampaigns.d.ts.map +1 -1
- package/dist/hooks/useCampaigns.js +0 -10
- package/dist/hooks/useDonations.d.ts.map +1 -1
- package/dist/hooks/useDonations.js +0 -1
- package/dist/hooks/useFiles.d.ts.map +1 -1
- package/dist/hooks/useFiles.js +0 -4
- package/dist/hooks/usePurchases.d.ts.map +1 -1
- package/dist/hooks/usePurchases.js +0 -3
- package/dist/hooks/useRedemptions.d.ts +4 -1
- package/dist/hooks/useRedemptions.d.ts.map +1 -1
- package/dist/hooks/useRedemptions.js +6 -17
- package/dist/hooks/useTenants.d.ts.map +1 -1
- package/dist/hooks/useTenants.js +0 -3
- package/dist/hooks/useTokens.d.ts.map +1 -1
- package/dist/hooks/useTokens.js +0 -6
- package/dist/hooks/useTransactionSigner.d.ts +13 -1
- package/dist/hooks/useTransactionSigner.d.ts.map +1 -1
- package/dist/hooks/useTransactionSigner.js +59 -2
- package/dist/hooks/useTransactions.d.ts +4 -1
- package/dist/hooks/useTransactions.d.ts.map +1 -1
- package/dist/hooks/useTransactions.js +9 -10
- package/dist/hooks/useUserStatus.d.ts.map +1 -1
- package/dist/hooks/useUserStatus.js +0 -3
- package/dist/hooks/useUsers.d.ts.map +1 -1
- package/dist/hooks/useUsers.js +0 -7
- package/dist/hooks/useWeb3.d.ts +26 -42
- package/dist/hooks/useWeb3.d.ts.map +1 -1
- package/dist/hooks/useWeb3.js +27 -53
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +325 -302
- package/dist/index.js.map +1 -1
- package/dist/providers/PersSDKProvider.d.ts +1 -3
- package/dist/providers/PersSDKProvider.d.ts.map +1 -1
- package/dist/providers/PersSDKProvider.js +13 -9
- package/dist/providers/rn-dpop-provider.d.ts +2 -4
- package/dist/providers/rn-dpop-provider.d.ts.map +1 -1
- package/dist/providers/rn-dpop-provider.js +50 -23
- package/dist/storage/rn-secure-storage.d.ts +1 -0
- package/dist/storage/rn-secure-storage.d.ts.map +1 -1
- package/dist/storage/rn-secure-storage.js +9 -12
- package/package.json +2 -2
- package/src/hooks/index.ts +10 -2
- package/src/hooks/useAnalytics.ts +0 -1
- package/src/hooks/useAuth.ts +4 -25
- package/src/hooks/useBusiness.ts +0 -9
- package/src/hooks/useCampaigns.ts +0 -10
- package/src/hooks/useDonations.ts +0 -1
- package/src/hooks/useFiles.ts +0 -4
- package/src/hooks/usePurchases.ts +0 -3
- package/src/hooks/useRedemptions.ts +7 -21
- package/src/hooks/useTenants.ts +0 -3
- package/src/hooks/useTokens.ts +0 -6
- package/src/hooks/useTransactionSigner.ts +74 -4
- package/src/hooks/useTransactions.ts +10 -12
- package/src/hooks/useUserStatus.ts +0 -3
- package/src/hooks/useUsers.ts +0 -7
- package/src/hooks/useWeb3.ts +28 -68
- package/src/index.ts +4 -0
- package/src/providers/PersSDKProvider.tsx +16 -17
- package/src/providers/rn-dpop-provider.ts +85 -45
- package/src/storage/rn-secure-storage.ts +13 -13
|
@@ -16,14 +16,12 @@ export interface PersSDKContext {
|
|
|
16
16
|
tenants: TenantManager | null;
|
|
17
17
|
analytics: AnalyticsManager | null;
|
|
18
18
|
donations: DonationManager | null;
|
|
19
|
-
business: BusinessManager | null;
|
|
20
19
|
authProvider: DefaultAuthProvider | null;
|
|
21
20
|
isInitialized: boolean;
|
|
22
21
|
isAuthenticated: boolean;
|
|
23
22
|
user: UserDTO | AdminDTO | null;
|
|
24
|
-
accountAddress: string | null;
|
|
25
23
|
initialize: (config: PersConfig) => Promise<void>;
|
|
26
|
-
setAuthenticationState: (user: UserDTO | AdminDTO | null,
|
|
24
|
+
setAuthenticationState: (user: UserDTO | AdminDTO | null, isAuthenticated: boolean) => void;
|
|
27
25
|
refreshUserData: () => Promise<void>;
|
|
28
26
|
}
|
|
29
27
|
export declare const PersSDKProvider: React.FC<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PersSDKProvider.d.ts","sourceRoot":"","sources":["../../src/providers/PersSDKProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAuC,SAAS,
|
|
1
|
+
{"version":3,"file":"PersSDKProvider.d.ts","sourceRoot":"","sources":["../../src/providers/PersSDKProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAuC,SAAS,EAA2C,MAAM,OAAO,CAAC;AAEvH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAIpF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAG3D,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,MAAM,WAAW,cAAc;IAE7B,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IAGpB,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,eAAe,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;IAClC,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACtC,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACxC,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;IAGlC,YAAY,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAGzC,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;IAGhC,UAAU,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,sBAAsB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,EAAE,eAAe,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5F,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAMD,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC;IACrC,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB,CA+IA,CAAC;AAGF,eAAO,MAAM,UAAU,QAAO,cAQ7B,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, useContext, useState, useCallback, useRef, useEffect } from 'react';
|
|
2
|
+
import { createContext, useContext, useState, useCallback, useRef, useEffect, useMemo } from 'react';
|
|
3
3
|
import { Platform } from 'react-native';
|
|
4
4
|
import { PersSDK } from '@explorins/pers-sdk/core';
|
|
5
5
|
import { ReactNativeHttpClient } from './react-native-http-client';
|
|
@@ -15,7 +15,6 @@ export const PersSDKProvider = ({ children, config }) => {
|
|
|
15
15
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
16
16
|
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
|
17
17
|
const [user, setUser] = useState(null);
|
|
18
|
-
const [accountAddress, setAccountAddress] = useState(null);
|
|
19
18
|
const initialize = useCallback(async (config) => {
|
|
20
19
|
// Prevent multiple initializations
|
|
21
20
|
if (isInitialized || initializingRef.current) {
|
|
@@ -77,9 +76,8 @@ export const PersSDKProvider = ({ children, config }) => {
|
|
|
77
76
|
});
|
|
78
77
|
}
|
|
79
78
|
}, [config, isInitialized, initialize]);
|
|
80
|
-
const setAuthenticationState = useCallback((user,
|
|
79
|
+
const setAuthenticationState = useCallback((user, isAuthenticated) => {
|
|
81
80
|
setUser(user);
|
|
82
|
-
setAccountAddress(accountAddress);
|
|
83
81
|
setIsAuthenticated(isAuthenticated);
|
|
84
82
|
}, []);
|
|
85
83
|
const refreshUserData = useCallback(async () => {
|
|
@@ -95,7 +93,7 @@ export const PersSDKProvider = ({ children, config }) => {
|
|
|
95
93
|
throw error;
|
|
96
94
|
}
|
|
97
95
|
}, [sdk, isAuthenticated, isInitialized]);
|
|
98
|
-
const contextValue = {
|
|
96
|
+
const contextValue = useMemo(() => ({
|
|
99
97
|
// Main SDK instance
|
|
100
98
|
sdk,
|
|
101
99
|
// Manager shortcuts for convenience
|
|
@@ -110,20 +108,26 @@ export const PersSDKProvider = ({ children, config }) => {
|
|
|
110
108
|
tenants: sdk?.tenants || null,
|
|
111
109
|
analytics: sdk?.analytics || null,
|
|
112
110
|
donations: sdk?.donations || null,
|
|
113
|
-
// Legacy support (deprecated but kept for backward compatibility)
|
|
114
|
-
business: sdk?.businesses || null,
|
|
115
111
|
// Platform-specific providers
|
|
116
112
|
authProvider,
|
|
117
113
|
// State
|
|
118
114
|
isInitialized,
|
|
119
115
|
isAuthenticated,
|
|
120
116
|
user,
|
|
121
|
-
accountAddress,
|
|
122
117
|
// Methods
|
|
123
118
|
initialize,
|
|
124
119
|
setAuthenticationState,
|
|
125
120
|
refreshUserData,
|
|
126
|
-
}
|
|
121
|
+
}), [
|
|
122
|
+
sdk,
|
|
123
|
+
authProvider,
|
|
124
|
+
isInitialized,
|
|
125
|
+
isAuthenticated,
|
|
126
|
+
user,
|
|
127
|
+
initialize,
|
|
128
|
+
setAuthenticationState,
|
|
129
|
+
refreshUserData
|
|
130
|
+
]);
|
|
127
131
|
return (_jsx(SDKContext.Provider, { value: contextValue, children: children }));
|
|
128
132
|
};
|
|
129
133
|
// Custom hook to use the SDK context
|
|
@@ -3,10 +3,8 @@ export declare class ReactNativeDPoPProvider implements DPoPCryptoProvider {
|
|
|
3
3
|
/**
|
|
4
4
|
* Generates a new key pair (ES256 recommended)
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* for security at rest (High Security), making the key "Extractable" in memory
|
|
9
|
-
* but protected by hardware encryption when stored.
|
|
6
|
+
* Uses WebCrypto API (crypto.subtle) for cross-platform compatibility.
|
|
7
|
+
* Falls back to Node.js crypto API on iOS if needed.
|
|
10
8
|
*/
|
|
11
9
|
generateKeyPair(options?: {
|
|
12
10
|
extractable?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rn-dpop-provider.d.ts","sourceRoot":"","sources":["../../src/providers/rn-dpop-provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"rn-dpop-provider.d.ts","sourceRoot":"","sources":["../../src/providers/rn-dpop-provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAiB3E,qBAAa,uBAAwB,YAAW,kBAAkB;IAChE;;;;;OAKG;IACG,eAAe,CAAC,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAqC1E,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAqD9E,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgB3D,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,eAAe;CAOxB"}
|
|
@@ -12,7 +12,6 @@ if (Platform.OS !== 'web') {
|
|
|
12
12
|
}
|
|
13
13
|
else {
|
|
14
14
|
// on Web, we shouldn't be using this provider anyway (Core SDK has WebDPoPProvider)
|
|
15
|
-
// But to be safe, we can mock or throw
|
|
16
15
|
crypto = {
|
|
17
16
|
generateKeyPair: () => { throw new Error('ReactNativeDPoPProvider not supported on Web'); }
|
|
18
17
|
};
|
|
@@ -21,26 +20,39 @@ export class ReactNativeDPoPProvider {
|
|
|
21
20
|
/**
|
|
22
21
|
* Generates a new key pair (ES256 recommended)
|
|
23
22
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* for security at rest (High Security), making the key "Extractable" in memory
|
|
27
|
-
* but protected by hardware encryption when stored.
|
|
23
|
+
* Uses WebCrypto API (crypto.subtle) for cross-platform compatibility.
|
|
24
|
+
* Falls back to Node.js crypto API on iOS if needed.
|
|
28
25
|
*/
|
|
29
26
|
async generateKeyPair(options) {
|
|
30
|
-
//
|
|
27
|
+
// Try WebCrypto API first (works on both iOS and Android)
|
|
28
|
+
if (crypto.subtle) {
|
|
29
|
+
try {
|
|
30
|
+
const keyPair = await crypto.subtle.generateKey({ name: 'ECDSA', namedCurve: 'P-256' }, true, // extractable - required for JWK export
|
|
31
|
+
['sign', 'verify']);
|
|
32
|
+
const publicKeyJwk = await crypto.subtle.exportKey('jwk', keyPair.publicKey);
|
|
33
|
+
const privateKeyJwk = await crypto.subtle.exportKey('jwk', keyPair.privateKey);
|
|
34
|
+
return {
|
|
35
|
+
publicKey: publicKeyJwk,
|
|
36
|
+
privateKey: privateKeyJwk
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
console.warn('[DPoP] WebCrypto API failed, trying Node.js crypto API', err);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Fallback: Node.js crypto API (works on iOS)
|
|
31
44
|
return new Promise((resolve, reject) => {
|
|
32
45
|
crypto.generateKeyPair('ec', { namedCurve: 'P-256' }, (err, publicKey, privateKey) => {
|
|
33
46
|
if (err)
|
|
34
47
|
return reject(err);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
48
|
+
try {
|
|
49
|
+
const pJwk = publicKey.export({ format: 'jwk' });
|
|
50
|
+
const prJwk = privateKey.export({ format: 'jwk' });
|
|
51
|
+
resolve({ publicKey: pJwk, privateKey: prJwk });
|
|
52
|
+
}
|
|
53
|
+
catch (exportErr) {
|
|
54
|
+
reject(exportErr);
|
|
55
|
+
}
|
|
44
56
|
});
|
|
45
57
|
});
|
|
46
58
|
}
|
|
@@ -61,21 +73,37 @@ export class ReactNativeDPoPProvider {
|
|
|
61
73
|
const b64Header = this.base64Url(JSON.stringify(header));
|
|
62
74
|
const b64Payload = this.base64Url(JSON.stringify(finalPayload));
|
|
63
75
|
const signingInput = `${b64Header}.${b64Payload}`;
|
|
64
|
-
// 4. Sign
|
|
76
|
+
// 4. Sign - try WebCrypto first, fallback to Node.js crypto
|
|
77
|
+
if (crypto.subtle) {
|
|
78
|
+
try {
|
|
79
|
+
const privateKey = await crypto.subtle.importKey('jwk', keyPair.privateKey, { name: 'ECDSA', namedCurve: 'P-256' }, false, ['sign']);
|
|
80
|
+
const signatureBuffer = await crypto.subtle.sign({ name: 'ECDSA', hash: 'SHA-256' }, privateKey, Buffer.from(signingInput));
|
|
81
|
+
// WebCrypto returns signature in IEEE P1363 format (r || s), which is what we need for JWT
|
|
82
|
+
return `${signingInput}.${this.base64UrlBuffer(Buffer.from(signatureBuffer))}`;
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
console.warn('[DPoP] WebCrypto sign failed, trying Node.js crypto', err);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Fallback: Node.js crypto API
|
|
65
89
|
const sign = crypto.createSign('SHA256');
|
|
66
90
|
sign.update(signingInput);
|
|
67
|
-
// sign.end() is not required/available in quick-crypto as it doesn't strictly follow stream interface
|
|
68
|
-
// Import private key back from JWK to sign
|
|
69
|
-
// The keyPair.privateKey is a JsonWebKey object because we exported it earlier.
|
|
70
|
-
// quick-crypto createPrivateKey expects jwk object if format is jwk
|
|
71
91
|
const privateKeyObj = crypto.createPrivateKey({ key: keyPair.privateKey, format: 'jwk' });
|
|
72
92
|
const signature = sign.sign(privateKeyObj);
|
|
73
|
-
// signature is a Buffer in quick-crypto
|
|
74
93
|
return `${signingInput}.${this.base64UrlBuffer(signature)}`;
|
|
75
94
|
}
|
|
76
95
|
async hashAccessToken(accessToken) {
|
|
96
|
+
// Try WebCrypto first
|
|
97
|
+
if (crypto.subtle) {
|
|
98
|
+
try {
|
|
99
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', Buffer.from(accessToken));
|
|
100
|
+
return this.base64UrlBuffer(Buffer.from(hashBuffer));
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
// Fallback to Node.js crypto
|
|
104
|
+
}
|
|
105
|
+
}
|
|
77
106
|
const hash = crypto.createHash('sha256').update(accessToken).digest();
|
|
78
|
-
// digest returns Buffer in quick-crypto
|
|
79
107
|
return this.base64UrlBuffer(hash);
|
|
80
108
|
}
|
|
81
109
|
// --- Helpers ---
|
|
@@ -83,7 +111,6 @@ export class ReactNativeDPoPProvider {
|
|
|
83
111
|
return this.base64UrlBuffer(Buffer.from(str));
|
|
84
112
|
}
|
|
85
113
|
base64UrlBuffer(buf) {
|
|
86
|
-
// Ensure we have a Buffer
|
|
87
114
|
const buffer = Buffer.isBuffer(buf) ? buf : Buffer.from(buf);
|
|
88
115
|
return buffer.toString('base64')
|
|
89
116
|
.replace(/=/g, '')
|
|
@@ -7,6 +7,7 @@ export declare class ReactNativeSecureStorage implements TokenStorage {
|
|
|
7
7
|
private keyPrefix;
|
|
8
8
|
readonly supportsObjects = false;
|
|
9
9
|
private readonly SECURE_KEYS;
|
|
10
|
+
private fallbackStorage;
|
|
10
11
|
constructor(keyPrefix?: string);
|
|
11
12
|
set(key: string, value: unknown): Promise<void>;
|
|
12
13
|
get(key: string): Promise<unknown | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rn-secure-storage.d.ts","sourceRoot":"","sources":["../../src/storage/rn-secure-storage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rn-secure-storage.d.ts","sourceRoot":"","sources":["../../src/storage/rn-secure-storage.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EAGb,MAAM,0BAA0B,CAAC;AAalC;;;GAGG;AACH,qBAAa,wBAAyB,YAAW,YAAY;IAc/C,OAAO,CAAC,SAAS;IAZ7B,QAAQ,CAAC,eAAe,SAAS;IAGjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAKzB;IAEH,OAAO,CAAC,eAAe,CAA2B;gBAE9B,SAAS,GAAE,MAAuB;IAIhD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B/C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAkCzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB5B,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,QAAQ;CAOjB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Platform } from 'react-native';
|
|
2
|
-
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
3
2
|
import { DPOP_STORAGE_KEYS, AUTH_STORAGE_KEYS } from '@explorins/pers-sdk/core';
|
|
3
|
+
import { AsyncStorageTokenStorage } from './async-storage-token-storage';
|
|
4
4
|
// Conditionally require Keychain to avoid Web bundler errors
|
|
5
5
|
let Keychain;
|
|
6
6
|
if (Platform.OS !== 'web') {
|
|
@@ -27,6 +27,7 @@ export class ReactNativeSecureStorage {
|
|
|
27
27
|
AUTH_STORAGE_KEYS.REFRESH_TOKEN,
|
|
28
28
|
AUTH_STORAGE_KEYS.PROVIDER_TOKEN
|
|
29
29
|
]);
|
|
30
|
+
this.fallbackStorage = new AsyncStorageTokenStorage(keyPrefix);
|
|
30
31
|
}
|
|
31
32
|
async set(key, value) {
|
|
32
33
|
const prefixedKey = this.getKeyName(key);
|
|
@@ -47,12 +48,12 @@ export class ReactNativeSecureStorage {
|
|
|
47
48
|
catch (e) {
|
|
48
49
|
console.warn(`[ReactNativeSecureStorage] Keychain set failed for ${key}, falling back to AsyncStorage`, e);
|
|
49
50
|
// Fallback to AsyncStorage if Keychain fails
|
|
50
|
-
await
|
|
51
|
+
await this.fallbackStorage.set(key, stringValue);
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
else {
|
|
54
55
|
// Store standard config/metadata in AsyncStorage
|
|
55
|
-
await
|
|
56
|
+
await this.fallbackStorage.set(key, stringValue);
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
async get(key) {
|
|
@@ -72,7 +73,7 @@ export class ReactNativeSecureStorage {
|
|
|
72
73
|
}
|
|
73
74
|
// Fallback: Check AsyncStorage if not found in Keychain or Keychain failed
|
|
74
75
|
try {
|
|
75
|
-
const val = await
|
|
76
|
+
const val = await this.fallbackStorage.get(key);
|
|
76
77
|
return val ? this.tryParse(val) : null;
|
|
77
78
|
}
|
|
78
79
|
catch (e) {
|
|
@@ -81,7 +82,7 @@ export class ReactNativeSecureStorage {
|
|
|
81
82
|
}
|
|
82
83
|
else {
|
|
83
84
|
try {
|
|
84
|
-
const val = await
|
|
85
|
+
const val = await this.fallbackStorage.get(key);
|
|
85
86
|
return val ? this.tryParse(val) : null;
|
|
86
87
|
}
|
|
87
88
|
catch (e) {
|
|
@@ -102,10 +103,10 @@ export class ReactNativeSecureStorage {
|
|
|
102
103
|
console.warn(`[ReactNativeSecureStorage] Failed to reset keychain for ${key}`, e);
|
|
103
104
|
}
|
|
104
105
|
// Always remove from fallback storage too, just in case
|
|
105
|
-
await
|
|
106
|
+
await this.fallbackStorage.remove(key);
|
|
106
107
|
}
|
|
107
108
|
else {
|
|
108
|
-
await
|
|
109
|
+
await this.fallbackStorage.remove(key);
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
async clear() {
|
|
@@ -122,11 +123,7 @@ export class ReactNativeSecureStorage {
|
|
|
122
123
|
}
|
|
123
124
|
// Clear AsyncStorage keys related to PERS
|
|
124
125
|
try {
|
|
125
|
-
|
|
126
|
-
const ourKeys = allKeys.filter(k => k.startsWith(this.keyPrefix));
|
|
127
|
-
if (ourKeys.length > 0) {
|
|
128
|
-
await AsyncStorage.multiRemove(ourKeys);
|
|
129
|
-
}
|
|
126
|
+
await this.fallbackStorage.clear();
|
|
130
127
|
}
|
|
131
128
|
catch (e) {
|
|
132
129
|
console.warn('[ReactNativeSecureStorage] Failed to clear AsyncStorage', e);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@explorins/pers-sdk-react-native",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.32",
|
|
4
4
|
"description": "React Native SDK for PERS Platform - Tourism Loyalty System with Blockchain Transaction Signing and WebAuthn Authentication",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@explorins/pers-sdk": "^1.6.36",
|
|
41
41
|
"@explorins/pers-shared": "^2.1.52",
|
|
42
|
-
"@explorins/pers-signer": "^1.0.
|
|
42
|
+
"@explorins/pers-signer": "^1.0.33",
|
|
43
43
|
"@explorins/web3-ts": "^0.3.75",
|
|
44
44
|
"buffer": "^6.0.3",
|
|
45
45
|
"ethers": "^6.15.0",
|
package/src/hooks/index.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export { useAuth } from './useAuth';
|
|
3
3
|
export { useTokens } from './useTokens';
|
|
4
4
|
export { useTransactions } from './useTransactions';
|
|
5
|
-
export { useTransactionSigner } from './useTransactionSigner';
|
|
5
|
+
export { useTransactionSigner, SigningStatus } from './useTransactionSigner';
|
|
6
6
|
export { useBusiness } from './useBusiness';
|
|
7
7
|
export { useCampaigns } from './useCampaigns';
|
|
8
8
|
export { useRedemptions } from './useRedemptions';
|
|
@@ -17,4 +17,12 @@ export { useDonations } from './useDonations';
|
|
|
17
17
|
|
|
18
18
|
// Re-export auth-related types for convenience
|
|
19
19
|
export type { RawUserData } from './useAuth';
|
|
20
|
-
export type {
|
|
20
|
+
export type {
|
|
21
|
+
TransactionSignerHook,
|
|
22
|
+
SubmissionResult,
|
|
23
|
+
AuthenticatedUser,
|
|
24
|
+
TransactionSigningResult,
|
|
25
|
+
StatusUpdateData,
|
|
26
|
+
OnStatusUpdateFn,
|
|
27
|
+
SigningStatus as SigningStatusType
|
|
28
|
+
} from './useTransactionSigner';
|
|
@@ -65,7 +65,6 @@ export const useAnalytics = () => {
|
|
|
65
65
|
|
|
66
66
|
try {
|
|
67
67
|
const result = await sdk.analytics.getTransactionAnalytics(request);
|
|
68
|
-
console.log('Transaction analytics fetched successfully:', result);
|
|
69
68
|
return result;
|
|
70
69
|
} catch (error) {
|
|
71
70
|
console.error('Failed to fetch transaction analytics:', error);
|
package/src/hooks/useAuth.ts
CHANGED
|
@@ -50,7 +50,6 @@ export const useAuth = () => {
|
|
|
50
50
|
isInitialized,
|
|
51
51
|
isAuthenticated,
|
|
52
52
|
user,
|
|
53
|
-
accountAddress,
|
|
54
53
|
setAuthenticationState,
|
|
55
54
|
refreshUserData
|
|
56
55
|
} = usePersSDK();
|
|
@@ -76,8 +75,6 @@ export const useAuth = () => {
|
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
try {
|
|
79
|
-
console.log(`Logging in as ${userType}...`);
|
|
80
|
-
|
|
81
78
|
// Set token in auth provider
|
|
82
79
|
await authProvider.setAccessToken(jwtToken);
|
|
83
80
|
|
|
@@ -87,13 +84,8 @@ export const useAuth = () => {
|
|
|
87
84
|
const userData = result.user || result.admin;
|
|
88
85
|
|
|
89
86
|
if (userData) {
|
|
90
|
-
|
|
91
|
-
('wallets' in userData && userData.wallets?.[0]?.address) ||
|
|
92
|
-
null;
|
|
93
|
-
|
|
94
|
-
setAuthenticationState(userData, userAccountAddress as string | null, true);
|
|
87
|
+
setAuthenticationState(userData, true);
|
|
95
88
|
|
|
96
|
-
console.log('Login successful');
|
|
97
89
|
return result;
|
|
98
90
|
} else {
|
|
99
91
|
throw new Error('No user data returned from login');
|
|
@@ -122,8 +114,6 @@ export const useAuth = () => {
|
|
|
122
114
|
}
|
|
123
115
|
|
|
124
116
|
try {
|
|
125
|
-
console.log('Logging in with raw user data...');
|
|
126
|
-
|
|
127
117
|
// Use the raw data login from the auth manager
|
|
128
118
|
const result = await sdk.auth.loginWithRawData(rawUserData);
|
|
129
119
|
|
|
@@ -135,13 +125,7 @@ export const useAuth = () => {
|
|
|
135
125
|
const userData = result.user;
|
|
136
126
|
|
|
137
127
|
if (userData) {
|
|
138
|
-
|
|
139
|
-
(userData as UserDTO & { wallets?: Array<{ address: string }> })?.wallets?.[0]?.address ||
|
|
140
|
-
null;
|
|
141
|
-
|
|
142
|
-
setAuthenticationState(userData, userAccountAddress, true);
|
|
143
|
-
|
|
144
|
-
console.log('Raw data login successful');
|
|
128
|
+
setAuthenticationState(userData, true);
|
|
145
129
|
} else {
|
|
146
130
|
throw new Error('No user data returned from raw data login');
|
|
147
131
|
}
|
|
@@ -165,15 +149,11 @@ export const useAuth = () => {
|
|
|
165
149
|
*/
|
|
166
150
|
const logout = useCallback(async (): Promise<void> => {
|
|
167
151
|
try {
|
|
168
|
-
console.log('Logging out...');
|
|
169
|
-
|
|
170
152
|
if (authProvider) {
|
|
171
153
|
await authProvider.clearTokens();
|
|
172
154
|
}
|
|
173
155
|
|
|
174
|
-
setAuthenticationState(null,
|
|
175
|
-
|
|
176
|
-
console.log('Logout successful');
|
|
156
|
+
setAuthenticationState(null, false);
|
|
177
157
|
} catch (error) {
|
|
178
158
|
console.error('Logout failed:', error);
|
|
179
159
|
throw error;
|
|
@@ -257,7 +237,7 @@ export const useAuth = () => {
|
|
|
257
237
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
258
238
|
}
|
|
259
239
|
await sdk.auth.clearAuth();
|
|
260
|
-
setAuthenticationState(null,
|
|
240
|
+
setAuthenticationState(null, false);
|
|
261
241
|
}, [sdk, setAuthenticationState]);
|
|
262
242
|
|
|
263
243
|
/**
|
|
@@ -284,7 +264,6 @@ export const useAuth = () => {
|
|
|
284
264
|
isInitialized,
|
|
285
265
|
isAuthenticated,
|
|
286
266
|
user,
|
|
287
|
-
accountAddress,
|
|
288
267
|
|
|
289
268
|
// Methods
|
|
290
269
|
login,
|
package/src/hooks/useBusiness.ts
CHANGED
|
@@ -59,7 +59,6 @@ export const useBusiness = () => {
|
|
|
59
59
|
|
|
60
60
|
try {
|
|
61
61
|
const result = await sdk.businesses.getActiveBusinesses();
|
|
62
|
-
console.log('Active businesses fetched successfully:', result);
|
|
63
62
|
return result;
|
|
64
63
|
} catch (error) {
|
|
65
64
|
console.error('Failed to fetch active businesses:', error);
|
|
@@ -87,7 +86,6 @@ export const useBusiness = () => {
|
|
|
87
86
|
|
|
88
87
|
try {
|
|
89
88
|
const result = await sdk.businesses.getBusinessTypes();
|
|
90
|
-
console.log('Business types fetched successfully:', result);
|
|
91
89
|
return result;
|
|
92
90
|
} catch (error) {
|
|
93
91
|
console.error('Failed to fetch business types:', error);
|
|
@@ -102,7 +100,6 @@ export const useBusiness = () => {
|
|
|
102
100
|
|
|
103
101
|
try {
|
|
104
102
|
const result = await sdk.businesses.getBusinessById(businessId);
|
|
105
|
-
console.log('Business fetched successfully:', result);
|
|
106
103
|
return result;
|
|
107
104
|
} catch (error) {
|
|
108
105
|
console.error('Failed to fetch business:', error);
|
|
@@ -117,7 +114,6 @@ export const useBusiness = () => {
|
|
|
117
114
|
|
|
118
115
|
try {
|
|
119
116
|
const result = await sdk.businesses.getBusinesses();
|
|
120
|
-
console.log('All businesses fetched successfully:', result);
|
|
121
117
|
return result;
|
|
122
118
|
} catch (error) {
|
|
123
119
|
console.error('Failed to fetch all businesses:', error);
|
|
@@ -132,7 +128,6 @@ export const useBusiness = () => {
|
|
|
132
128
|
|
|
133
129
|
try {
|
|
134
130
|
const result = await sdk.businesses.getBusinessByAccount(accountAddress);
|
|
135
|
-
console.log('Business by account fetched successfully:', result);
|
|
136
131
|
return result;
|
|
137
132
|
} catch (error) {
|
|
138
133
|
console.error('Failed to fetch business by account:', error);
|
|
@@ -147,7 +142,6 @@ export const useBusiness = () => {
|
|
|
147
142
|
|
|
148
143
|
try {
|
|
149
144
|
const result = await sdk.businesses.getBusinessesByType(typeId);
|
|
150
|
-
console.log('Businesses by type fetched successfully:', result);
|
|
151
145
|
return result;
|
|
152
146
|
} catch (error) {
|
|
153
147
|
console.error('Failed to fetch businesses by type:', error);
|
|
@@ -177,7 +171,6 @@ export const useBusiness = () => {
|
|
|
177
171
|
|
|
178
172
|
try {
|
|
179
173
|
const result = await sdk.businesses.createBusiness(displayName);
|
|
180
|
-
console.log('Business created successfully:', result);
|
|
181
174
|
return result;
|
|
182
175
|
} catch (error) {
|
|
183
176
|
console.error('Failed to create business:', error);
|
|
@@ -192,7 +185,6 @@ export const useBusiness = () => {
|
|
|
192
185
|
|
|
193
186
|
try {
|
|
194
187
|
const result = await sdk.businesses.updateBusiness(businessId, businessData);
|
|
195
|
-
console.log('Business updated successfully:', result);
|
|
196
188
|
return result;
|
|
197
189
|
} catch (error) {
|
|
198
190
|
console.error('Failed to update business:', error);
|
|
@@ -207,7 +199,6 @@ export const useBusiness = () => {
|
|
|
207
199
|
|
|
208
200
|
try {
|
|
209
201
|
const result = await sdk.businesses.toggleBusinessStatus(businessId, toggleData);
|
|
210
|
-
console.log('Business status toggled successfully:', result);
|
|
211
202
|
return result;
|
|
212
203
|
} catch (error) {
|
|
213
204
|
console.error('Failed to toggle business status:', error);
|
|
@@ -20,7 +20,6 @@ export const useCampaigns = () => {
|
|
|
20
20
|
|
|
21
21
|
try {
|
|
22
22
|
const result = await sdk.campaigns.getActiveCampaigns();
|
|
23
|
-
console.log('Active campaigns fetched successfully:', result);
|
|
24
23
|
return result;
|
|
25
24
|
} catch (error) {
|
|
26
25
|
console.error('Failed to fetch active campaigns:', error);
|
|
@@ -35,7 +34,6 @@ export const useCampaigns = () => {
|
|
|
35
34
|
|
|
36
35
|
try {
|
|
37
36
|
const result = await sdk.campaigns.getCampaignById(campaignId);
|
|
38
|
-
console.log('Campaign fetched successfully:', result);
|
|
39
37
|
return result;
|
|
40
38
|
} catch (error) {
|
|
41
39
|
console.error('Failed to fetch campaign:', error);
|
|
@@ -52,9 +50,7 @@ export const useCampaigns = () => {
|
|
|
52
50
|
}
|
|
53
51
|
|
|
54
52
|
try {
|
|
55
|
-
console.log('Claiming campaign with request:', request);
|
|
56
53
|
const result = await sdk.campaigns.claimCampaign(request);
|
|
57
|
-
console.log('Campaign claimed successfully:', result);
|
|
58
54
|
return result;
|
|
59
55
|
} catch (error) {
|
|
60
56
|
console.error('Failed to claim campaign:', error);
|
|
@@ -73,7 +69,6 @@ export const useCampaigns = () => {
|
|
|
73
69
|
|
|
74
70
|
try {
|
|
75
71
|
const result = await sdk.campaigns.getUserClaims();
|
|
76
|
-
console.log('User claims fetched successfully:', result);
|
|
77
72
|
return result;
|
|
78
73
|
} catch (error) {
|
|
79
74
|
console.error('Failed to fetch user claims:', error);
|
|
@@ -88,7 +83,6 @@ export const useCampaigns = () => {
|
|
|
88
83
|
|
|
89
84
|
try {
|
|
90
85
|
const result = await sdk.campaigns.getCampaignTriggers();
|
|
91
|
-
console.log('Campaign triggers fetched successfully:', result);
|
|
92
86
|
return result;
|
|
93
87
|
} catch (error) {
|
|
94
88
|
console.error('Failed to fetch campaign triggers:', error);
|
|
@@ -104,7 +98,6 @@ export const useCampaigns = () => {
|
|
|
104
98
|
|
|
105
99
|
try {
|
|
106
100
|
const result = await sdk.campaigns.getAllCampaigns(active);
|
|
107
|
-
console.log('All campaigns fetched successfully:', result);
|
|
108
101
|
return result;
|
|
109
102
|
} catch (error) {
|
|
110
103
|
console.error('Failed to fetch all campaigns:', error);
|
|
@@ -119,7 +112,6 @@ export const useCampaigns = () => {
|
|
|
119
112
|
|
|
120
113
|
try {
|
|
121
114
|
const result = await sdk.campaigns.getCampaignClaims();
|
|
122
|
-
console.log('Campaign claims fetched successfully:', result);
|
|
123
115
|
return result;
|
|
124
116
|
} catch (error) {
|
|
125
117
|
console.error('Failed to fetch campaign claims:', error);
|
|
@@ -134,7 +126,6 @@ export const useCampaigns = () => {
|
|
|
134
126
|
|
|
135
127
|
try {
|
|
136
128
|
const result = await sdk.campaigns.getCampaignClaimsByUserId(userId);
|
|
137
|
-
console.log('Campaign claims by user ID fetched successfully:', result);
|
|
138
129
|
return result;
|
|
139
130
|
} catch (error) {
|
|
140
131
|
console.error('Failed to fetch campaign claims by user ID:', error);
|
|
@@ -149,7 +140,6 @@ export const useCampaigns = () => {
|
|
|
149
140
|
|
|
150
141
|
try {
|
|
151
142
|
const result = await sdk.campaigns.getCampaignClaimsByBusinessId(businessId);
|
|
152
|
-
console.log('Campaign claims by business ID fetched successfully:', result);
|
|
153
143
|
return result;
|
|
154
144
|
} catch (error) {
|
|
155
145
|
console.error('Failed to fetch campaign claims by business ID:', error);
|
|
@@ -51,7 +51,6 @@ export const useDonations = () => {
|
|
|
51
51
|
|
|
52
52
|
try {
|
|
53
53
|
const result = await sdk.donations.getDonationTypes();
|
|
54
|
-
console.log('Donation types fetched successfully:', result);
|
|
55
54
|
return result;
|
|
56
55
|
} catch (error) {
|
|
57
56
|
console.error('Failed to fetch donation types:', error);
|
package/src/hooks/useFiles.ts
CHANGED
|
@@ -75,7 +75,6 @@ export const useFiles = () => {
|
|
|
75
75
|
|
|
76
76
|
try {
|
|
77
77
|
const result = await sdk.files.getSignedPutUrl(entityId, entityType, fileExtension);
|
|
78
|
-
console.log('Signed put URL generated successfully:', result);
|
|
79
78
|
return result;
|
|
80
79
|
} catch (error) {
|
|
81
80
|
console.error('Failed to generate signed put URL:', error);
|
|
@@ -110,7 +109,6 @@ export const useFiles = () => {
|
|
|
110
109
|
|
|
111
110
|
try {
|
|
112
111
|
const result = await sdk.files.getSignedGetUrl(entityId, entityType, expireSeconds);
|
|
113
|
-
console.log('Signed get URL generated successfully:', result);
|
|
114
112
|
return result;
|
|
115
113
|
} catch (error) {
|
|
116
114
|
console.error('Failed to generate signed get URL:', error);
|
|
@@ -125,7 +123,6 @@ export const useFiles = () => {
|
|
|
125
123
|
|
|
126
124
|
try {
|
|
127
125
|
const result = await sdk.files.getSignedUrl(request);
|
|
128
|
-
console.log('Signed URL generated successfully:', result);
|
|
129
126
|
return result;
|
|
130
127
|
} catch (error) {
|
|
131
128
|
console.error('Failed to generate signed URL:', error);
|
|
@@ -140,7 +137,6 @@ export const useFiles = () => {
|
|
|
140
137
|
|
|
141
138
|
try {
|
|
142
139
|
const result = await sdk.files.optimizeMedia(url, width, height);
|
|
143
|
-
console.log('Media optimized successfully:', result);
|
|
144
140
|
return result;
|
|
145
141
|
} catch (error) {
|
|
146
142
|
console.error('Failed to optimize media:', error);
|
|
@@ -17,7 +17,6 @@ export const usePurchases = () => {
|
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
19
|
const result = await sdk.purchases.createPaymentIntent(amount, currency, receiptEmail, description);
|
|
20
|
-
console.log('Payment intent created successfully:', result);
|
|
21
20
|
return result;
|
|
22
21
|
} catch (error) {
|
|
23
22
|
console.error('Failed to create payment intent:', error);
|
|
@@ -32,7 +31,6 @@ export const usePurchases = () => {
|
|
|
32
31
|
|
|
33
32
|
try {
|
|
34
33
|
const result = await sdk.purchases.getActivePurchaseTokens();
|
|
35
|
-
console.log('Active purchase tokens fetched successfully:', result);
|
|
36
34
|
return result;
|
|
37
35
|
} catch (error) {
|
|
38
36
|
console.error('Failed to fetch active purchase tokens:', error);
|
|
@@ -50,7 +48,6 @@ export const usePurchases = () => {
|
|
|
50
48
|
|
|
51
49
|
try {
|
|
52
50
|
const result = await sdk.purchases.getAllUserPurchases();
|
|
53
|
-
console.log('User purchases fetched successfully:', result);
|
|
54
51
|
return result;
|
|
55
52
|
} catch (error) {
|
|
56
53
|
console.error('Failed to fetch user purchases:', error);
|