@explorins/pers-sdk-react-native 2.2.0-beta.1 → 2.2.1
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 +8 -0
- package/dist/__tests__/PersSDKProvider.test.d.ts +2 -0
- package/dist/__tests__/PersSDKProvider.test.d.ts.map +1 -0
- package/dist/__tests__/PersSDKProvider.test.js +290 -0
- package/dist/__tests__/setup.d.ts +2 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +35 -0
- package/dist/hooks/useRedemptions.d.ts +1 -0
- package/dist/hooks/useRedemptions.d.ts.map +1 -1
- package/dist/hooks/useRedemptions.js +69 -3
- package/dist/hooks/useTokenBalances.d.ts +34 -1
- package/dist/hooks/useTokenBalances.d.ts.map +1 -1
- package/dist/hooks/useTokens.d.ts +4 -1
- package/dist/hooks/useTokens.d.ts.map +1 -1
- package/dist/hooks/useTokens.js +96 -0
- package/dist/index.js +948 -81
- package/dist/index.js.map +1 -1
- package/dist/providers/PersSDKProvider.d.ts +36 -2
- package/dist/providers/PersSDKProvider.d.ts.map +1 -1
- package/dist/providers/PersSDKProvider.js +1 -1
- package/package.json +12 -2
- package/src/__tests__/PersSDKProvider.test.tsx +420 -0
- package/src/__tests__/setup.ts +40 -0
- package/src/hooks/useRedemptions.ts +74 -4
- package/src/hooks/useTokenBalances.ts +34 -1
- package/src/hooks/useTokens.ts +100 -1
- package/src/providers/PersSDKProvider.tsx +37 -3
|
@@ -10,9 +10,42 @@ import type { TokenBalance, TokenBalanceRequest } from '@explorins/pers-sdk/web3
|
|
|
10
10
|
* This composite type combines blockchain balance data with token metadata,
|
|
11
11
|
* making it easy to display token information in UI components without
|
|
12
12
|
* needing to join data from multiple sources.
|
|
13
|
+
*
|
|
14
|
+
* ## CRITICAL: Token ID for Transactions
|
|
15
|
+
*
|
|
16
|
+
* For ERC721 (stamps) and ERC1155 (rewards), use `tokenBalance.tokenId` as the
|
|
17
|
+
* `contractTokenId` when creating transactions. This is the **on-chain token ID**
|
|
18
|
+
* assigned by the blockchain, NOT the metadata definition ID.
|
|
19
|
+
*
|
|
20
|
+
* | Token Type | tokenId meaning | Example |
|
|
21
|
+
* |------------|-----------------|---------|
|
|
22
|
+
* | ERC20 | `null` or `""` | N/A (fungible points) |
|
|
23
|
+
* | ERC721 | NFT instance ID | `"46"` (on-chain ID) |
|
|
24
|
+
* | ERC1155 | Token type ID | `"16"` (semi-fungible type) |
|
|
25
|
+
*
|
|
26
|
+
* @example Correct usage for token burn transaction
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const stampBalance = tokenBalances.find(b => b.token.type === 'ERC721');
|
|
29
|
+
*
|
|
30
|
+
* const request = buildPOSBurnRequest({
|
|
31
|
+
* amount: 1,
|
|
32
|
+
* contractAddress: stampBalance.token.contractAddress,
|
|
33
|
+
* contractTokenId: stampBalance.tokenBalance.tokenId, // ✅ Correct
|
|
34
|
+
* chainId: stampBalance.token.chainId,
|
|
35
|
+
* userId: userId,
|
|
36
|
+
* businessId: businessId
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @see {@link https://docs.explorins.com/pers-sdk/troubleshooting#stamp-voucher-transaction-fails | Troubleshooting: Stamp Transaction Fails}
|
|
13
41
|
*/
|
|
14
42
|
export interface TokenBalanceWithToken {
|
|
15
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* The balance data from blockchain
|
|
45
|
+
*
|
|
46
|
+
* **Important:** For NFT operations, use `tokenBalance.tokenId` as the `contractTokenId`
|
|
47
|
+
* in transaction requests. This is the actual on-chain ID, not the metadata definition.
|
|
48
|
+
*/
|
|
16
49
|
tokenBalance: TokenBalance;
|
|
17
50
|
/** The token definition (contract, symbol, metadata, etc.) */
|
|
18
51
|
token: TokenDTO;
|
package/src/hooks/useTokens.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useCallback } from 'react';
|
|
2
2
|
import { usePersSDK } from '../providers/PersSDKProvider';
|
|
3
|
-
import type { TokenDTO, PaginatedResponseDTO } from '@explorins/pers-sdk';
|
|
3
|
+
import type { TokenDTO, TokenMetadataDTO, PaginatedResponseDTO, TokenMetadataFilterOptions, RewardsFilterOptions, StampsFilterOptions } from '@explorins/pers-sdk';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* React hook for token operations in the PERS SDK
|
|
@@ -201,6 +201,102 @@ export const useTokens = () => {
|
|
|
201
201
|
}
|
|
202
202
|
}, [sdk, isInitialized]);
|
|
203
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Get all token metadata with filtering and pagination
|
|
206
|
+
*
|
|
207
|
+
* Retrieves token metadata (rewards/stamps) with server-side filtering.
|
|
208
|
+
* Use tokenType: 'ERC1155' for rewards, 'ERC721' for stamps.
|
|
209
|
+
*
|
|
210
|
+
* @param options - Filter and pagination options
|
|
211
|
+
* @returns Promise resolving to paginated token metadata
|
|
212
|
+
* @throws Error if SDK is not initialized
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* const { getTokenMetadata } = useTokens();
|
|
217
|
+
* const rewards = await getTokenMetadata({
|
|
218
|
+
* tokenType: 'ERC1155',
|
|
219
|
+
* active: true,
|
|
220
|
+
* limit: 10
|
|
221
|
+
* });
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
const getTokenMetadata = useCallback(async (options?: TokenMetadataFilterOptions): Promise<PaginatedResponseDTO<TokenMetadataDTO>> => {
|
|
225
|
+
if (!isInitialized || !sdk) {
|
|
226
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
const result = await sdk.tokens.getTokenMetadata(options);
|
|
231
|
+
return result;
|
|
232
|
+
} catch (error) {
|
|
233
|
+
console.error('Failed to fetch token metadata:', error);
|
|
234
|
+
throw error;
|
|
235
|
+
}
|
|
236
|
+
}, [sdk, isInitialized]);
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Get rewards (ERC1155 token metadata) with filtering and pagination
|
|
240
|
+
*
|
|
241
|
+
* Convenience method for fetching reward metadata. Rewards are ERC1155 tokens
|
|
242
|
+
* that represent collectible items, vouchers, or other redeemable rewards.
|
|
243
|
+
*
|
|
244
|
+
* @param options - Filter and pagination options
|
|
245
|
+
* @returns Promise resolving to paginated reward metadata
|
|
246
|
+
* @throws Error if SDK is not initialized
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* ```typescript
|
|
250
|
+
* const { getRewards } = useTokens();
|
|
251
|
+
* const rewards = await getRewards({ active: true, limit: 10 });
|
|
252
|
+
* console.log(`Found ${rewards.pagination.total} rewards`);
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
const getRewards = useCallback(async (options?: RewardsFilterOptions): Promise<PaginatedResponseDTO<TokenMetadataDTO>> => {
|
|
256
|
+
if (!isInitialized || !sdk) {
|
|
257
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
try {
|
|
261
|
+
const result = await sdk.tokens.getRewards(options);
|
|
262
|
+
return result;
|
|
263
|
+
} catch (error) {
|
|
264
|
+
console.error('Failed to fetch rewards:', error);
|
|
265
|
+
throw error;
|
|
266
|
+
}
|
|
267
|
+
}, [sdk, isInitialized]);
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Get stamps (ERC721 token metadata) with filtering and pagination
|
|
271
|
+
*
|
|
272
|
+
* Convenience method for fetching stamp metadata. Stamps are ERC721 tokens
|
|
273
|
+
* that represent achievements, badges, or collectible status markers.
|
|
274
|
+
*
|
|
275
|
+
* @param options - Filter and pagination options
|
|
276
|
+
* @returns Promise resolving to paginated stamp metadata
|
|
277
|
+
* @throws Error if SDK is not initialized
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* ```typescript
|
|
281
|
+
* const { getStamps } = useTokens();
|
|
282
|
+
* const stamps = await getStamps({ active: true, limit: 10 });
|
|
283
|
+
* console.log(`Found ${stamps.pagination.total} stamps`);
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
const getStamps = useCallback(async (options?: StampsFilterOptions): Promise<PaginatedResponseDTO<TokenMetadataDTO>> => {
|
|
287
|
+
if (!isInitialized || !sdk) {
|
|
288
|
+
throw new Error('SDK not initialized. Call initialize() first.');
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
try {
|
|
292
|
+
const result = await sdk.tokens.getStamps(options);
|
|
293
|
+
return result;
|
|
294
|
+
} catch (error) {
|
|
295
|
+
console.error('Failed to fetch stamps:', error);
|
|
296
|
+
throw error;
|
|
297
|
+
}
|
|
298
|
+
}, [sdk, isInitialized]);
|
|
299
|
+
|
|
204
300
|
return {
|
|
205
301
|
getTokens,
|
|
206
302
|
getActiveCreditToken,
|
|
@@ -208,6 +304,9 @@ export const useTokens = () => {
|
|
|
208
304
|
getTokenTypes,
|
|
209
305
|
getStatusTokens,
|
|
210
306
|
getTokenByContract,
|
|
307
|
+
getTokenMetadata,
|
|
308
|
+
getRewards,
|
|
309
|
+
getStamps,
|
|
211
310
|
isAvailable: isInitialized && !!sdk?.tokens,
|
|
212
311
|
};
|
|
213
312
|
};
|
|
@@ -27,11 +27,45 @@ export type { PersConfig } from '@explorins/pers-sdk/core';
|
|
|
27
27
|
/**
|
|
28
28
|
* Context interface for PERS SDK React Native integration
|
|
29
29
|
*
|
|
30
|
+
* ## Session Restoration Behavior
|
|
31
|
+
*
|
|
32
|
+
* Session restoration is **asynchronous**. When the app starts:
|
|
33
|
+
* 1. `isInitialized` becomes `true` when SDK is ready
|
|
34
|
+
* 2. Session restoration happens automatically
|
|
35
|
+
* 3. `isAuthenticated` and `user` update when restoration completes
|
|
36
|
+
*
|
|
37
|
+
* **Always check `isInitialized` AND `isAuthenticated` before using `user`:**
|
|
38
|
+
*
|
|
39
|
+
* ```tsx
|
|
40
|
+
* const { user, isInitialized, isAuthenticated } = usePersSDK();
|
|
41
|
+
*
|
|
42
|
+
* if (!isInitialized) return <LoadingSpinner />;
|
|
43
|
+
* if (!isAuthenticated || !user) return <LoginScreen />;
|
|
44
|
+
* return <WalletContent user={user} />;
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* **Why `user` might be null on app restart:**
|
|
48
|
+
* - Access tokens expire after 1 hour (auto-refreshed if app is active)
|
|
49
|
+
* - Refresh tokens expire after 30 days (user must re-login)
|
|
50
|
+
* - Session restoration is in progress
|
|
51
|
+
*
|
|
52
|
+
* Listen for auth events to debug:
|
|
53
|
+
* ```typescript
|
|
54
|
+
* sdk.events.subscribe((event) => {
|
|
55
|
+
* console.log('[Auth Event]', event.type, event.details);
|
|
56
|
+
* }, { domains: ['authentication'], replay: true });
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* | Event | Meaning |
|
|
60
|
+
* |-------|---------|
|
|
61
|
+
* | `session_restored` | Tokens valid, user logged in |
|
|
62
|
+
* | `session_restoration_failed` | Tokens expired, needs re-login |
|
|
63
|
+
*
|
|
30
64
|
* @property sdk - Main SDK instance (null until initialized)
|
|
31
65
|
* @property authProvider - Platform-specific auth provider
|
|
32
|
-
* @property isInitialized - Whether SDK has been initialized
|
|
66
|
+
* @property isInitialized - Whether SDK has been initialized (not whether user is authenticated!)
|
|
33
67
|
* @property isAuthenticated - Whether user is currently authenticated
|
|
34
|
-
* @property user - Current user data (null if not authenticated)
|
|
68
|
+
* @property user - Current user data (null if not authenticated OR restoration in progress)
|
|
35
69
|
*/
|
|
36
70
|
export interface PersSDKContext {
|
|
37
71
|
// Main SDK instance
|
|
@@ -168,7 +202,7 @@ export const PersSDKProvider: React.FC<{
|
|
|
168
202
|
}
|
|
169
203
|
}
|
|
170
204
|
|
|
171
|
-
if (event.type === 'logout_success' || event.type === 'session_restoration_failed'
|
|
205
|
+
if (event.type === 'logout_success' || event.type === 'session_restoration_failed') {
|
|
172
206
|
setUser(null);
|
|
173
207
|
setIsAuthenticated(false);
|
|
174
208
|
}
|