@explorins/pers-sdk-react-native 1.5.17 → 1.5.20
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 +336 -234
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useAuth.d.ts +1 -1
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +7 -7
- package/dist/hooks/useRedemptions.d.ts.map +1 -1
- package/dist/hooks/useRedemptions.js +4 -4
- package/dist/hooks/useTenants.d.ts.map +1 -1
- package/dist/hooks/useTenants.js +0 -1
- package/dist/hooks/useTransactionSigner.d.ts +186 -53
- package/dist/hooks/useTransactionSigner.d.ts.map +1 -1
- package/dist/hooks/useTransactionSigner.js +285 -102
- package/dist/hooks/useTransactions.d.ts +2 -2
- package/dist/hooks/useTransactions.d.ts.map +1 -1
- package/dist/hooks/useTransactions.js +38 -9
- package/dist/index.d.ts +211 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21154 -18543
- package/dist/index.js.map +1 -1
- package/dist/providers/PersSDKProvider.d.ts +2 -8
- package/dist/providers/PersSDKProvider.d.ts.map +1 -1
- package/dist/providers/PersSDKProvider.js +16 -31
- package/dist/providers/react-native-auth-provider.d.ts +25 -36
- package/dist/providers/react-native-auth-provider.d.ts.map +1 -1
- package/dist/providers/react-native-auth-provider.js +36 -146
- package/dist/storage/async-storage-token-storage.d.ts +22 -0
- package/dist/storage/async-storage-token-storage.d.ts.map +1 -0
- package/dist/storage/async-storage-token-storage.js +113 -0
- package/package.json +16 -11
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useAuth.ts +7 -7
- package/src/hooks/useRedemptions.ts +5 -7
- package/src/hooks/useTenants.ts +0 -1
- package/src/hooks/useTransactionSigner.ts +322 -166
- package/src/hooks/useTransactions.ts +44 -11
- package/src/index.ts +243 -7
- package/src/providers/PersSDKProvider.tsx +21 -40
- package/src/providers/react-native-auth-provider.ts +59 -176
- package/src/storage/async-storage-token-storage.ts +133 -0
package/README.md
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
# PERS SDK React Native
|
|
2
2
|
|
|
3
|
-
A comprehensive React Native SDK for the PERS (
|
|
3
|
+
A comprehensive React Native SDK for the PERS (Phygital Experience Rewards System) platform, designed specifically for tourism loyalty applications with blockchain transaction signing capabilities.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- **🌐 Web3 Integration**: Blockchain operations and wallet management
|
|
20
|
-
- **🔒 Secure Storage**: Multiple storage strategies for different security needs
|
|
21
|
-
- **📱 Cross-Platform**: Full React Native support with optimized performance
|
|
7
|
+
- **Secure Authentication**: WebAuthn-based authentication with device biometrics
|
|
8
|
+
- **Blockchain Integration**: Complete transaction signing with PERS Signer SDK supporting EVM-compatible chains (Ethereum, Polygon, Camino, etc.)
|
|
9
|
+
- **Token Operations**: Balance checking, earning, redeeming, and transfers
|
|
10
|
+
- **Business Management**: Business profiles, campaigns, and operations
|
|
11
|
+
- **Campaign System**: Marketing campaigns, participation, and rewards
|
|
12
|
+
- **Redemption Engine**: Comprehensive reward redemption and fulfillment
|
|
13
|
+
- **Analytics**: Real-time analytics and transaction monitoring
|
|
14
|
+
- **Donations**: Charitable giving and donation management
|
|
15
|
+
- **User Management**: Profile management and user operations
|
|
16
|
+
- **Web3 Support**: EVM-compatible chain wallet operations and blockchain interactions
|
|
17
|
+
- **Secure Storage**: Multiple storage strategies with React Native Keychain
|
|
18
|
+
- **React Native Optimized**: Full platform support with automatic polyfills
|
|
22
19
|
|
|
23
20
|
## Installation
|
|
24
21
|
|
|
@@ -28,326 +25,431 @@ npm install @explorins/pers-sdk-react-native
|
|
|
28
25
|
|
|
29
26
|
### Required Dependencies
|
|
30
27
|
|
|
31
|
-
The SDK requires AsyncStorage for persistence:
|
|
32
|
-
|
|
33
28
|
```bash
|
|
34
29
|
npm install @react-native-async-storage/async-storage
|
|
35
30
|
```
|
|
36
31
|
|
|
37
|
-
### Optional Dependencies
|
|
38
|
-
|
|
39
|
-
For additional functionality, install these optional packages:
|
|
32
|
+
### Optional Dependencies (Recommended)
|
|
40
33
|
|
|
41
34
|
```bash
|
|
42
|
-
# For secure keychain storage
|
|
35
|
+
# For secure keychain storage
|
|
43
36
|
npm install react-native-keychain
|
|
44
37
|
|
|
45
|
-
# For crypto
|
|
38
|
+
# For crypto operations
|
|
46
39
|
npm install react-native-get-random-values
|
|
47
40
|
|
|
48
|
-
# For
|
|
49
|
-
npm install
|
|
50
|
-
|
|
51
|
-
# For global polyfills (if needed)
|
|
52
|
-
npm install react-native-polyfill-globals
|
|
41
|
+
# For blockchain transaction signing
|
|
42
|
+
npm install @explorins/pers-signer
|
|
53
43
|
|
|
54
|
-
# For
|
|
55
|
-
npm install
|
|
44
|
+
# For URL polyfills
|
|
45
|
+
npm install react-native-url-polyfill
|
|
56
46
|
```
|
|
57
47
|
|
|
58
48
|
## Quick Start
|
|
59
49
|
|
|
60
50
|
### 1. Setup the Provider
|
|
61
51
|
|
|
62
|
-
Wrap your app with the `PersSDKProvider`:
|
|
63
|
-
|
|
64
52
|
```typescript
|
|
65
53
|
import React from 'react';
|
|
66
54
|
import { PersSDKProvider } from '@explorins/pers-sdk-react-native';
|
|
67
55
|
|
|
68
56
|
export default function App() {
|
|
69
57
|
return (
|
|
70
|
-
<PersSDKProvider
|
|
71
|
-
|
|
58
|
+
<PersSDKProvider config={{
|
|
59
|
+
apiUrl: 'https://api.pers.ninja',
|
|
60
|
+
tenantId: 'your-tenant-id' // Optional
|
|
61
|
+
}}>
|
|
62
|
+
<NavigationContainer>
|
|
63
|
+
<YourAppContent />
|
|
64
|
+
</NavigationContainer>
|
|
72
65
|
</PersSDKProvider>
|
|
73
66
|
);
|
|
74
67
|
}
|
|
75
68
|
```
|
|
76
69
|
|
|
77
|
-
### 2.
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
import { useAuth } from '@explorins/pers-sdk-react-native';
|
|
81
|
-
|
|
82
|
-
function InitializeSDK() {
|
|
83
|
-
const { initialize, isInitialized } = useAuth();
|
|
84
|
-
|
|
85
|
-
useEffect(() => {
|
|
86
|
-
initialize({
|
|
87
|
-
apiProjectKey: 'your-project-key',
|
|
88
|
-
environment: 'production', // or 'development', 'staging'
|
|
89
|
-
});
|
|
90
|
-
}, []);
|
|
91
|
-
|
|
92
|
-
if (!isInitialized) {
|
|
93
|
-
return <Text>Initializing...</Text>;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return <YourMainComponent />;
|
|
97
|
-
}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### 3. Authentication
|
|
70
|
+
### 2. Authentication & Token Operations
|
|
101
71
|
|
|
102
72
|
```typescript
|
|
103
|
-
import {
|
|
104
|
-
|
|
105
|
-
function
|
|
106
|
-
const {
|
|
73
|
+
import { usePersSDK, useTransactionSigner } from '@explorins/pers-sdk-react-native';
|
|
74
|
+
|
|
75
|
+
function RewardScreen() {
|
|
76
|
+
const {
|
|
77
|
+
user,
|
|
78
|
+
isAuthenticated,
|
|
79
|
+
login,
|
|
80
|
+
earnTokens,
|
|
81
|
+
redeemTokens,
|
|
82
|
+
getTokenBalance
|
|
83
|
+
} = usePersSDK();
|
|
84
|
+
|
|
85
|
+
const { signAndSubmitTransactionWithJWT, isSignerAvailable } = useTransactionSigner();
|
|
107
86
|
|
|
108
87
|
const handleLogin = async () => {
|
|
109
88
|
try {
|
|
110
89
|
await login('your-jwt-token');
|
|
111
|
-
console.log('
|
|
90
|
+
console.log('Authenticated:', user?.identifier);
|
|
112
91
|
} catch (error) {
|
|
113
92
|
console.error('Login failed:', error);
|
|
114
93
|
}
|
|
115
94
|
};
|
|
116
95
|
|
|
96
|
+
const handleEarnTokens = async () => {
|
|
97
|
+
try {
|
|
98
|
+
const result = await earnTokens({
|
|
99
|
+
amount: 100,
|
|
100
|
+
source: 'activity_completion',
|
|
101
|
+
metadata: { activity: 'hotel_checkin' }
|
|
102
|
+
});
|
|
103
|
+
console.log('Earned tokens:', result);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error('Earn failed:', error);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const handleRedemption = async () => {
|
|
110
|
+
try {
|
|
111
|
+
// Step 1: Create redemption
|
|
112
|
+
const redemption = await redeemTokens({
|
|
113
|
+
amount: 50,
|
|
114
|
+
rewardType: 'discount_voucher'
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Step 2: Sign blockchain transaction
|
|
118
|
+
if (redemption.requiresBlockchainSigning && isSignerAvailable) {
|
|
119
|
+
const txResult = await signAndSubmitTransactionWithJWT(redemption.jwtToken);
|
|
120
|
+
|
|
121
|
+
if (txResult.success) {
|
|
122
|
+
console.log('Redemption completed!');
|
|
123
|
+
console.log('Transaction Hash:', txResult.transactionHash);
|
|
124
|
+
console.log('View on blockchain explorer: [Chain-specific URL]');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.error('Redemption failed:', error);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
117
132
|
return (
|
|
118
|
-
<
|
|
119
|
-
{isAuthenticated ? (
|
|
120
|
-
<
|
|
133
|
+
<ScrollView style={styles.container}>
|
|
134
|
+
{!isAuthenticated ? (
|
|
135
|
+
<TouchableOpacity onPress={handleLogin} style={styles.loginButton}>
|
|
136
|
+
<Text style={styles.buttonText}>Login with PERS</Text>
|
|
137
|
+
</TouchableOpacity>
|
|
121
138
|
) : (
|
|
122
|
-
<
|
|
139
|
+
<View>
|
|
140
|
+
<Text style={styles.welcome}>Welcome, {user?.identifier}!</Text>
|
|
141
|
+
|
|
142
|
+
<TouchableOpacity onPress={handleEarnTokens} style={styles.button}>
|
|
143
|
+
<Text style={styles.buttonText}>Earn 100 Tokens</Text>
|
|
144
|
+
</TouchableOpacity>
|
|
145
|
+
|
|
146
|
+
<TouchableOpacity
|
|
147
|
+
onPress={handleRedemption}
|
|
148
|
+
disabled={!isSignerAvailable}
|
|
149
|
+
style={[styles.button, !isSignerAvailable && styles.disabled]}
|
|
150
|
+
>
|
|
151
|
+
<Text style={styles.buttonText}>
|
|
152
|
+
{isSignerAvailable ? 'Redeem Rewards' : 'Signer Loading...'}
|
|
153
|
+
</Text>
|
|
154
|
+
</TouchableOpacity>
|
|
155
|
+
</View>
|
|
123
156
|
)}
|
|
124
|
-
</
|
|
157
|
+
</ScrollView>
|
|
125
158
|
);
|
|
126
159
|
}
|
|
127
160
|
```
|
|
128
161
|
|
|
129
|
-
##
|
|
130
|
-
|
|
131
|
-
The SDK provides multiple authentication providers for different security needs:
|
|
132
|
-
|
|
133
|
-
### BaseReactNativeAuthProvider
|
|
134
|
-
Base class for all React Native authentication providers.
|
|
135
|
-
|
|
136
|
-
### ReactNativeAuthProvider
|
|
137
|
-
Standard authentication with AsyncStorage for persistence.
|
|
138
|
-
|
|
139
|
-
```typescript
|
|
140
|
-
import { ReactNativeAuthProvider } from '@explorins/pers-sdk-react-native';
|
|
141
|
-
|
|
142
|
-
const authProvider = new ReactNativeAuthProvider('your-project-key');
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### SecureReactNativeAuthProvider
|
|
146
|
-
Secure keychain storage for sensitive data.
|
|
147
|
-
|
|
148
|
-
```typescript
|
|
149
|
-
import { SecureReactNativeAuthProvider } from '@explorins/pers-sdk-react-native';
|
|
150
|
-
|
|
151
|
-
const authProvider = new SecureReactNativeAuthProvider('your-project-key');
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## API Reference
|
|
155
|
-
|
|
156
|
-
### Available Hooks
|
|
157
|
-
|
|
158
|
-
The SDK provides comprehensive hooks for all PERS platform functionality through modern manager pattern:
|
|
159
|
-
|
|
160
|
-
#### Core Hooks
|
|
161
|
-
- **useAuth()** - Authentication state and operations (login, logout, user management)
|
|
162
|
-
- **useUsers()** - User profile management and public user data
|
|
163
|
-
- **useTokens()** - Token operations, balances, and credit/reward tokens
|
|
162
|
+
## Core Hooks
|
|
164
163
|
|
|
165
|
-
|
|
166
|
-
- **useBusiness()** - Business data, types, and operations management
|
|
167
|
-
- **useCampaigns()** - Marketing campaigns, claims, and promotions
|
|
168
|
-
- **useRedemptions()** - Reward redemption functionality and user redemptions
|
|
169
|
-
- **useTransactions()** - Transaction history, creation, and analytics
|
|
170
|
-
|
|
171
|
-
#### Platform Integration Hooks
|
|
172
|
-
- **usePurchases()** - Payment intents, purchase tokens, and purchase processing
|
|
173
|
-
- **useTenants()** - Multi-tenant configuration and admin operations
|
|
174
|
-
- **useWeb3()** - Web3 and blockchain functionality
|
|
175
|
-
|
|
176
|
-
### Hook Examples
|
|
177
|
-
|
|
178
|
-
#### useAuth()
|
|
179
|
-
|
|
180
|
-
Handles authentication state and operations.
|
|
164
|
+
### Authentication & Users
|
|
181
165
|
|
|
182
166
|
```typescript
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
isAuthenticated,
|
|
186
|
-
user,
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
loginWithRawData,
|
|
190
|
-
logout
|
|
167
|
+
// Authentication management
|
|
168
|
+
const {
|
|
169
|
+
isAuthenticated,
|
|
170
|
+
user,
|
|
171
|
+
login,
|
|
172
|
+
logout
|
|
191
173
|
} = useAuth();
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
### Storage Strategies
|
|
195
174
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
// MEMORY - Memory-only (not persistent)
|
|
175
|
+
// User profile operations
|
|
176
|
+
const {
|
|
177
|
+
getUserProfile,
|
|
178
|
+
updateUserProfile,
|
|
179
|
+
getUserPublicData
|
|
180
|
+
} = useUsers();
|
|
203
181
|
```
|
|
204
182
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
### Custom HTTP Client
|
|
183
|
+
### Token & Financial Operations
|
|
208
184
|
|
|
209
185
|
```typescript
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
186
|
+
// Token management
|
|
187
|
+
const {
|
|
188
|
+
getTokenBalance,
|
|
189
|
+
earnTokens,
|
|
190
|
+
redeemTokens,
|
|
191
|
+
transferTokens
|
|
192
|
+
} = useTokens();
|
|
193
|
+
|
|
194
|
+
// Transaction history
|
|
195
|
+
const {
|
|
196
|
+
getTransactions,
|
|
197
|
+
getTransactionById,
|
|
198
|
+
createTransaction
|
|
199
|
+
} = useTransactions();
|
|
200
|
+
|
|
201
|
+
// 🌟 Blockchain transaction signing
|
|
202
|
+
const {
|
|
203
|
+
signAndSubmitTransactionWithJWT,
|
|
204
|
+
isSignerAvailable,
|
|
205
|
+
isSignerInitialized
|
|
206
|
+
} = useTransactionSigner();
|
|
213
207
|
```
|
|
214
208
|
|
|
215
|
-
###
|
|
216
|
-
|
|
217
|
-
If you need direct access to individual SDKs:
|
|
209
|
+
### Business & Campaign Management
|
|
218
210
|
|
|
219
211
|
```typescript
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
212
|
+
// Business operations
|
|
213
|
+
const {
|
|
214
|
+
getBusinessProfile,
|
|
215
|
+
updateBusinessProfile,
|
|
216
|
+
getBusinessTypes
|
|
217
|
+
} = useBusiness();
|
|
218
|
+
|
|
219
|
+
// Campaign management
|
|
220
|
+
const {
|
|
221
|
+
getActiveCampaigns,
|
|
222
|
+
participateInCampaign,
|
|
223
|
+
claimCampaignReward
|
|
224
|
+
} = useCampaigns();
|
|
225
|
+
|
|
226
|
+
// Redemption system
|
|
227
|
+
const {
|
|
228
|
+
createRedemption,
|
|
229
|
+
getUserRedemptions,
|
|
230
|
+
getRedemptionTypes
|
|
231
|
+
} = useRedemptions();
|
|
227
232
|
```
|
|
228
233
|
|
|
229
|
-
###
|
|
230
|
-
|
|
231
|
-
For advanced usage, you can import components from the core SDK:
|
|
234
|
+
### Platform & Analytics
|
|
232
235
|
|
|
233
236
|
```typescript
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
237
|
+
// Purchase processing
|
|
238
|
+
const {
|
|
239
|
+
createPurchase,
|
|
240
|
+
getUserPurchases,
|
|
241
|
+
processPayment
|
|
242
|
+
} = usePurchases();
|
|
243
|
+
|
|
244
|
+
// Multi-tenant support
|
|
245
|
+
const {
|
|
246
|
+
getTenantConfig,
|
|
247
|
+
updateTenantConfig,
|
|
248
|
+
getTenantAdmins
|
|
249
|
+
} = useTenants();
|
|
250
|
+
|
|
251
|
+
// Analytics & reporting
|
|
252
|
+
const {
|
|
253
|
+
getTransactionAnalytics,
|
|
254
|
+
getUserAnalytics,
|
|
255
|
+
getBusinessAnalytics
|
|
256
|
+
} = useAnalytics();
|
|
257
|
+
|
|
258
|
+
// Web3 & blockchain
|
|
259
|
+
const {
|
|
260
|
+
getWalletBalance,
|
|
261
|
+
createWallet,
|
|
262
|
+
getTransactionHistory
|
|
263
|
+
} = useWeb3();
|
|
239
264
|
```
|
|
240
265
|
|
|
241
|
-
##
|
|
266
|
+
## 🔐 EVM Blockchain Transaction Signing
|
|
242
267
|
|
|
243
|
-
|
|
244
|
-
import { useAuth } from '@explorins/pers-sdk-react-native';
|
|
268
|
+
The `useTransactionSigner` hook provides secure EVM blockchain transaction signing:
|
|
245
269
|
|
|
246
|
-
|
|
247
|
-
|
|
270
|
+
```typescript
|
|
271
|
+
import { useTransactionSigner } from '@explorins/pers-sdk-react-native';
|
|
272
|
+
|
|
273
|
+
function BlockchainRedemption() {
|
|
274
|
+
const {
|
|
275
|
+
signAndSubmitTransactionWithJWT,
|
|
276
|
+
isSignerAvailable,
|
|
277
|
+
isSignerInitialized
|
|
278
|
+
} = useTransactionSigner();
|
|
279
|
+
|
|
280
|
+
const handleBlockchainRedemption = async (jwtToken: string) => {
|
|
281
|
+
if (!isSignerAvailable) {
|
|
282
|
+
console.error('EVM blockchain signer not available');
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
248
285
|
|
|
249
|
-
const handleLogin = async () => {
|
|
250
286
|
try {
|
|
251
|
-
|
|
287
|
+
// This handles the complete flow:
|
|
288
|
+
// 1. User authentication via WebAuthn
|
|
289
|
+
// 2. Transaction data fetching from PERS backend
|
|
290
|
+
// 3. Secure EVM transaction signing using device biometrics
|
|
291
|
+
// 4. EVM blockchain submission
|
|
292
|
+
const result = await signAndSubmitTransactionWithJWT(jwtToken);
|
|
293
|
+
|
|
294
|
+
if (result.success) {
|
|
295
|
+
console.log('🎉 Transaction completed!');
|
|
296
|
+
console.log('📄 Hash:', result.transactionHash);
|
|
297
|
+
console.log('🔗 View on blockchain explorer: [Chain-specific URL]');
|
|
298
|
+
|
|
299
|
+
// Handle post-transaction flow
|
|
300
|
+
if (result.shouldRedirect && result.redirectUrl) {
|
|
301
|
+
// Navigate to success page or external URL
|
|
302
|
+
Linking.openURL(result.redirectUrl);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
252
305
|
} catch (error) {
|
|
253
|
-
if (error.
|
|
254
|
-
//
|
|
255
|
-
|
|
256
|
-
|
|
306
|
+
if (error.message.includes('expired')) {
|
|
307
|
+
// JWT token expired - redirect to login
|
|
308
|
+
navigation.navigate('Login');
|
|
309
|
+
} else if (error.message.includes('cancelled')) {
|
|
310
|
+
// User cancelled WebAuthn authentication
|
|
311
|
+
console.log('User cancelled transaction');
|
|
257
312
|
} else {
|
|
258
|
-
//
|
|
313
|
+
// Other errors
|
|
314
|
+
Alert.alert('Transaction Failed', error.message);
|
|
259
315
|
}
|
|
260
316
|
}
|
|
261
317
|
};
|
|
262
|
-
}
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
## Environment Configuration
|
|
266
318
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
319
|
+
// Show loading state while signer initializes
|
|
320
|
+
if (!isSignerInitialized) {
|
|
321
|
+
return (
|
|
322
|
+
<View style={styles.loadingContainer}>
|
|
323
|
+
<ActivityIndicator size="large" />
|
|
324
|
+
<Text>Initializing EVM blockchain signer...</Text>
|
|
325
|
+
</View>
|
|
326
|
+
);
|
|
327
|
+
}
|
|
273
328
|
|
|
274
|
-
|
|
329
|
+
return (
|
|
330
|
+
<TouchableOpacity
|
|
331
|
+
onPress={() => handleBlockchainRedemption(redemptionJWT)}
|
|
332
|
+
disabled={!isSignerAvailable}
|
|
333
|
+
style={[styles.button, !isSignerAvailable && styles.disabled]}
|
|
334
|
+
>
|
|
335
|
+
<Text style={styles.buttonText}>
|
|
336
|
+
🔐 Sign & Submit Transaction
|
|
337
|
+
</Text>
|
|
338
|
+
</TouchableOpacity>
|
|
339
|
+
);
|
|
340
|
+
}
|
|
275
341
|
```
|
|
276
342
|
|
|
277
|
-
##
|
|
343
|
+
## 🛡️ Security Features
|
|
278
344
|
|
|
279
|
-
|
|
345
|
+
### WebAuthn Authentication
|
|
346
|
+
- Device biometric authentication (fingerprint, face ID, PIN)
|
|
347
|
+
- No passwords or private keys stored locally
|
|
348
|
+
- Secure hardware-backed authentication
|
|
280
349
|
|
|
281
|
-
|
|
350
|
+
### Token Storage
|
|
351
|
+
- React Native Keychain integration for sensitive data
|
|
352
|
+
- Automatic token refresh and expiration handling
|
|
353
|
+
- Multiple storage strategies (AsyncStorage, Keychain, Memory)
|
|
282
354
|
|
|
283
|
-
|
|
355
|
+
### Transaction Security
|
|
356
|
+
- JWT token validation and expiration checking
|
|
357
|
+
- Secure transaction signing without exposing private keys
|
|
358
|
+
- Automatic session management with secure caching
|
|
284
359
|
|
|
285
|
-
|
|
286
|
-
const { getTokens, getActiveCreditToken, getRewardTokens } = useTokens();
|
|
360
|
+
## 📱 Platform Support
|
|
287
361
|
|
|
288
|
-
|
|
289
|
-
|
|
362
|
+
- **iOS**: Full support with Keychain integration
|
|
363
|
+
- **Android**: Full support with Keystore integration
|
|
364
|
+
- **Expo**: Compatible with Expo managed workflow
|
|
365
|
+
- **Web**: React Native Web compatibility
|
|
290
366
|
|
|
291
|
-
|
|
292
|
-
const creditToken = await getActiveCreditToken();
|
|
367
|
+
## 🔧 Advanced Configuration
|
|
293
368
|
|
|
294
|
-
|
|
295
|
-
const rewardTokens = await getRewardTokens();
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
#### usePayments()
|
|
299
|
-
|
|
300
|
-
Handle payment processing and purchase tokens.
|
|
369
|
+
### Custom Authentication Provider
|
|
301
370
|
|
|
302
371
|
```typescript
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
// Create payment intent
|
|
306
|
-
const paymentIntent = await createPaymentIntent(100, 'usd', 'user@example.com', 'Token purchase');
|
|
307
|
-
|
|
308
|
-
// Get purchase tokens
|
|
309
|
-
const purchaseTokens = await getActivePurchaseTokens();
|
|
372
|
+
import { createReactNativeAuthProvider } from '@explorins/pers-sdk-react-native';
|
|
310
373
|
|
|
311
|
-
|
|
312
|
-
|
|
374
|
+
const authProvider = createReactNativeAuthProvider({
|
|
375
|
+
projectKey: 'your-project-key',
|
|
376
|
+
storage: 'keychain', // 'asyncStorage' | 'keychain' | 'memory'
|
|
377
|
+
biometricPrompt: 'Authenticate to access your rewards'
|
|
378
|
+
});
|
|
313
379
|
```
|
|
314
380
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
Multi-tenant configuration and management.
|
|
381
|
+
### Error Handling Patterns
|
|
318
382
|
|
|
319
383
|
```typescript
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
// Get tenant configuration
|
|
323
|
-
const tenantInfo = await getTenantInfo();
|
|
384
|
+
import { usePersSDK } from '@explorins/pers-sdk-react-native';
|
|
324
385
|
|
|
325
|
-
|
|
326
|
-
const
|
|
386
|
+
function ErrorHandlingExample() {
|
|
387
|
+
const { earnTokens } = usePersSDK();
|
|
388
|
+
const [error, setError] = useState<string | null>(null);
|
|
327
389
|
|
|
328
|
-
|
|
329
|
-
|
|
390
|
+
const handleEarnWithErrorHandling = async () => {
|
|
391
|
+
try {
|
|
392
|
+
setError(null);
|
|
393
|
+
await earnTokens({ amount: 100, source: 'activity' });
|
|
394
|
+
} catch (err) {
|
|
395
|
+
// Handle specific error types
|
|
396
|
+
if (err.code === 'NETWORK_ERROR') {
|
|
397
|
+
setError('Network connection required');
|
|
398
|
+
} else if (err.code === 'INVALID_TOKEN') {
|
|
399
|
+
setError('Please log in again');
|
|
400
|
+
} else if (err.code === 'INSUFFICIENT_BALANCE') {
|
|
401
|
+
setError('Insufficient balance for this operation');
|
|
402
|
+
} else {
|
|
403
|
+
setError(err.message || 'An unexpected error occurred');
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
}
|
|
330
408
|
```
|
|
331
409
|
|
|
332
|
-
##
|
|
333
|
-
|
|
334
|
-
### Metro Configuration
|
|
335
|
-
|
|
336
|
-
If you encounter bundling issues, add polyfill configurations to your `metro.config.js` as needed.
|
|
337
|
-
|
|
338
|
-
### Polyfill Setup
|
|
339
|
-
|
|
340
|
-
Add to your root index file:
|
|
410
|
+
## 📊 Analytics Integration
|
|
341
411
|
|
|
342
412
|
```typescript
|
|
343
|
-
import 'react-native
|
|
344
|
-
|
|
413
|
+
import { useAnalytics } from '@explorins/pers-sdk-react-native';
|
|
414
|
+
|
|
415
|
+
function AnalyticsExample() {
|
|
416
|
+
const {
|
|
417
|
+
getTransactionAnalytics,
|
|
418
|
+
getUserAnalytics,
|
|
419
|
+
trackEvent
|
|
420
|
+
} = useAnalytics();
|
|
421
|
+
|
|
422
|
+
const loadAnalytics = async () => {
|
|
423
|
+
const txAnalytics = await getTransactionAnalytics({
|
|
424
|
+
dateRange: { start: '2023-01-01', end: '2023-12-31' }
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
const userAnalytics = await getUserAnalytics();
|
|
428
|
+
|
|
429
|
+
// Track custom events
|
|
430
|
+
await trackEvent('reward_claimed', {
|
|
431
|
+
amount: 100,
|
|
432
|
+
type: 'discount_voucher',
|
|
433
|
+
timestamp: new Date().toISOString()
|
|
434
|
+
});
|
|
435
|
+
};
|
|
436
|
+
}
|
|
345
437
|
```
|
|
346
438
|
|
|
347
439
|
## Contributing
|
|
348
440
|
|
|
349
|
-
Please
|
|
441
|
+
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
350
442
|
|
|
351
443
|
## License
|
|
352
444
|
|
|
353
|
-
MIT License - see LICENSE file for details.
|
|
445
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
446
|
+
|
|
447
|
+
## Support
|
|
448
|
+
|
|
449
|
+
- Email: support@explorins.com
|
|
450
|
+
- Documentation: [https://docs.pers.ninja](https://docs.pers.ninja)
|
|
451
|
+
- Issues: [GitHub Issues](https://github.com/eXplorins/pers-sdk/issues)
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
Built with care by [eXplorins](https://explorins.com) for the tourism and loyalty industry.
|