@explorins/pers-sdk-react-native 2.2.0 → 2.2.2

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.
@@ -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
@@ -1,42 +0,0 @@
1
- /// <reference types="jest" />
2
- export interface PersConfig {
3
- apiProjectKey?: string;
4
- environment?: 'staging' | 'production';
5
- captureWalletEvents?: boolean;
6
- authProvider?: any;
7
- dpop?: {
8
- enabled?: boolean;
9
- cryptoProvider?: any;
10
- };
11
- }
12
- export declare const createMockEventEmitter: () => {
13
- subscribe: jest.Mock<() => void, [callback: (event: any) => void, options?: any], any>;
14
- emit: (event: any) => void;
15
- _subscribers: {
16
- callback: (event: any) => void;
17
- options?: any;
18
- }[];
19
- };
20
- export declare class PersSDK {
21
- events: ReturnType<typeof createMockEventEmitter>;
22
- auth: any;
23
- users: any;
24
- constructor(_httpClient: any, _config: PersConfig);
25
- restoreSession: jest.Mock<any, any, any>;
26
- _mockEmitEvent(event: any): void;
27
- }
28
- export declare class DefaultAuthProvider {
29
- constructor(_projectKey?: string, _options?: any);
30
- }
31
- export type AuthManager = any;
32
- export type UserManager = any;
33
- export type TokenManager = any;
34
- export type BusinessManager = any;
35
- export type CampaignManager = any;
36
- export type RedemptionManager = any;
37
- export type TransactionManager = any;
38
- export type PurchaseManager = any;
39
- export type TenantManager = any;
40
- export type AnalyticsManager = any;
41
- export type DonationManager = any;
42
- //# sourceMappingURL=pers-sdk-core.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pers-sdk-core.d.ts","sourceRoot":"","sources":["../../../src/__tests__/__mocks__/pers-sdk-core.ts"],"names":[],"mappings":";AAEA,MAAM,WAAW,UAAU;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;IACvC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,cAAc,CAAC,EAAE,GAAG,CAAC;KACtB,CAAC;CACH;AAGD,eAAO,MAAM,sBAAsB;wDAIO,GAAG,KAAK,IAAI;kBAapC,GAAG;;kBAhBkB,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI;kBAAY,GAAG;;CAyBzE,CAAC;AAGF,qBAAa,OAAO;IAClB,MAAM,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;IAClD,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,EAAE,GAAG,CAAC;gBAEC,WAAW,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU;IAUjD,cAAc,2BAAqC;IAGnD,cAAc,CAAC,KAAK,EAAE,GAAG;CAG1B;AAGD,qBAAa,mBAAmB;gBAClB,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG;CACjD;AAGD,MAAM,MAAM,WAAW,GAAG,GAAG,CAAC;AAC9B,MAAM,MAAM,WAAW,GAAG,GAAG,CAAC;AAC9B,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC;AAC/B,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC;AAClC,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC;AAClC,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC;AACpC,MAAM,MAAM,kBAAkB,GAAG,GAAG,CAAC;AACrC,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC;AAClC,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC;AAChC,MAAM,MAAM,gBAAgB,GAAG,GAAG,CAAC;AACnC,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC"}
@@ -1,48 +0,0 @@
1
- // Mock @explorins/pers-sdk/core
2
- // Create mock event emitter factory
3
- export const createMockEventEmitter = () => {
4
- const subscribers = [];
5
- return {
6
- subscribe: jest.fn((callback, options) => {
7
- subscribers.push({ callback, options });
8
- // Replay immediately if requested
9
- if (options?.replay) {
10
- // No events to replay in mock
11
- }
12
- return () => {
13
- const index = subscribers.findIndex(s => s.callback === callback);
14
- if (index > -1)
15
- subscribers.splice(index, 1);
16
- };
17
- }),
18
- emit: (event) => {
19
- subscribers.forEach(({ callback, options }) => {
20
- if (!options?.domains || options.domains.includes(event.domain)) {
21
- callback(event);
22
- }
23
- });
24
- },
25
- _subscribers: subscribers
26
- };
27
- };
28
- // Mock PersSDK class
29
- export class PersSDK {
30
- constructor(_httpClient, _config) {
31
- this.restoreSession = jest.fn().mockResolvedValue(null);
32
- this.events = createMockEventEmitter();
33
- this.auth = {
34
- ensureValidToken: jest.fn().mockResolvedValue(true)
35
- };
36
- this.users = {
37
- getCurrentUser: jest.fn().mockResolvedValue({ id: 'user-1', email: 'test@test.com' })
38
- };
39
- }
40
- // Helper for tests to emit events
41
- _mockEmitEvent(event) {
42
- this.events.emit(event);
43
- }
44
- }
45
- // Mock DefaultAuthProvider
46
- export class DefaultAuthProvider {
47
- constructor(_projectKey, _options) { }
48
- }
@@ -1,15 +0,0 @@
1
- export interface UserDTO {
2
- id: string;
3
- email?: string;
4
- firstName?: string;
5
- lastName?: string;
6
- walletAddress?: string;
7
- createdAt?: string;
8
- updatedAt?: string;
9
- }
10
- export interface AdminDTO {
11
- id: string;
12
- email?: string;
13
- role?: string;
14
- }
15
- //# sourceMappingURL=pers-shared.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pers-shared.d.ts","sourceRoot":"","sources":["../../../src/__tests__/__mocks__/pers-shared.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -1,2 +0,0 @@
1
- // Mock @explorins/pers-shared
2
- export {};
@@ -1,83 +0,0 @@
1
- // Mock @explorins/pers-sdk/core
2
-
3
- export interface PersConfig {
4
- apiProjectKey?: string;
5
- environment?: 'staging' | 'production';
6
- captureWalletEvents?: boolean;
7
- authProvider?: any;
8
- dpop?: {
9
- enabled?: boolean;
10
- cryptoProvider?: any;
11
- };
12
- }
13
-
14
- // Create mock event emitter factory
15
- export const createMockEventEmitter = () => {
16
- const subscribers: Array<{ callback: (event: any) => void; options?: any }> = [];
17
-
18
- return {
19
- subscribe: jest.fn((callback: (event: any) => void, options?: any) => {
20
- subscribers.push({ callback, options });
21
-
22
- // Replay immediately if requested
23
- if (options?.replay) {
24
- // No events to replay in mock
25
- }
26
-
27
- return () => {
28
- const index = subscribers.findIndex(s => s.callback === callback);
29
- if (index > -1) subscribers.splice(index, 1);
30
- };
31
- }),
32
- emit: (event: any) => {
33
- subscribers.forEach(({ callback, options }) => {
34
- if (!options?.domains || options.domains.includes(event.domain)) {
35
- callback(event);
36
- }
37
- });
38
- },
39
- _subscribers: subscribers
40
- };
41
- };
42
-
43
- // Mock PersSDK class
44
- export class PersSDK {
45
- events: ReturnType<typeof createMockEventEmitter>;
46
- auth: any;
47
- users: any;
48
-
49
- constructor(_httpClient: any, _config: PersConfig) {
50
- this.events = createMockEventEmitter();
51
- this.auth = {
52
- ensureValidToken: jest.fn().mockResolvedValue(true)
53
- };
54
- this.users = {
55
- getCurrentUser: jest.fn().mockResolvedValue({ id: 'user-1', email: 'test@test.com' })
56
- };
57
- }
58
-
59
- restoreSession = jest.fn().mockResolvedValue(null);
60
-
61
- // Helper for tests to emit events
62
- _mockEmitEvent(event: any) {
63
- this.events.emit(event);
64
- }
65
- }
66
-
67
- // Mock DefaultAuthProvider
68
- export class DefaultAuthProvider {
69
- constructor(_projectKey?: string, _options?: any) {}
70
- }
71
-
72
- // Mock manager types
73
- export type AuthManager = any;
74
- export type UserManager = any;
75
- export type TokenManager = any;
76
- export type BusinessManager = any;
77
- export type CampaignManager = any;
78
- export type RedemptionManager = any;
79
- export type TransactionManager = any;
80
- export type PurchaseManager = any;
81
- export type TenantManager = any;
82
- export type AnalyticsManager = any;
83
- export type DonationManager = any;
@@ -1,17 +0,0 @@
1
- // Mock @explorins/pers-shared
2
-
3
- export interface UserDTO {
4
- id: string;
5
- email?: string;
6
- firstName?: string;
7
- lastName?: string;
8
- walletAddress?: string;
9
- createdAt?: string;
10
- updatedAt?: string;
11
- }
12
-
13
- export interface AdminDTO {
14
- id: string;
15
- email?: string;
16
- role?: string;
17
- }