@explorins/pers-sdk-react-native 1.5.36 → 2.0.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.
Files changed (51) hide show
  1. package/README.md +329 -0
  2. package/dist/hooks/index.d.ts +2 -0
  3. package/dist/hooks/index.d.ts.map +1 -1
  4. package/dist/hooks/index.js +1 -0
  5. package/dist/hooks/useBusiness.d.ts +5 -5
  6. package/dist/hooks/useBusiness.d.ts.map +1 -1
  7. package/dist/hooks/useCampaigns.d.ts +8 -8
  8. package/dist/hooks/useCampaigns.d.ts.map +1 -1
  9. package/dist/hooks/useCampaigns.js +3 -3
  10. package/dist/hooks/useDonations.d.ts +2 -2
  11. package/dist/hooks/useDonations.d.ts.map +1 -1
  12. package/dist/hooks/useEvents.d.ts +178 -0
  13. package/dist/hooks/useEvents.d.ts.map +1 -0
  14. package/dist/hooks/useEvents.js +312 -0
  15. package/dist/hooks/usePurchases.d.ts +3 -3
  16. package/dist/hooks/usePurchases.d.ts.map +1 -1
  17. package/dist/hooks/useRedemptions.d.ts +6 -5
  18. package/dist/hooks/useRedemptions.d.ts.map +1 -1
  19. package/dist/hooks/useRedemptions.js +13 -19
  20. package/dist/hooks/useTenants.d.ts +2 -2
  21. package/dist/hooks/useTenants.d.ts.map +1 -1
  22. package/dist/hooks/useTokens.d.ts +4 -4
  23. package/dist/hooks/useTokens.d.ts.map +1 -1
  24. package/dist/hooks/useTransactionSigner.d.ts +2 -0
  25. package/dist/hooks/useTransactionSigner.d.ts.map +1 -1
  26. package/dist/hooks/useTransactionSigner.js +68 -0
  27. package/dist/hooks/useTransactions.d.ts +3 -3
  28. package/dist/hooks/useTransactions.d.ts.map +1 -1
  29. package/dist/hooks/useUserStatus.d.ts +3 -3
  30. package/dist/hooks/useUserStatus.d.ts.map +1 -1
  31. package/dist/hooks/useUsers.d.ts +3 -3
  32. package/dist/hooks/useUsers.d.ts.map +1 -1
  33. package/dist/index.d.ts +83 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +2986 -653
  36. package/dist/index.js.map +1 -1
  37. package/package.json +3 -3
  38. package/src/hooks/index.ts +3 -1
  39. package/src/hooks/useBusiness.ts +5 -5
  40. package/src/hooks/useCampaigns.ts +12 -11
  41. package/src/hooks/useDonations.ts +2 -2
  42. package/src/hooks/useEvents.ts +360 -0
  43. package/src/hooks/usePurchases.ts +3 -3
  44. package/src/hooks/useRedemptions.ts +16 -22
  45. package/src/hooks/useTenants.ts +2 -2
  46. package/src/hooks/useTokens.ts +4 -4
  47. package/src/hooks/useTransactionSigner.ts +73 -0
  48. package/src/hooks/useTransactions.ts +4 -3
  49. package/src/hooks/useUserStatus.ts +3 -3
  50. package/src/hooks/useUsers.ts +3 -3
  51. package/src/index.ts +105 -2
package/README.md CHANGED
@@ -331,8 +331,189 @@ const {
331
331
  const {
332
332
  getDonationTypes
333
333
  } = useDonations();
334
+
335
+ // Event subscriptions (notifications, logging)
336
+ const {
337
+ subscribe, // Subscribe to SDK events
338
+ once, // One-time event listener
339
+ clear, // Clear all subscriptions
340
+ isAvailable, // Event system available
341
+ subscriberCount // Active subscriber count
342
+ } = useEvents();
334
343
  ```
335
344
 
345
+ ## Event System
346
+
347
+ The `useEvents` hook provides access to SDK-wide events for showing notifications, logging, and reacting to SDK operations. All events include a `userMessage` field ready for UI display.
348
+
349
+ ### Basic Usage
350
+
351
+ ```typescript
352
+ import { useEvents } from '@explorins/pers-sdk-react-native';
353
+ import { useEffect } from 'react';
354
+
355
+ function NotificationHandler() {
356
+ const { subscribe, isAvailable } = useEvents();
357
+
358
+ useEffect(() => {
359
+ if (!isAvailable) return;
360
+
361
+ // Subscribe to all events
362
+ const unsubscribe = subscribe((event) => {
363
+ showNotification(event.userMessage, event.level);
364
+ });
365
+
366
+ return () => unsubscribe(); // Cleanup on unmount
367
+ }, [subscribe, isAvailable]);
368
+ }
369
+ ```
370
+
371
+ ### Filtering Events
372
+
373
+ ```typescript
374
+ // Only transaction successes
375
+ subscribe(
376
+ (event) => {
377
+ playSuccessSound();
378
+ showConfetti();
379
+ },
380
+ { domain: 'transaction', level: 'success' }
381
+ );
382
+
383
+ // Only errors (for logging)
384
+ subscribe(
385
+ (event) => {
386
+ logToSentry(event);
387
+ },
388
+ { level: 'error' }
389
+ );
390
+
391
+ // One-time event (auto-unsubscribes)
392
+ once(
393
+ (event) => {
394
+ console.log('First transaction completed!');
395
+ },
396
+ { domain: 'transaction', level: 'success' }
397
+ );
398
+ ```
399
+
400
+ ### Event Domains
401
+
402
+ | Domain | Events |
403
+ |--------|--------|
404
+ | `auth` | Login, logout, token refresh |
405
+ | `user` | Profile updates |
406
+ | `transaction` | Created, completed, failed |
407
+ | `campaign` | Claimed, activated |
408
+ | `redemption` | Redeemed, expired |
409
+ | `business` | Created, updated, membership |
410
+ | `api` | Network errors, validation errors |
411
+
412
+ ### Event Structure
413
+
414
+ ```typescript
415
+ interface PersEvent {
416
+ id: string; // Unique event ID
417
+ timestamp: number; // Unix timestamp (ms)
418
+ domain: string; // Event domain (transaction, auth, etc.)
419
+ type: string; // Event type within domain
420
+ level: 'success' | 'error';
421
+ userMessage: string; // Ready for UI display
422
+ action?: string; // Suggested action
423
+ details?: object; // Additional data
424
+ }
425
+ ```
426
+
427
+ ---
428
+
429
+ ## POS Transaction Flow
430
+
431
+ For Point-of-Sale scenarios where a **business submits a transaction on behalf of a user**, use the `buildPOSTransferRequest` helper:
432
+
433
+ ```typescript
434
+ import {
435
+ useTransactions,
436
+ buildPOSTransferRequest,
437
+ useEvents
438
+ } from '@explorins/pers-sdk-react-native';
439
+
440
+ function POSScreen() {
441
+ const { createTransaction, signingStatus } = useTransactions();
442
+ const { subscribe, isAvailable } = useEvents();
443
+
444
+ // Listen for transaction events
445
+ useEffect(() => {
446
+ if (!isAvailable) return;
447
+
448
+ const unsubscribe = subscribe(
449
+ (event) => {
450
+ if (event.level === 'success') {
451
+ Alert.alert('Success', event.userMessage);
452
+ }
453
+ },
454
+ { domain: 'transaction' }
455
+ );
456
+
457
+ return () => unsubscribe();
458
+ }, [subscribe, isAvailable]);
459
+
460
+ const handlePOSTransaction = async (
461
+ userAccountId: string,
462
+ businessAccountId: string,
463
+ amount: number,
464
+ token: TokenDTO
465
+ ) => {
466
+ // Build POS transfer request
467
+ const request = buildPOSTransferRequest({
468
+ amount,
469
+ contractAddress: token.contractAddress,
470
+ chainId: token.chainId,
471
+ userAccountId, // User sending tokens
472
+ businessAccountId // Business receiving & authorized to submit
473
+ });
474
+
475
+ // Create and sign transaction
476
+ const result = await createTransaction(request, (status, message) => {
477
+ console.log(`Signing: ${status} - ${message}`);
478
+ });
479
+
480
+ console.log('Transaction created:', result.transaction?.id);
481
+ };
482
+ }
483
+ ```
484
+
485
+ ### POS Authorization Fields
486
+
487
+ The `buildPOSTransferRequest` helper automatically sets:
488
+
489
+ | Field | Value | Purpose |
490
+ |-------|-------|---------|
491
+ | `engagedBusinessId` | Business ID | Business commercially involved (for reporting) |
492
+ | `authorizedSubmitterId` | Business ID | Entity authorized to submit the signed tx |
493
+ | `authorizedSubmitterType` | `BUSINESS` | Type of authorized submitter |
494
+
495
+ For custom scenarios, use `buildTransferRequest` with manual POS fields:
496
+
497
+ ```typescript
498
+ import { buildTransferRequest, AccountOwnerType } from '@explorins/pers-sdk-react-native';
499
+
500
+ const request = buildTransferRequest({
501
+ amount: 100,
502
+ contractAddress: '0x...',
503
+ chainId: 137,
504
+ senderAccountId: 'user-123',
505
+ senderAccountType: AccountOwnerType.USER,
506
+ recipientAccountId: 'business-456',
507
+ recipientAccountType: AccountOwnerType.BUSINESS,
508
+ // POS authorization
509
+ engagedBusinessId: 'business-456',
510
+ authorizedSubmitterId: 'business-456',
511
+ authorizedSubmitterType: AccountOwnerType.BUSINESS
512
+ });
513
+ ```
514
+
515
+ ---
516
+
336
517
  ## Token Collection Helper Methods
337
518
 
338
519
  The `useWeb3` hook includes helper methods for querying token balances from any blockchain address. These work with **all token standards** (ERC-20, ERC-721, ERC-1155).
@@ -598,6 +779,154 @@ function AnalyticsExample() {
598
779
  }
599
780
  ```
600
781
 
782
+ ## Migration Guide
783
+
784
+ ### v2.0.0 Breaking Changes - Pagination
785
+
786
+ **Version 2.0.0 introduces standardized pagination** across all hooks that return lists. Previously, hooks returned raw arrays. Now they return `PaginatedResponseDTO<T>` with pagination metadata.
787
+
788
+ #### What Changed
789
+
790
+ All hooks returning lists now return paginated responses:
791
+
792
+ ```typescript
793
+ // ❌ OLD (v1.x) - Direct array
794
+ const businesses: BusinessDTO[] = await getActiveBusinesses();
795
+
796
+ // ✅ NEW (v2.x) - Paginated response
797
+ const response: PaginatedResponseDTO<BusinessDTO> = await getActiveBusinesses();
798
+ const businesses: BusinessDTO[] = response.data;
799
+ ```
800
+
801
+ #### Affected Hooks
802
+
803
+ | Hook | Method | Return Type |
804
+ |------|--------|-------------|
805
+ | `useBusiness` | `getActiveBusinesses()` | `PaginatedResponseDTO<BusinessDTO>` |
806
+ | `useBusiness` | `getBusinessTypes()` | `PaginatedResponseDTO<BusinessTypeDTO>` |
807
+ | `useCampaigns` | `getActiveCampaigns()` | `PaginatedResponseDTO<CampaignDTO>` |
808
+ | `useCampaigns` | `getUserClaims()` | `PaginatedResponseDTO<CampaignClaimDTO>` |
809
+ | `useTokens` | `getTokens()` | `PaginatedResponseDTO<TokenDTO>` |
810
+ | `useTokens` | `getRewardTokens()` | `PaginatedResponseDTO<TokenDTO>` |
811
+ | `useTokens` | `getStatusTokens()` | `PaginatedResponseDTO<TokenDTO>` |
812
+ | `useRedemptions` | `getActiveRedemptions()` | `PaginatedResponseDTO<RedemptionDTO>` |
813
+ | `useRedemptions` | `getUserRedemptions()` | `PaginatedResponseDTO<RedemptionDTO>` |
814
+ | `useTransactions` | `getUserTransactionHistory()` | `PaginatedResponseDTO<TransactionDTO>` |
815
+ | `usePurchases` | `getAllUserPurchases()` | `PaginatedResponseDTO<PurchaseDTO>` |
816
+ | `usePurchases` | `getActivePurchaseTokens()` | `PaginatedResponseDTO<PurchaseTokenDTO>` |
817
+ | `useDonations` | `getDonationTypes()` | `PaginatedResponseDTO<DonationTypeDTO>` |
818
+
819
+ #### PaginatedResponseDTO Structure
820
+
821
+ ```typescript
822
+ import type { PaginatedResponseDTO } from '@explorins/pers-shared';
823
+
824
+ interface PaginatedResponseDTO<T> {
825
+ data: T[]; // Array of results
826
+ pagination: {
827
+ currentPage: number; // Current page number (1-indexed)
828
+ pageSize: number; // Items per page
829
+ totalItems: number; // Total number of items across all pages
830
+ totalPages: number; // Total number of pages
831
+ };
832
+ }
833
+ ```
834
+
835
+ #### Migration Examples
836
+
837
+ **Before (v1.x):**
838
+ ```typescript
839
+ const businesses = await getActiveBusinesses();
840
+ console.log('Business count:', businesses.length);
841
+ businesses.forEach(b => console.log(b.name));
842
+ ```
843
+
844
+ **After (v2.x):**
845
+ ```typescript
846
+ const response = await getActiveBusinesses();
847
+ console.log('Business count:', response.data.length);
848
+ console.log('Total businesses:', response.pagination.totalItems);
849
+ response.data.forEach(b => console.log(b.name));
850
+ ```
851
+
852
+ **With Pagination Parameters:**
853
+ ```typescript
854
+ // Fetch page 2 with 20 items per page
855
+ const response = await getActiveBusinesses({ page: 2, pageSize: 20 });
856
+
857
+ console.log(`Page ${response.pagination.currentPage} of ${response.pagination.totalPages}`);
858
+ console.log(`Showing ${response.data.length} businesses`);
859
+ ```
860
+
861
+ #### React Native Component Example
862
+
863
+ ```typescript
864
+ import { useState, useEffect } from 'react';
865
+ import { useBusiness } from '@explorins/pers-sdk-react-native';
866
+ import { View, Text, FlatList, ActivityIndicator } from 'react-native';
867
+
868
+ function BusinessListScreen() {
869
+ const { getActiveBusinesses } = useBusiness();
870
+ const [businesses, setBusinesses] = useState<BusinessDTO[]>([]);
871
+ const [pagination, setPagination] = useState(null);
872
+ const [loading, setLoading] = useState(true);
873
+
874
+ useEffect(() => {
875
+ loadBusinesses();
876
+ }, []);
877
+
878
+ const loadBusinesses = async (page = 1) => {
879
+ try {
880
+ setLoading(true);
881
+ const response = await getActiveBusinesses({ page, pageSize: 20 });
882
+ setBusinesses(response.data);
883
+ setPagination(response.pagination);
884
+ } catch (error) {
885
+ console.error('Failed to load businesses:', error);
886
+ } finally {
887
+ setLoading(false);
888
+ }
889
+ };
890
+
891
+ if (loading) return <ActivityIndicator />;
892
+
893
+ return (
894
+ <View>
895
+ <Text>
896
+ Showing {businesses.length} of {pagination?.totalItems} businesses
897
+ </Text>
898
+ <FlatList
899
+ data={businesses}
900
+ keyExtractor={(item) => item.id}
901
+ renderItem={({ item }) => <BusinessCard business={item} />}
902
+ />
903
+ <Text>Page {pagination?.currentPage} of {pagination?.totalPages}</Text>
904
+ </View>
905
+ );
906
+ }
907
+ ```
908
+
909
+ #### Quick Fix for Existing Code
910
+
911
+ If you want minimal code changes, extract `.data` immediately:
912
+
913
+ ```typescript
914
+ // Quick adaptation in your hooks
915
+ const businesses = (await getActiveBusinesses()).data;
916
+ const campaigns = (await getActiveCampaigns()).data;
917
+ const tokens = (await getTokens()).data;
918
+ ```
919
+
920
+ #### Benefits of Pagination
921
+
922
+ - **Performance**: Load only what you need, not entire datasets
923
+ - **Consistency**: All list endpoints follow the same pattern
924
+ - **Metadata**: Access total counts without loading all items
925
+ - **Better UX**: Build proper pagination UI components
926
+ - **Memory Efficiency**: Reduced memory footprint for large datasets
927
+
928
+ ---
929
+
601
930
  ## Contributing
602
931
 
603
932
  We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
@@ -13,7 +13,9 @@ export { useUserStatus } from './useUserStatus';
13
13
  export { useFiles } from './useFiles';
14
14
  export { useAnalytics } from './useAnalytics';
15
15
  export { useDonations } from './useDonations';
16
+ export { useEvents } from './useEvents';
16
17
  export type { RawUserData } from './useAuth';
17
18
  export type { TransactionSignerHook, SubmissionResult, AuthenticatedUser, TransactionSigningResult, StatusUpdateData, OnStatusUpdateFn, SigningStatus as SigningStatusType } from './useTransactionSigner';
18
19
  export type { AccountOwnedTokensResult, Web3Hook } from './useWeb3';
20
+ export type { EventsHook, PersEvent, EventHandler, EventFilter, Unsubscribe } from './useEvents';
19
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EACV,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,IAAI,iBAAiB,EACnC,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,wBAAwB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EACV,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,IAAI,iBAAiB,EACnC,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,wBAAwB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACpE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
@@ -14,3 +14,4 @@ export { useUserStatus } from './useUserStatus';
14
14
  export { useFiles } from './useFiles';
15
15
  export { useAnalytics } from './useAnalytics';
16
16
  export { useDonations } from './useDonations';
17
+ export { useEvents } from './useEvents';
@@ -1,4 +1,4 @@
1
- import type { BusinessDTO, BusinessTypeDTO, BusinessUpdateRequestDTO, BusinessToggleActiveRequestDTO } from '@explorins/pers-shared';
1
+ import type { BusinessDTO, BusinessTypeDTO, BusinessUpdateRequestDTO, BusinessToggleActiveRequestDTO, PaginatedResponseDTO } from '@explorins/pers-shared';
2
2
  /**
3
3
  * React hook for business operations in the PERS SDK
4
4
  *
@@ -34,12 +34,12 @@ import type { BusinessDTO, BusinessTypeDTO, BusinessUpdateRequestDTO, BusinessTo
34
34
  * ```
35
35
  */
36
36
  export declare const useBusiness: () => {
37
- getActiveBusinesses: () => Promise<BusinessDTO[]>;
38
- getBusinessTypes: () => Promise<BusinessTypeDTO[]>;
39
- getBusinesses: () => Promise<BusinessDTO[]>;
37
+ getActiveBusinesses: () => Promise<PaginatedResponseDTO<BusinessDTO>>;
38
+ getBusinessTypes: () => Promise<PaginatedResponseDTO<BusinessTypeDTO>>;
39
+ getBusinesses: () => Promise<PaginatedResponseDTO<BusinessDTO>>;
40
40
  getBusinessById: (businessId: string) => Promise<BusinessDTO | null>;
41
41
  getBusinessByAccount: (accountAddress: string) => Promise<BusinessDTO>;
42
- getBusinessesByType: (typeId: string) => Promise<BusinessDTO[]>;
42
+ getBusinessesByType: (typeId: string) => Promise<PaginatedResponseDTO<BusinessDTO>>;
43
43
  createBusiness: (displayName: string) => Promise<BusinessDTO>;
44
44
  updateBusiness: (businessId: string, businessData: BusinessUpdateRequestDTO) => Promise<BusinessDTO>;
45
45
  toggleBusinessStatus: (businessId: string, toggleData: BusinessToggleActiveRequestDTO) => Promise<BusinessDTO>;
@@ -1 +1 @@
1
- {"version":3,"file":"useBusiness.d.ts","sourceRoot":"","sources":["../../src/hooks/useBusiness.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,wBAAwB,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AAErI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,WAAW;+BAgB4B,QAAQ,WAAW,EAAE,CAAC;4BA2BzB,QAAQ,eAAe,EAAE,CAAC;yBA4B7B,QAAQ,WAAW,EAAE,CAAC;kCAdX,MAAM,KAAG,QAAQ,WAAW,GAAG,IAAI,CAAC;2CA4B3B,MAAM,KAAG,QAAQ,WAAW,CAAC;kCActC,MAAM,KAAG,QAAQ,WAAW,EAAE,CAAC;kCA6B/B,MAAM,KAAG,QAAQ,WAAW,CAAC;iCAc9B,MAAM,gBAAgB,wBAAwB,KAAG,QAAQ,WAAW,CAAC;uCAc/D,MAAM,cAAc,8BAA8B,KAAG,QAAQ,WAAW,CAAC;;CA0BtI,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC"}
1
+ {"version":3,"file":"useBusiness.d.ts","sourceRoot":"","sources":["../../src/hooks/useBusiness.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,wBAAwB,EAAE,8BAA8B,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE3J;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,WAAW;+BAgB4B,QAAQ,qBAAqB,WAAW,CAAC,CAAC;4BA2B7C,QAAQ,qBAAqB,eAAe,CAAC,CAAC;yBA4BjD,QAAQ,qBAAqB,WAAW,CAAC,CAAC;kCAd/B,MAAM,KAAG,QAAQ,WAAW,GAAG,IAAI,CAAC;2CA4B3B,MAAM,KAAG,QAAQ,WAAW,CAAC;kCActC,MAAM,KAAG,QAAQ,qBAAqB,WAAW,CAAC,CAAC;kCA6BnD,MAAM,KAAG,QAAQ,WAAW,CAAC;iCAc9B,MAAM,gBAAgB,wBAAwB,KAAG,QAAQ,WAAW,CAAC;uCAc/D,MAAM,cAAc,8BAA8B,KAAG,QAAQ,WAAW,CAAC;;CA0BtI,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC"}
@@ -1,14 +1,14 @@
1
- import type { CampaignClaimRequestDTO, CampaignDTO, CampaignClaimDTO, CampaignTriggerDTO } from '@explorins/pers-shared';
1
+ import type { CampaignClaimRequestDTO, CampaignDTO, CampaignClaimDTO, CampaignTriggerDTO, PaginatedResponseDTO } from '@explorins/pers-shared';
2
2
  export declare const useCampaigns: () => {
3
- getActiveCampaigns: () => Promise<CampaignDTO[]>;
3
+ getActiveCampaigns: () => Promise<PaginatedResponseDTO<CampaignDTO>>;
4
4
  getCampaignById: (campaignId: string) => Promise<CampaignDTO | null>;
5
5
  claimCampaign: (request: CampaignClaimRequestDTO) => Promise<CampaignClaimDTO | null>;
6
- getUserClaims: () => Promise<CampaignClaimDTO[]>;
7
- getCampaignTriggers: () => Promise<CampaignTriggerDTO[]>;
8
- getAllCampaigns: (active?: boolean) => Promise<CampaignDTO[]>;
9
- getCampaignClaims: () => Promise<CampaignClaimDTO[]>;
10
- getCampaignClaimsByUserId: (userId: string) => Promise<CampaignClaimDTO[]>;
11
- getCampaignClaimsByBusinessId: (businessId: string) => Promise<CampaignClaimDTO[]>;
6
+ getUserClaims: () => Promise<PaginatedResponseDTO<CampaignClaimDTO>>;
7
+ getCampaignTriggers: () => Promise<PaginatedResponseDTO<CampaignTriggerDTO>>;
8
+ getAllCampaigns: (active?: boolean) => Promise<PaginatedResponseDTO<CampaignDTO>>;
9
+ getCampaignClaims: () => Promise<PaginatedResponseDTO<CampaignClaimDTO>>;
10
+ getCampaignClaimsByUserId: (userId: string) => Promise<PaginatedResponseDTO<CampaignClaimDTO>>;
11
+ getCampaignClaimsByBusinessId: (businessId: string) => Promise<PaginatedResponseDTO<CampaignClaimDTO>>;
12
12
  isAvailable: boolean;
13
13
  };
14
14
  export type CampaignHook = ReturnType<typeof useCampaigns>;
@@ -1 +1 @@
1
- {"version":3,"file":"useCampaigns.d.ts","sourceRoot":"","sources":["../../src/hooks/useCampaigns.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAInB,MAAM,wBAAwB,CAAC;AAEhC,eAAO,MAAM,YAAY;8BAG0B,QAAQ,WAAW,EAAE,CAAC;kCAchB,MAAM,KAAG,QAAQ,WAAW,GAAG,IAAI,CAAC;6BAczC,uBAAuB,KAAG,QAAQ,gBAAgB,GAAG,IAAI,CAAC;yBAiBhE,QAAQ,gBAAgB,EAAE,CAAC;+BAkBrB,QAAQ,kBAAkB,EAAE,CAAC;+BAe3B,OAAO,KAAG,QAAQ,WAAW,EAAE,CAAC;6BAcpC,QAAQ,gBAAgB,EAAE,CAAC;wCAcd,MAAM,KAAG,QAAQ,gBAAgB,EAAE,CAAC;gDAc5B,MAAM,KAAG,QAAQ,gBAAgB,EAAE,CAAC;;CA0B1G,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC"}
1
+ {"version":3,"file":"useCampaigns.d.ts","sourceRoot":"","sources":["../../src/hooks/useCampaigns.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAIlB,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAEhC,eAAO,MAAM,YAAY;8BAG0B,QAAQ,qBAAqB,WAAW,CAAC,CAAC;kCAcpC,MAAM,KAAG,QAAQ,WAAW,GAAG,IAAI,CAAC;6BAczC,uBAAuB,KAAG,QAAQ,gBAAgB,GAAG,IAAI,CAAC;yBAiBhE,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;+BAkBzC,QAAQ,qBAAqB,kBAAkB,CAAC,CAAC;+BAe/C,OAAO,KAAG,QAAQ,qBAAqB,WAAW,CAAC,CAAC;6BAcxD,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;wCAclC,MAAM,KAAG,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;gDAchD,MAAM,KAAG,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;;CA0B9H,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC"}
@@ -7,7 +7,7 @@ export const useCampaigns = () => {
7
7
  throw new Error('SDK not initialized. Call initialize() first.');
8
8
  }
9
9
  try {
10
- const result = await sdk.campaigns.getActiveCampaigns();
10
+ const result = await sdk.campaigns.getCampaigns({ active: true });
11
11
  return result;
12
12
  }
13
13
  catch (error) {
@@ -50,7 +50,7 @@ export const useCampaigns = () => {
50
50
  }
51
51
  if (!isAuthenticated) {
52
52
  console.warn('SDK not authenticated. getUserClaims requires authentication.');
53
- return [];
53
+ return { data: [], pagination: { page: 1, limit: 0, total: 0, pages: 0, hasNext: false, hasPrev: false } };
54
54
  }
55
55
  try {
56
56
  const result = await sdk.campaigns.getUserClaims();
@@ -80,7 +80,7 @@ export const useCampaigns = () => {
80
80
  throw new Error('SDK not initialized. Call initialize() first.');
81
81
  }
82
82
  try {
83
- const result = await sdk.campaigns.getAllCampaigns(active);
83
+ const result = await sdk.campaigns.getCampaigns({ active });
84
84
  return result;
85
85
  }
86
86
  catch (error) {
@@ -1,4 +1,4 @@
1
- import type { DonationTypeDTO } from '@explorins/pers-shared';
1
+ import type { DonationTypeDTO, PaginatedResponseDTO } from '@explorins/pers-shared';
2
2
  /**
3
3
  * React hook for donation operations in the PERS SDK
4
4
  *
@@ -26,7 +26,7 @@ import type { DonationTypeDTO } from '@explorins/pers-shared';
26
26
  * ```
27
27
  */
28
28
  export declare const useDonations: () => {
29
- getDonationTypes: () => Promise<DonationTypeDTO[]>;
29
+ getDonationTypes: () => Promise<PaginatedResponseDTO<DonationTypeDTO>>;
30
30
  isAvailable: boolean;
31
31
  };
32
32
  export type DonationHook = ReturnType<typeof useDonations>;
@@ -1 +1 @@
1
- {"version":3,"file":"useDonations.d.ts","sourceRoot":"","sources":["../../src/hooks/useDonations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,YAAY;4BAgBwB,QAAQ,eAAe,EAAE,CAAC;;CAkB1E,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC"}
1
+ {"version":3,"file":"useDonations.d.ts","sourceRoot":"","sources":["../../src/hooks/useDonations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,YAAY;4BAgBwB,QAAQ,qBAAqB,eAAe,CAAC,CAAC;;CAkB9F,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC"}
@@ -0,0 +1,178 @@
1
+ import type { PersEvent, EventHandler, EventFilter, Unsubscribe } from '@explorins/pers-sdk/core';
2
+ export type { PersEvent, EventHandler, EventFilter, Unsubscribe };
3
+ /**
4
+ * Return interface for the useEvents hook
5
+ *
6
+ * Provides event subscription capabilities for the PERS SDK event system.
7
+ * Use this to display notifications, update UI, or trigger side effects.
8
+ *
9
+ * @interface EventsHook
10
+ * @property {Function} subscribe - Subscribe to SDK events with optional filtering
11
+ * @property {Function} once - Subscribe to a single event (auto-unsubscribes)
12
+ * @property {Function} clear - Clear all subscriptions
13
+ * @property {boolean} isAvailable - Whether the event system is available
14
+ * @property {number} subscriberCount - Current number of active subscribers
15
+ */
16
+ export interface EventsHook {
17
+ subscribe: (handler: EventHandler, filter?: EventFilter) => Unsubscribe;
18
+ once: (handler: EventHandler, filter?: EventFilter) => Unsubscribe;
19
+ clear: () => void;
20
+ isAvailable: boolean;
21
+ subscriberCount: number;
22
+ }
23
+ /**
24
+ * React Native hook for PERS SDK event system
25
+ *
26
+ * This hook provides access to the platform-agnostic event system for subscribing to
27
+ * transaction, authentication, campaign, and system events. All events include a
28
+ * `userMessage` field ready for display to end users.
29
+ *
30
+ * **Event Domains:**
31
+ * - `auth` - Authentication events (login, logout, token refresh)
32
+ * - `user` - User profile events (update, create)
33
+ * - `transaction` - Transaction events (created, completed, failed)
34
+ * - `campaign` - Campaign events (claimed, activated)
35
+ * - `redemption` - Redemption events (redeemed, expired)
36
+ * - `business` - Business events (created, updated, membership)
37
+ * - `api` - API error events (network, validation, server errors)
38
+ *
39
+ * **Notification Levels:**
40
+ * - `success` - Operation completed successfully
41
+ * - `error` - Operation failed
42
+ * - `warning` - Operation completed with warnings
43
+ * - `info` - Informational event
44
+ *
45
+ * **Cleanup:**
46
+ * All subscriptions created through this hook are automatically cleaned up when
47
+ * the component unmounts, preventing memory leaks and stale event handlers.
48
+ *
49
+ * @returns {EventsHook} Hook interface with event subscription methods
50
+ *
51
+ * @example
52
+ * **Basic Usage - Show All Notifications**
53
+ * ```typescript
54
+ * import { useEvents } from '@explorins/pers-sdk-react-native';
55
+ *
56
+ * function NotificationComponent() {
57
+ * const { subscribe, isAvailable } = useEvents();
58
+ *
59
+ * useEffect(() => {
60
+ * if (!isAvailable) return;
61
+ *
62
+ * const unsubscribe = subscribe((event) => {
63
+ * // userMessage is always present and UI-ready
64
+ * showNotification(event.userMessage, event.level);
65
+ * });
66
+ *
67
+ * return () => unsubscribe();
68
+ * }, [subscribe, isAvailable]);
69
+ *
70
+ * return <View />;
71
+ * }
72
+ * ```
73
+ *
74
+ * @example
75
+ * **Filter by Domain and Level**
76
+ * ```typescript
77
+ * function TransactionListener() {
78
+ * const { subscribe, isAvailable } = useEvents();
79
+ *
80
+ * useEffect(() => {
81
+ * if (!isAvailable) return;
82
+ *
83
+ * // Only listen to successful transactions
84
+ * const unsubscribe = subscribe(
85
+ * (event) => {
86
+ * if (event.level === 'success') {
87
+ * playSuccessSound();
88
+ * showConfetti();
89
+ * }
90
+ * },
91
+ * { domain: 'transaction' } // Filter
92
+ * );
93
+ *
94
+ * return () => unsubscribe();
95
+ * }, [subscribe, isAvailable]);
96
+ * }
97
+ * ```
98
+ *
99
+ * @example
100
+ * **Filter Errors for Logging**
101
+ * ```typescript
102
+ * function ErrorLogger() {
103
+ * const { subscribe, isAvailable } = useEvents();
104
+ *
105
+ * useEffect(() => {
106
+ * if (!isAvailable) return;
107
+ *
108
+ * const unsubscribe = subscribe(
109
+ * (event) => {
110
+ * // Log errors to crash reporting
111
+ * logToSentry({
112
+ * message: event.userMessage,
113
+ * domain: event.domain,
114
+ * type: event.type,
115
+ * });
116
+ * },
117
+ * { level: 'error' } // Only errors
118
+ * );
119
+ *
120
+ * return () => unsubscribe();
121
+ * }, [subscribe, isAvailable]);
122
+ * }
123
+ * ```
124
+ *
125
+ * @example
126
+ * **One-time Event**
127
+ * ```typescript
128
+ * function FirstTransactionHandler() {
129
+ * const { once, isAvailable } = useEvents();
130
+ *
131
+ * useEffect(() => {
132
+ * if (!isAvailable) return;
133
+ *
134
+ * // Auto-unsubscribe after first transaction event
135
+ * const unsubscribe = once(
136
+ * (event) => {
137
+ * console.log('First transaction event:', event.type);
138
+ * showOnboardingComplete();
139
+ * },
140
+ * { domain: 'transaction', level: 'success' }
141
+ * );
142
+ *
143
+ * return () => unsubscribe();
144
+ * }, [once, isAvailable]);
145
+ * }
146
+ * ```
147
+ *
148
+ * @example
149
+ * **Combined Domain and Level Filter**
150
+ * ```typescript
151
+ * function AuthErrorHandler() {
152
+ * const { subscribe, isAvailable } = useEvents();
153
+ *
154
+ * useEffect(() => {
155
+ * if (!isAvailable) return;
156
+ *
157
+ * const unsubscribe = subscribe(
158
+ * (event) => {
159
+ * Alert.alert('Authentication Error', event.userMessage);
160
+ * navigation.navigate('Login');
161
+ * },
162
+ * { domain: 'auth', level: 'error' }
163
+ * );
164
+ *
165
+ * return () => unsubscribe();
166
+ * }, [subscribe, isAvailable]);
167
+ * }
168
+ * ```
169
+ *
170
+ * @see {@link PersEvent} for event structure
171
+ * @see {@link EventFilter} for filtering options
172
+ * @see {@link EventHandler} for handler function type
173
+ *
174
+ * @since 1.6.49
175
+ */
176
+ export declare const useEvents: () => EventsHook;
177
+ export type EventsHook_ = ReturnType<typeof useEvents>;
178
+ //# sourceMappingURL=useEvents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEvents.d.ts","sourceRoot":"","sources":["../../src/hooks/useEvents.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AAElE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,WAAW,CAAC;IACxE,IAAI,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,WAAW,CAAC;IACnE,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwJG;AACH,eAAO,MAAM,SAAS,QAAO,UA2K5B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC"}