@explorins/pers-sdk-react-native 2.1.3 → 2.1.6

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 +7 -7
  2. package/dist/hooks/index.d.ts +6 -0
  3. package/dist/hooks/index.d.ts.map +1 -1
  4. package/dist/hooks/index.js +1 -0
  5. package/dist/hooks/useAnalytics.d.ts +37 -14
  6. package/dist/hooks/useAnalytics.d.ts.map +1 -1
  7. package/dist/hooks/useAnalytics.js +239 -19
  8. package/dist/hooks/useCampaigns.d.ts +14 -6
  9. package/dist/hooks/useCampaigns.d.ts.map +1 -1
  10. package/dist/hooks/useCampaigns.js +144 -10
  11. package/dist/hooks/useEvents.d.ts +17 -5
  12. package/dist/hooks/useEvents.d.ts.map +1 -1
  13. package/dist/hooks/useEvents.js +17 -5
  14. package/dist/hooks/useRedemptions.d.ts +5 -2
  15. package/dist/hooks/useRedemptions.d.ts.map +1 -1
  16. package/dist/hooks/useRedemptions.js +53 -2
  17. package/dist/hooks/useTokenBalances.d.ts +24 -0
  18. package/dist/hooks/useTokenBalances.d.ts.map +1 -1
  19. package/dist/hooks/useTokenBalances.js +42 -2
  20. package/dist/hooks/useTransactions.d.ts +8 -5
  21. package/dist/hooks/useTransactions.d.ts.map +1 -1
  22. package/dist/hooks/useTransactions.js +70 -27
  23. package/dist/hooks/useTriggerSources.d.ts +76 -0
  24. package/dist/hooks/useTriggerSources.d.ts.map +1 -0
  25. package/dist/hooks/useTriggerSources.js +272 -0
  26. package/dist/hooks/useUsers.d.ts +5 -4
  27. package/dist/hooks/useUsers.d.ts.map +1 -1
  28. package/dist/hooks/useUsers.js +47 -8
  29. package/dist/hooks/useWeb3.d.ts +6 -5
  30. package/dist/hooks/useWeb3.d.ts.map +1 -1
  31. package/dist/hooks/useWeb3.js +23 -10
  32. package/dist/index.d.ts +12 -3
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +5500 -893
  35. package/dist/index.js.map +1 -1
  36. package/dist/providers/PersSDKProvider.d.ts +38 -0
  37. package/dist/providers/PersSDKProvider.d.ts.map +1 -1
  38. package/dist/providers/PersSDKProvider.js +29 -1
  39. package/package.json +3 -2
  40. package/src/hooks/index.ts +17 -1
  41. package/src/hooks/useAnalytics.ts +268 -21
  42. package/src/hooks/useCampaigns.ts +176 -14
  43. package/src/hooks/useEvents.ts +17 -5
  44. package/src/hooks/useRedemptions.ts +66 -3
  45. package/src/hooks/useTokenBalances.ts +60 -2
  46. package/src/hooks/useTransactions.ts +84 -29
  47. package/src/hooks/useTriggerSources.ts +301 -0
  48. package/src/hooks/useUsers.ts +51 -9
  49. package/src/hooks/useWeb3.ts +28 -13
  50. package/src/index.ts +33 -3
  51. package/src/providers/PersSDKProvider.tsx +38 -1
@@ -15,12 +15,26 @@ export const useCampaigns = () => {
15
15
  throw error;
16
16
  }
17
17
  }, [sdk, isInitialized]);
18
- const getCampaignById = useCallback(async (campaignId) => {
18
+ /**
19
+ * Get campaign by ID with optional include relations
20
+ *
21
+ * @param campaignId - The campaign ID
22
+ * @param include - Relations to include: 'triggerSources', 'businesses'
23
+ * @returns Promise resolving to campaign data
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * // Get campaign with all related data
28
+ * const campaign = await getCampaignById('campaign-123', ['triggerSources', 'businesses']);
29
+ * console.log('Trigger sources:', campaign.included?.triggerSources);
30
+ * ```
31
+ */
32
+ const getCampaignById = useCallback(async (campaignId, include) => {
19
33
  if (!isInitialized || !sdk) {
20
34
  throw new Error('SDK not initialized. Call initialize() first.');
21
35
  }
22
36
  try {
23
- const result = await sdk.campaigns.getCampaignById(campaignId);
37
+ const result = await sdk.campaigns.getCampaignById(campaignId, include);
24
38
  return result;
25
39
  }
26
40
  catch (error) {
@@ -44,7 +58,25 @@ export const useCampaigns = () => {
44
58
  throw error;
45
59
  }
46
60
  }, [sdk, isInitialized, isAuthenticated]);
47
- const getUserClaims = useCallback(async () => {
61
+ /**
62
+ * Get user's campaign claims with optional pagination and include relations
63
+ *
64
+ * @param options - Optional options including pagination and include relations
65
+ * @returns Promise resolving to paginated campaign claims
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * // Get user's claims with campaign details
70
+ * const { data: claims } = await getUserClaims({ include: ['campaign', 'business'] });
71
+ * claims.forEach(claim => {
72
+ * console.log('Campaign:', claim.included?.campaign?.title);
73
+ * });
74
+ *
75
+ * // With pagination
76
+ * const { data } = await getUserClaims({ page: 1, limit: 10, include: ['campaign'] });
77
+ * ```
78
+ */
79
+ const getUserClaims = useCallback(async (options) => {
48
80
  if (!isInitialized || !sdk) {
49
81
  throw new Error('SDK not initialized. Call initialize() first.');
50
82
  }
@@ -53,7 +85,7 @@ export const useCampaigns = () => {
53
85
  return { data: [], pagination: { page: 1, limit: 0, total: 0, pages: 0, hasNext: false, hasPrev: false } };
54
86
  }
55
87
  try {
56
- const result = await sdk.campaigns.getUserClaims();
88
+ const result = await sdk.campaigns.getUserClaims(options);
57
89
  return result;
58
90
  }
59
91
  catch (error) {
@@ -88,12 +120,28 @@ export const useCampaigns = () => {
88
120
  throw error;
89
121
  }
90
122
  }, [sdk, isInitialized]);
91
- const getCampaignClaims = useCallback(async () => {
123
+ /**
124
+ * Admin: Get campaign claims with optional filters and include relations
125
+ *
126
+ * @param filters - Optional filters for campaign, user, or business
127
+ * @param include - Relations to include: 'campaign', 'user', 'business'
128
+ * @returns Promise resolving to paginated campaign claims
129
+ *
130
+ * @example
131
+ * ```typescript
132
+ * // Get all claims with user details
133
+ * const { data: claims } = await getCampaignClaims({}, ['user']);
134
+ *
135
+ * // Get claims for a specific campaign
136
+ * const { data } = await getCampaignClaims({ campaignId: 'campaign-123' }, ['user', 'business']);
137
+ * ```
138
+ */
139
+ const getCampaignClaims = useCallback(async (filters, include) => {
92
140
  if (!isInitialized || !sdk) {
93
141
  throw new Error('SDK not initialized. Call initialize() first.');
94
142
  }
95
143
  try {
96
- const result = await sdk.campaigns.getCampaignClaims();
144
+ const result = await sdk.campaigns.getCampaignClaims(filters, include);
97
145
  return result;
98
146
  }
99
147
  catch (error) {
@@ -101,12 +149,19 @@ export const useCampaigns = () => {
101
149
  throw error;
102
150
  }
103
151
  }, [sdk, isInitialized]);
104
- const getCampaignClaimsByUserId = useCallback(async (userId) => {
152
+ /**
153
+ * Admin: Get campaign claims by user ID with optional include relations
154
+ *
155
+ * @param userId - The user ID
156
+ * @param include - Relations to include: 'campaign', 'user', 'business'
157
+ * @returns Promise resolving to paginated campaign claims
158
+ */
159
+ const getCampaignClaimsByUserId = useCallback(async (userId, include) => {
105
160
  if (!isInitialized || !sdk) {
106
161
  throw new Error('SDK not initialized. Call initialize() first.');
107
162
  }
108
163
  try {
109
- const result = await sdk.campaigns.getCampaignClaimsByUserId(userId);
164
+ const result = await sdk.campaigns.getCampaignClaimsByUserId(userId, undefined, include);
110
165
  return result;
111
166
  }
112
167
  catch (error) {
@@ -114,12 +169,19 @@ export const useCampaigns = () => {
114
169
  throw error;
115
170
  }
116
171
  }, [sdk, isInitialized]);
117
- const getCampaignClaimsByBusinessId = useCallback(async (businessId) => {
172
+ /**
173
+ * Admin: Get campaign claims by business ID with optional include relations
174
+ *
175
+ * @param businessId - The business ID
176
+ * @param include - Relations to include: 'campaign', 'user', 'business'
177
+ * @returns Promise resolving to paginated campaign claims
178
+ */
179
+ const getCampaignClaimsByBusinessId = useCallback(async (businessId, include) => {
118
180
  if (!isInitialized || !sdk) {
119
181
  throw new Error('SDK not initialized. Call initialize() first.');
120
182
  }
121
183
  try {
122
- const result = await sdk.campaigns.getCampaignClaimsByBusinessId(businessId);
184
+ const result = await sdk.campaigns.getCampaignClaimsByBusinessId(businessId, undefined, include);
123
185
  return result;
124
186
  }
125
187
  catch (error) {
@@ -127,6 +189,76 @@ export const useCampaigns = () => {
127
189
  throw error;
128
190
  }
129
191
  }, [sdk, isInitialized]);
192
+ // ==========================================
193
+ // TRIGGER SOURCE ASSIGNMENT (Admin)
194
+ // Note: TriggerSource CRUD is in useTriggerSources hook
195
+ // ==========================================
196
+ /**
197
+ * Admin: Assign a trigger source to a campaign
198
+ *
199
+ * Associates a trigger source (QR code, NFC tag, etc.) with a campaign.
200
+ * A campaign can have multiple trigger sources.
201
+ *
202
+ * Note: To create/update/delete trigger sources, use `useTriggerSources` hook.
203
+ *
204
+ * @param campaignId - Campaign UUID
205
+ * @param triggerSourceId - Trigger source UUID
206
+ * @returns Promise resolving to updated campaign
207
+ *
208
+ * @example
209
+ * ```typescript
210
+ * const { create } = useTriggerSources();
211
+ * const { assignTriggerSource } = useCampaigns();
212
+ *
213
+ * // Create trigger source first
214
+ * const source = await create({ type: 'QR_CODE', name: 'Store QR' });
215
+ *
216
+ * // Then assign to campaign
217
+ * const updated = await assignTriggerSource('campaign-123', source.id);
218
+ * ```
219
+ */
220
+ const assignTriggerSource = useCallback(async (campaignId, triggerSourceId) => {
221
+ if (!isInitialized || !sdk) {
222
+ throw new Error('SDK not initialized. Call initialize() first.');
223
+ }
224
+ if (!isAuthenticated) {
225
+ throw new Error('SDK not authenticated. assignTriggerSource requires admin authentication.');
226
+ }
227
+ try {
228
+ const result = await sdk.campaigns.assignTriggerSource(campaignId, triggerSourceId);
229
+ return result;
230
+ }
231
+ catch (error) {
232
+ console.error('Failed to assign trigger source:', error);
233
+ throw error;
234
+ }
235
+ }, [sdk, isInitialized, isAuthenticated]);
236
+ /**
237
+ * Admin: Remove a trigger source from a campaign
238
+ *
239
+ * Removes the association between a trigger source and a campaign.
240
+ * The trigger source itself is not deleted.
241
+ *
242
+ * @param campaignId - Campaign UUID
243
+ * @param triggerSourceId - Trigger source UUID
244
+ * @returns Promise resolving to updated campaign
245
+ */
246
+ const removeTriggerSource = useCallback(async (campaignId, triggerSourceId) => {
247
+ if (!isInitialized || !sdk) {
248
+ throw new Error('SDK not initialized. Call initialize() first.');
249
+ }
250
+ if (!isAuthenticated) {
251
+ throw new Error('SDK not authenticated. removeTriggerSource requires admin authentication.');
252
+ }
253
+ try {
254
+ const result = await sdk.campaigns.removeTriggerSource(campaignId, triggerSourceId);
255
+ return result;
256
+ }
257
+ catch (error) {
258
+ console.error('Failed to remove trigger source:', error);
259
+ throw error;
260
+ }
261
+ }, [sdk, isInitialized, isAuthenticated]);
130
262
  return {
131
263
  getActiveCampaigns,
132
264
  getCampaignById,
@@ -137,6 +269,8 @@ export const useCampaigns = () => {
137
269
  getCampaignClaims,
138
270
  getCampaignClaimsByUserId,
139
271
  getCampaignClaimsByBusinessId,
272
+ assignTriggerSource,
273
+ removeTriggerSource,
140
274
  isAvailable: isInitialized && !!sdk?.campaigns,
141
275
  };
142
276
  };
@@ -24,23 +24,35 @@ export interface EventsHook {
24
24
  * React Native hook for PERS SDK event system
25
25
  *
26
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.
27
+ * transaction, authentication, campaign, blockchain, and system events. All events
28
+ * include a `userMessage` field ready for display to end users.
29
29
  *
30
30
  * **Event Domains:**
31
31
  * - `auth` - Authentication events (login, logout, token refresh)
32
32
  * - `user` - User profile events (update, create)
33
- * - `transaction` - Transaction events (created, completed, failed)
33
+ * - `transaction` - Transaction events (created, submitted, confirmed)
34
34
  * - `campaign` - Campaign events (claimed, activated)
35
35
  * - `redemption` - Redemption events (redeemed, expired)
36
36
  * - `business` - Business events (created, updated, membership)
37
+ * - `wallet` - Real-time blockchain events (Transfer, Approval, etc.) - Auto-enabled on auth
37
38
  * - `api` - API error events (network, validation, server errors)
38
39
  *
40
+ * **Blockchain Events (Wallet Domain):**
41
+ * When `sdk.connectWalletEvents()` is called (or auto-enabled via `captureWalletEvents: true`),
42
+ * real-time blockchain events are automatically routed through the same event system:
43
+ * ```typescript
44
+ * const { subscribe } = useEvents();
45
+ *
46
+ * subscribe((event) => {
47
+ * if (event.domain === 'wallet') {
48
+ * console.log('Blockchain event:', event.type); // wallet_transfer, wallet_approval, etc.
49
+ * }
50
+ * });
51
+ * ```
52
+ *
39
53
  * **Notification Levels:**
40
54
  * - `success` - Operation completed successfully
41
55
  * - `error` - Operation failed
42
- * - `warning` - Operation completed with warnings
43
- * - `info` - Informational event
44
56
  *
45
57
  * **Cleanup:**
46
58
  * All subscriptions created through this hook are automatically cleaned up when
@@ -1 +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"}
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoKG;AACH,eAAO,MAAM,SAAS,QAAO,UA2K5B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC"}
@@ -4,23 +4,35 @@ import { usePersSDK } from '../providers/PersSDKProvider';
4
4
  * React Native hook for PERS SDK event system
5
5
  *
6
6
  * This hook provides access to the platform-agnostic event system for subscribing to
7
- * transaction, authentication, campaign, and system events. All events include a
8
- * `userMessage` field ready for display to end users.
7
+ * transaction, authentication, campaign, blockchain, and system events. All events
8
+ * include a `userMessage` field ready for display to end users.
9
9
  *
10
10
  * **Event Domains:**
11
11
  * - `auth` - Authentication events (login, logout, token refresh)
12
12
  * - `user` - User profile events (update, create)
13
- * - `transaction` - Transaction events (created, completed, failed)
13
+ * - `transaction` - Transaction events (created, submitted, confirmed)
14
14
  * - `campaign` - Campaign events (claimed, activated)
15
15
  * - `redemption` - Redemption events (redeemed, expired)
16
16
  * - `business` - Business events (created, updated, membership)
17
+ * - `wallet` - Real-time blockchain events (Transfer, Approval, etc.) - Auto-enabled on auth
17
18
  * - `api` - API error events (network, validation, server errors)
18
19
  *
20
+ * **Blockchain Events (Wallet Domain):**
21
+ * When `sdk.connectWalletEvents()` is called (or auto-enabled via `captureWalletEvents: true`),
22
+ * real-time blockchain events are automatically routed through the same event system:
23
+ * ```typescript
24
+ * const { subscribe } = useEvents();
25
+ *
26
+ * subscribe((event) => {
27
+ * if (event.domain === 'wallet') {
28
+ * console.log('Blockchain event:', event.type); // wallet_transfer, wallet_approval, etc.
29
+ * }
30
+ * });
31
+ * ```
32
+ *
19
33
  * **Notification Levels:**
20
34
  * - `success` - Operation completed successfully
21
35
  * - `error` - Operation failed
22
- * - `warning` - Operation completed with warnings
23
- * - `info` - Informational event
24
36
  *
25
37
  * **Cleanup:**
26
38
  * All subscriptions created through this hook are automatically cleaned up when
@@ -1,12 +1,15 @@
1
1
  import { OnStatusUpdateFn } from './useTransactionSigner';
2
- import type { RedemptionCreateRequestDTO, RedemptionDTO, RedemptionRedeemDTO, RedemptionRedeemRequestResponseDTO, RedemptionTypeDTO, PaginatedResponseDTO } from '@explorins/pers-shared';
2
+ import type { RedemptionCreateRequestDTO, RedemptionDTO, RedemptionRedeemDTO, RedemptionRedeemRequestResponseDTO, RedemptionTypeDTO, PaginatedResponseDTO, RedemptionRedeemIncludeRelation } from '@explorins/pers-shared';
3
+ import type { RedemptionRedeemFilters } from '@explorins/pers-sdk/redemption';
4
+ export type { RedemptionRedeemFilters } from '@explorins/pers-sdk/redemption';
3
5
  export declare const useRedemptions: () => {
4
6
  getRedemptions: (options?: {
5
7
  active?: boolean;
6
8
  }) => Promise<PaginatedResponseDTO<RedemptionDTO>>;
7
- getUserRedemptions: () => Promise<PaginatedResponseDTO<RedemptionRedeemDTO>>;
9
+ getUserRedemptions: (include?: RedemptionRedeemIncludeRelation[]) => Promise<PaginatedResponseDTO<RedemptionRedeemDTO>>;
8
10
  redeem: (redemptionId: string, onStatusUpdate?: OnStatusUpdateFn) => Promise<RedemptionRedeemRequestResponseDTO>;
9
11
  getRedemptionTypes: () => Promise<PaginatedResponseDTO<RedemptionTypeDTO>>;
12
+ getRedemptionRedeems: (filters?: RedemptionRedeemFilters, include?: RedemptionRedeemIncludeRelation[]) => Promise<PaginatedResponseDTO<RedemptionRedeemDTO>>;
10
13
  createRedemption: (redemptionData: RedemptionCreateRequestDTO) => Promise<RedemptionDTO>;
11
14
  updateRedemption: (redemptionId: string, redemptionData: RedemptionCreateRequestDTO) => Promise<RedemptionDTO>;
12
15
  toggleRedemptionStatus: (redemptionId: string) => Promise<RedemptionDTO>;
@@ -1 +1 @@
1
- {"version":3,"file":"useRedemptions.d.ts","sourceRoot":"","sources":["../../src/hooks/useRedemptions.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0C,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAClG,OAAO,KAAK,EACV,0BAA0B,EAC1B,aAAa,EACb,mBAAmB,EACnB,kCAAkC,EAClC,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAEhC,eAAO,MAAM,cAAc;+BAY2B;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAG,QAAQ,qBAAqB,aAAa,CAAC,CAAC;8BActE,QAAQ,qBAAqB,mBAAmB,CAAC,CAAC;2BAkBnD,MAAM,mBAAmB,gBAAgB,KAAG,QAAQ,kCAAkC,CAAC;8BA4DtF,QAAQ,qBAAqB,iBAAiB,CAAC,CAAC;uCAdrC,0BAA0B,KAAG,QAAQ,aAAa,CAAC;qCA4BrD,MAAM,kBAAkB,0BAA0B,KAAG,QAAQ,aAAa,CAAC;2CAcrE,MAAM,KAAG,QAAQ,aAAa,CAAC;;;;CA2BhG,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC"}
1
+ {"version":3,"file":"useRedemptions.d.ts","sourceRoot":"","sources":["../../src/hooks/useRedemptions.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0C,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAClG,OAAO,KAAK,EACV,0BAA0B,EAC1B,aAAa,EACb,mBAAmB,EACnB,kCAAkC,EAClC,iBAAiB,EACjB,oBAAoB,EACpB,+BAA+B,EAChC,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAG9E,YAAY,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAE9E,eAAO,MAAM,cAAc;+BAY2B;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAG,QAAQ,qBAAqB,aAAa,CAAC,CAAC;mCA+B3G,+BAA+B,EAAE,KAC1C,QAAQ,qBAAqB,mBAAmB,CAAC,CAAC;2BAkBL,MAAM,mBAAmB,gBAAgB,KAAG,QAAQ,kCAAkC,CAAC;8BAmGtF,QAAQ,qBAAqB,iBAAiB,CAAC,CAAC;qCA9BrF,uBAAuB,YACvB,+BAA+B,EAAE,KAC1C,QAAQ,qBAAqB,mBAAmB,CAAC,CAAC;uCAcO,0BAA0B,KAAG,QAAQ,aAAa,CAAC;qCA4BrD,MAAM,kBAAkB,0BAA0B,KAAG,QAAQ,aAAa,CAAC;2CAcrE,MAAM,KAAG,QAAQ,aAAa,CAAC;;;;CA4BhG,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC"}
@@ -25,7 +25,23 @@ export const useRedemptions = () => {
25
25
  throw error;
26
26
  }
27
27
  }, [sdk, isInitialized]);
28
- const getUserRedemptions = useCallback(async () => {
28
+ /**
29
+ * Get user's redemption history with optional include relations
30
+ *
31
+ * @param include - Relations to include: 'redemption', 'user', 'business'
32
+ * @returns Promise resolving to paginated redemption history
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * // Get user redemptions with full redemption details
37
+ * const { data: redeems } = await getUserRedemptions(['redemption', 'business']);
38
+ * redeems.forEach(redeem => {
39
+ * console.log('Redemption:', redeem.included?.redemption?.title);
40
+ * console.log('Business:', redeem.included?.business?.displayName);
41
+ * });
42
+ * ```
43
+ */
44
+ const getUserRedemptions = useCallback(async (include) => {
29
45
  if (!isInitialized || !sdk) {
30
46
  throw new Error('SDK not initialized. Call initialize() first.');
31
47
  }
@@ -34,7 +50,7 @@ export const useRedemptions = () => {
34
50
  return { data: [], pagination: { page: 1, limit: 0, total: 0, pages: 0, hasNext: false, hasPrev: false } };
35
51
  }
36
52
  try {
37
- const result = await sdk.redemptions.getUserRedemptions();
53
+ const result = await sdk.redemptions.getUserRedemptions(undefined, include);
38
54
  return result;
39
55
  }
40
56
  catch (error) {
@@ -88,6 +104,40 @@ export const useRedemptions = () => {
88
104
  }
89
105
  }, [sdk, isInitialized, isAuthenticated, signAndSubmitTransactionWithJWT, isSignerAvailable]);
90
106
  // Admin methods
107
+ /**
108
+ * Admin: Get all redemption redeems with filters and include relations
109
+ *
110
+ * Retrieves all redemption redeems across the platform with filtering.
111
+ *
112
+ * @param filters - Optional filters for user, redemption, and pagination
113
+ * @param include - Relations to include: 'redemption', 'user', 'business'
114
+ * @returns Promise resolving to paginated redemption redeems
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * // Get all redeems with user details
119
+ * const { data: redeems } = await getRedemptionRedeems({}, ['user', 'redemption']);
120
+ *
121
+ * // Filter by specific user
122
+ * const { data: userRedeems } = await getRedemptionRedeems(
123
+ * { userId: 'user-123' },
124
+ * ['redemption']
125
+ * );
126
+ * ```
127
+ */
128
+ const getRedemptionRedeems = useCallback(async (filters, include) => {
129
+ if (!isInitialized || !sdk) {
130
+ throw new Error('SDK not initialized. Call initialize() first.');
131
+ }
132
+ try {
133
+ const result = await sdk.redemptions.getRedemptionRedeems(filters, include);
134
+ return result;
135
+ }
136
+ catch (error) {
137
+ console.error('Failed to fetch redemption redeems:', error);
138
+ throw error;
139
+ }
140
+ }, [sdk, isInitialized]);
91
141
  const createRedemption = useCallback(async (redemptionData) => {
92
142
  if (!isInitialized || !sdk) {
93
143
  throw new Error('SDK not initialized. Call initialize() first.');
@@ -145,6 +195,7 @@ export const useRedemptions = () => {
145
195
  getUserRedemptions,
146
196
  redeem,
147
197
  getRedemptionTypes,
198
+ getRedemptionRedeems,
148
199
  createRedemption,
149
200
  updateRedemption,
150
201
  toggleRedemptionStatus,
@@ -31,6 +31,18 @@ export interface UseTokenBalancesOptions {
31
31
  autoLoad?: boolean;
32
32
  /** Optional refresh interval in milliseconds (0 = disabled) */
33
33
  refreshInterval?: number;
34
+ /**
35
+ * Auto-refresh balances when wallet events are received (Transfer, Approval, etc.)
36
+ * Requires `captureWalletEvents: true` in SDK config (default)
37
+ * @default true
38
+ */
39
+ refreshOnWalletEvents?: boolean;
40
+ /**
41
+ * Debounce time for wallet event-triggered refreshes (milliseconds)
42
+ * Prevents rapid refresh calls during batch transfers
43
+ * @default 1000
44
+ */
45
+ walletEventDebounceMs?: number;
34
46
  }
35
47
  /**
36
48
  * Token balance loading hook return value
@@ -119,6 +131,18 @@ export interface UseTokenBalancesResult {
119
131
  * ```
120
132
  *
121
133
  * @example
134
+ * **With Wallet Events (Real-time):**
135
+ * ```typescript
136
+ * // Auto-refresh on Transfer, Approval, and other blockchain events
137
+ * const { tokenBalances } = useTokenBalances({
138
+ * accountAddress: walletAddress!,
139
+ * availableTokens,
140
+ * refreshOnWalletEvents: true, // Enable real-time refresh (default: true)
141
+ * walletEventDebounceMs: 1000 // Debounce rapid events (default: 1000ms)
142
+ * });
143
+ * ```
144
+ *
145
+ * @example
122
146
  * **Multi-Wallet Support:**
123
147
  * ```typescript
124
148
  * function MultiWalletBalances() {
@@ -1 +1 @@
1
- {"version":3,"file":"useTokenBalances.d.ts","sourceRoot":"","sources":["../../src/hooks/useTokenBalances.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,0BAA0B,CAAC;AAElF;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,YAAY,EAAE,YAAY,CAAC;IAC3B,8DAA8D;IAC9D,KAAK,EAAE,QAAQ,CAAC;IAChB,8EAA8E;IAC9E,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,0DAA0D;IAC1D,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,uCAAuC;IACvC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,sFAAsF;IACtF,WAAW,EAAE,OAAO,CAAC;IACrB,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsFG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,sBAAsB,CA8JzF"}
1
+ {"version":3,"file":"useTokenBalances.d.ts","sourceRoot":"","sources":["../../src/hooks/useTokenBalances.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,0BAA0B,CAAC;AAElF;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,YAAY,EAAE,YAAY,CAAC;IAC3B,8DAA8D;IAC9D,KAAK,EAAE,QAAQ,CAAC;IAChB,8EAA8E;IAC9E,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,0DAA0D;IAC1D,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,uCAAuC;IACvC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,sFAAsF;IACtF,WAAW,EAAE,OAAO,CAAC;IACrB,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,sBAAsB,CAgMzF"}
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect, useState } from 'react';
1
+ import { useCallback, useEffect, useState, useRef } from 'react';
2
2
  import { usePersSDK } from '../providers/PersSDKProvider';
3
3
  import { useWeb3 } from './useWeb3';
4
4
  import { NativeTokenTypes } from '@explorins/pers-shared';
@@ -72,6 +72,18 @@ import { NativeTokenTypes } from '@explorins/pers-shared';
72
72
  * ```
73
73
  *
74
74
  * @example
75
+ * **With Wallet Events (Real-time):**
76
+ * ```typescript
77
+ * // Auto-refresh on Transfer, Approval, and other blockchain events
78
+ * const { tokenBalances } = useTokenBalances({
79
+ * accountAddress: walletAddress!,
80
+ * availableTokens,
81
+ * refreshOnWalletEvents: true, // Enable real-time refresh (default: true)
82
+ * walletEventDebounceMs: 1000 // Debounce rapid events (default: 1000ms)
83
+ * });
84
+ * ```
85
+ *
86
+ * @example
75
87
  * **Multi-Wallet Support:**
76
88
  * ```typescript
77
89
  * function MultiWalletBalances() {
@@ -90,12 +102,14 @@ import { NativeTokenTypes } from '@explorins/pers-shared';
90
102
  * ```
91
103
  */
92
104
  export function useTokenBalances(options) {
93
- const { accountAddress, availableTokens = [], autoLoad = true, refreshInterval = 0 } = options;
105
+ const { accountAddress, availableTokens = [], autoLoad = true, refreshInterval = 0, refreshOnWalletEvents = true, walletEventDebounceMs = 1000 } = options;
94
106
  const { isAuthenticated, sdk } = usePersSDK();
95
107
  const web3 = useWeb3();
96
108
  const [tokenBalances, setTokenBalances] = useState([]);
97
109
  const [isLoading, setIsLoading] = useState(false);
98
110
  const [error, setError] = useState(null);
111
+ // Debounce ref for wallet events
112
+ const walletEventDebounceRef = useRef(null);
99
113
  // Check if the hook is available for use
100
114
  const isAvailable = web3.isAvailable && isAuthenticated && !!accountAddress;
101
115
  /**
@@ -215,6 +229,32 @@ export function useTokenBalances(options) {
215
229
  clearInterval(intervalId);
216
230
  };
217
231
  }, [sdk, refreshInterval, isAvailable, loadBalances]);
232
+ // Wallet events refresh: listen for real-time blockchain events
233
+ // Refreshes on ANY wallet domain event (Transfer, TransferSingle, etc.)
234
+ // Debouncing prevents excessive API calls during rapid events
235
+ useEffect(() => {
236
+ if (!sdk || !refreshOnWalletEvents || !isAvailable)
237
+ return;
238
+ const unsubscribe = sdk.events.subscribe((event) => {
239
+ if (event.domain === 'wallet') {
240
+ // Debounce rapid events (batch transfers, etc.)
241
+ if (walletEventDebounceRef.current) {
242
+ clearTimeout(walletEventDebounceRef.current);
243
+ }
244
+ walletEventDebounceRef.current = setTimeout(() => {
245
+ console.log(`[useTokenBalances] Wallet event (${event.type}), refreshing balances...`);
246
+ loadBalances();
247
+ walletEventDebounceRef.current = null;
248
+ }, walletEventDebounceMs);
249
+ }
250
+ }, { domains: ['wallet'] });
251
+ return () => {
252
+ unsubscribe();
253
+ if (walletEventDebounceRef.current) {
254
+ clearTimeout(walletEventDebounceRef.current);
255
+ }
256
+ };
257
+ }, [sdk, refreshOnWalletEvents, walletEventDebounceMs, isAvailable, loadBalances]);
218
258
  return {
219
259
  tokenBalances,
220
260
  isLoading,
@@ -1,5 +1,7 @@
1
1
  import { OnStatusUpdateFn } from './useTransactionSigner';
2
- import type { TransactionRequestDTO, TransactionRequestResponseDTO, TransactionDTO, TransactionRole, TransactionPaginationRequestDTO, PaginatedResponseDTO } from '@explorins/pers-shared';
2
+ import type { TransactionRequestDTO, TransactionRequestResponseDTO, TransactionDTO, TransactionPaginationRequestDTO, PaginatedResponseDTO, TransactionIncludeRelation } from '@explorins/pers-shared';
3
+ import type { TransactionQueryOptions } from '@explorins/pers-sdk/transaction';
4
+ export type { TransactionQueryOptions } from '@explorins/pers-sdk/transaction';
3
5
  /**
4
6
  * React hook for transaction operations in the PERS SDK
5
7
  *
@@ -38,10 +40,11 @@ import type { TransactionRequestDTO, TransactionRequestResponseDTO, TransactionD
38
40
  */
39
41
  export declare const useTransactions: () => {
40
42
  createTransaction: (request: TransactionRequestDTO, onStatusUpdate?: OnStatusUpdateFn) => Promise<TransactionRequestResponseDTO>;
41
- getTransactionById: (transactionId: string) => Promise<TransactionDTO | null>;
42
- getUserTransactionHistory: (role?: TransactionRole) => Promise<PaginatedResponseDTO<TransactionDTO>>;
43
- getTenantTransactions: () => Promise<PaginatedResponseDTO<TransactionDTO>>;
44
- getPaginatedTransactions: (params: TransactionPaginationRequestDTO) => Promise<any>;
43
+ getTransactionById: (transactionId: string, include?: TransactionIncludeRelation[]) => Promise<TransactionDTO | null>;
44
+ getUserTransactionHistory: (options?: TransactionQueryOptions) => Promise<PaginatedResponseDTO<TransactionDTO>>;
45
+ getPaginatedTransactions: (options: TransactionPaginationRequestDTO & {
46
+ include?: TransactionIncludeRelation[];
47
+ }) => Promise<PaginatedResponseDTO<TransactionDTO>>;
45
48
  exportTransactionsCSV: () => Promise<Blob>;
46
49
  isAvailable: boolean;
47
50
  signingStatus: import("@explorins/pers-signer").SigningStatus | null;
@@ -1 +1 @@
1
- {"version":3,"file":"useTransactions.d.ts","sourceRoot":"","sources":["../../src/hooks/useTransactions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,KAAK,EACV,qBAAqB,EACrB,6BAA6B,EAC7B,cAAc,EACd,eAAe,EACf,+BAA+B,EAC/B,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,eAAe;iCAgC4B,qBAAqB,mBAAmB,gBAAgB,KAAG,QAAQ,6BAA6B,CAAC;wCA2D1F,MAAM,KAAG,QAAQ,cAAc,GAAG,IAAI,CAAC;uCA4BxC,eAAe,KAAG,QAAQ,qBAAqB,cAAc,CAAC,CAAC;iCAevE,QAAQ,qBAAqB,cAAc,CAAC,CAAC;uCAcrC,+BAA+B,KAAG,QAAQ,GAAG,CAAC;iCActD,QAAQ,IAAI,CAAC;;;;CA0BlE,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC"}
1
+ {"version":3,"file":"useTransactions.d.ts","sourceRoot":"","sources":["../../src/hooks/useTransactions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,KAAK,EACV,qBAAqB,EACrB,6BAA6B,EAC7B,cAAc,EACd,+BAA+B,EAC/B,oBAAoB,EACpB,0BAA0B,EAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAG/E,YAAY,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,eAAe;iCAgC4B,qBAAqB,mBAAmB,gBAAgB,KAAG,QAAQ,6BAA6B,CAAC;wCAmEtI,MAAM,YACX,0BAA0B,EAAE,KACrC,QAAQ,cAAc,GAAG,IAAI,CAAC;0CAoDrB,uBAAuB,KAChC,QAAQ,qBAAqB,cAAc,CAAC,CAAC;wCA2CrC,+BAA+B,GAAG;QACzC,OAAO,CAAC,EAAE,0BAA0B,EAAE,CAAC;KACxC,KACA,QAAQ,qBAAqB,cAAc,CAAC,CAAC;iCAcI,QAAQ,IAAI,CAAC;;;;CAyBlE,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC"}