@explorins/pers-sdk-react-native 2.1.2 → 2.1.5

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 (38) 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/useRedemptions.d.ts +5 -2
  12. package/dist/hooks/useRedemptions.d.ts.map +1 -1
  13. package/dist/hooks/useRedemptions.js +53 -2
  14. package/dist/hooks/useTokenBalances.d.ts.map +1 -1
  15. package/dist/hooks/useTokenBalances.js +21 -8
  16. package/dist/hooks/useTransactions.d.ts +8 -5
  17. package/dist/hooks/useTransactions.d.ts.map +1 -1
  18. package/dist/hooks/useTransactions.js +70 -27
  19. package/dist/hooks/useTriggerSources.d.ts +76 -0
  20. package/dist/hooks/useTriggerSources.d.ts.map +1 -0
  21. package/dist/hooks/useTriggerSources.js +272 -0
  22. package/dist/index.d.ts +12 -3
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +2742 -495
  25. package/dist/index.js.map +1 -1
  26. package/dist/providers/PersSDKProvider.d.ts +1 -12
  27. package/dist/providers/PersSDKProvider.d.ts.map +1 -1
  28. package/dist/providers/PersSDKProvider.js +50 -25
  29. package/package.json +2 -2
  30. package/src/hooks/index.ts +17 -1
  31. package/src/hooks/useAnalytics.ts +268 -21
  32. package/src/hooks/useCampaigns.ts +176 -14
  33. package/src/hooks/useRedemptions.ts +66 -3
  34. package/src/hooks/useTokenBalances.ts +23 -9
  35. package/src/hooks/useTransactions.ts +84 -29
  36. package/src/hooks/useTriggerSources.ts +301 -0
  37. package/src/index.ts +33 -3
  38. package/src/providers/PersSDKProvider.tsx +58 -39
@@ -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
  };
@@ -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,
@@ -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,CAgJzF"}
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"}
@@ -91,7 +91,7 @@ import { NativeTokenTypes } from '@explorins/pers-shared';
91
91
  */
92
92
  export function useTokenBalances(options) {
93
93
  const { accountAddress, availableTokens = [], autoLoad = true, refreshInterval = 0 } = options;
94
- const { isAuthenticated } = usePersSDK();
94
+ const { isAuthenticated, sdk } = usePersSDK();
95
95
  const web3 = useWeb3();
96
96
  const [tokenBalances, setTokenBalances] = useState([]);
97
97
  const [isLoading, setIsLoading] = useState(false);
@@ -193,15 +193,28 @@ export function useTokenBalances(options) {
193
193
  loadBalances();
194
194
  }
195
195
  }, [autoLoad, isAvailable, availableTokens.length, loadBalances]);
196
- // Optional auto-refresh interval
196
+ // Event-driven refresh: listen for transaction events instead of polling
197
197
  useEffect(() => {
198
- if (refreshInterval > 0 && isAvailable && availableTokens.length > 0) {
199
- const intervalId = setInterval(() => {
198
+ if (!sdk || refreshInterval <= 0 || !isAvailable)
199
+ return;
200
+ // Subscribe to transaction domain events
201
+ const unsubscribe = sdk.events.subscribe((event) => {
202
+ if (event.domain === 'transaction' && event.type === 'transaction_completed') {
203
+ console.log('[useTokenBalances] Transaction completed, refreshing balances...');
200
204
  loadBalances();
201
- }, refreshInterval);
202
- return () => clearInterval(intervalId);
203
- }
204
- }, [refreshInterval, isAvailable, availableTokens.length, loadBalances]);
205
+ }
206
+ }, { domains: ['transaction'] });
207
+ // Also set up a fallback polling interval (much longer than before)
208
+ // This handles cases where events might be missed
209
+ const fallbackInterval = Math.max(refreshInterval, 60000); // Minimum 1 minute
210
+ const intervalId = setInterval(() => {
211
+ loadBalances();
212
+ }, fallbackInterval);
213
+ return () => {
214
+ unsubscribe();
215
+ clearInterval(intervalId);
216
+ };
217
+ }, [sdk, refreshInterval, isAvailable, loadBalances]);
205
218
  return {
206
219
  tokenBalances,
207
220
  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"}
@@ -109,25 +109,32 @@ export const useTransactions = () => {
109
109
  }
110
110
  }, [sdk, isInitialized, signAndSubmitTransactionWithJWT, isSignerAvailable]);
111
111
  /**
112
- * Retrieves a specific transaction by its ID
112
+ * Retrieves a specific transaction by its ID with optional include relations
113
113
  *
114
114
  * @param transactionId - Unique identifier of the transaction
115
+ * @param include - Optional relations to include (sender, recipient, business) for enriched entity data
115
116
  * @returns Promise resolving to transaction data or null if not found
116
117
  * @throws Error if SDK is not initialized
117
118
  *
118
119
  * @example
119
120
  * ```typescript
120
121
  * const { getTransactionById } = useTransactions();
122
+ *
123
+ * // Basic retrieval
121
124
  * const transaction = await getTransactionById('txn-123');
122
- * console.log('Transaction details:', transaction);
125
+ *
126
+ * // With enriched sender/recipient data
127
+ * const enrichedTx = await getTransactionById('txn-123', ['sender', 'recipient', 'business']);
128
+ * console.log('Sender:', enrichedTx?.included?.sender);
129
+ * console.log('Business:', enrichedTx?.included?.engagedBusiness?.displayName);
123
130
  * ```
124
131
  */
125
- const getTransactionById = useCallback(async (transactionId) => {
132
+ const getTransactionById = useCallback(async (transactionId, include) => {
126
133
  if (!isInitialized || !sdk) {
127
134
  throw new Error('SDK not initialized. Call initialize() first.');
128
135
  }
129
136
  try {
130
- const result = await sdk.transactions.getTransactionById(transactionId);
137
+ const result = await sdk.transactions.getTransactionById(transactionId, include);
131
138
  return result;
132
139
  }
133
140
  catch (error) {
@@ -136,25 +143,48 @@ export const useTransactions = () => {
136
143
  }
137
144
  }, [sdk, isInitialized]);
138
145
  /**
139
- * Retrieves transaction history for the authenticated user, filtered by role
146
+ * Retrieves transaction history for the authenticated user with comprehensive filtering
140
147
  *
141
- * @param role - Optional transaction role filter (TransactionRole.SENDER, TransactionRole.RECIPIENT)
142
- * @returns Promise resolving to array of user's transactions
148
+ * Supports filtering by role, status, type, business, token, and more.
149
+ * Optionally enrich with related entities (sender, recipient, business).
150
+ *
151
+ * @param options - Query options including filters, pagination, and include relations
152
+ * @returns Promise resolving to paginated array of user's transactions
143
153
  * @throws Error if SDK is not initialized
144
154
  *
145
155
  * @example
146
156
  * ```typescript
147
157
  * const { getUserTransactionHistory } = useTransactions();
148
- * const sentTransactions = await getUserTransactionHistory(TransactionRole.SENDER);
149
- * const allTransactions = await getUserTransactionHistory(); // No filter
158
+ *
159
+ * // Simple: Get all transactions
160
+ * const allTransactions = await getUserTransactionHistory();
161
+ *
162
+ * // Filter by role (legacy support)
163
+ * const sentTransactions = await getUserTransactionHistory({ role: 'SENDER' });
164
+ *
165
+ * // Advanced filtering with include relations
166
+ * const filtered = await getUserTransactionHistory({
167
+ * role: 'SENDER',
168
+ * status: 'COMPLETED',
169
+ * engagedBusinessId: 'business-123',
170
+ * include: ['recipient', 'business'],
171
+ * page: 1,
172
+ * limit: 20
173
+ * });
174
+ *
175
+ * // Access enriched data
176
+ * filtered.data.forEach(tx => {
177
+ * console.log('Recipient:', tx.included?.recipient);
178
+ * console.log('Business:', tx.included?.engagedBusiness?.displayName);
179
+ * });
150
180
  * ```
151
181
  */
152
- const getUserTransactionHistory = useCallback(async (role) => {
182
+ const getUserTransactionHistory = useCallback(async (options) => {
153
183
  if (!isInitialized || !sdk) {
154
184
  throw new Error('SDK not initialized. Call initialize() first.');
155
185
  }
156
186
  try {
157
- const result = await sdk.transactions.getUserTransactionHistory(role);
187
+ const result = await sdk.transactions.getUserTransactionHistory(options);
158
188
  return result;
159
189
  }
160
190
  catch (error) {
@@ -162,25 +192,39 @@ export const useTransactions = () => {
162
192
  throw error;
163
193
  }
164
194
  }, [sdk, isInitialized]);
165
- const getTenantTransactions = useCallback(async () => {
166
- if (!isInitialized || !sdk) {
167
- throw new Error('SDK not initialized. Call initialize() first.');
168
- }
169
- try {
170
- const result = await sdk.transactions.getTenantTransactions();
171
- return result;
172
- }
173
- catch (error) {
174
- console.error('Failed to fetch tenant transactions:', error);
175
- throw error;
176
- }
177
- }, [sdk, isInitialized]);
178
- const getPaginatedTransactions = useCallback(async (params) => {
195
+ /**
196
+ * Admin: Get paginated transactions with optional include relations
197
+ *
198
+ * @param params - Pagination and filtering parameters
199
+ * @param include - Optional relations to include for enriched entity data
200
+ * @returns Promise resolving to paginated transaction results
201
+ * @throws Error if SDK is not initialized
202
+ *
203
+ * @example
204
+ * ```typescript
205
+ * const { getPaginatedTransactions } = useTransactions();
206
+ *
207
+ * // Basic pagination
208
+ * const result = await getPaginatedTransactions({ page: 1, limit: 50 });
209
+ *
210
+ * // With include relations
211
+ * const enrichedResult = await getPaginatedTransactions(
212
+ * { page: 1, limit: 50, sortBy: 'createdAt', sortOrder: 'DESC' },
213
+ * include: ['sender', 'recipient', 'business']
214
+ * });
215
+ *
216
+ * enrichedResult.data.forEach(tx => {
217
+ * console.log('From:', tx.included?.sender);
218
+ * console.log('To:', tx.included?.recipient);
219
+ * });
220
+ * ```
221
+ */
222
+ const getPaginatedTransactions = useCallback(async (options) => {
179
223
  if (!isInitialized || !sdk) {
180
224
  throw new Error('SDK not initialized. Call initialize() first.');
181
225
  }
182
226
  try {
183
- const result = await sdk.transactions.getPaginatedTransactions(params);
227
+ const result = await sdk.transactions.getPaginatedTransactions(options);
184
228
  return result;
185
229
  }
186
230
  catch (error) {
@@ -205,7 +249,6 @@ export const useTransactions = () => {
205
249
  createTransaction,
206
250
  getTransactionById,
207
251
  getUserTransactionHistory,
208
- getTenantTransactions,
209
252
  getPaginatedTransactions,
210
253
  exportTransactionsCSV,
211
254
  isAvailable: isInitialized && !!sdk?.transactions,
@@ -0,0 +1,76 @@
1
+ import type { TriggerSourceDTO, TriggerSourceCreateRequestDTO, PaginatedResponseDTO } from '@explorins/pers-shared';
2
+ import type { TriggerSourceQueryOptions } from '@explorins/pers-sdk/trigger-source';
3
+ export type { TriggerSourceQueryOptions } from '@explorins/pers-sdk/trigger-source';
4
+ /**
5
+ * React hook for TriggerSource operations in the PERS SDK
6
+ *
7
+ * Manages trigger sources which are physical or digital activation points for campaigns:
8
+ * - **QR_CODE**: Scannable QR codes at physical locations
9
+ * - **NFC_TAG**: NFC tap points for contactless interactions
10
+ * - **GPS_GEOFENCE**: Location-based triggers with radius detection
11
+ * - **API_WEBHOOK**: External system integration triggers
12
+ * - **TRANSACTION**: Purchase/payment based triggers
13
+ *
14
+ * TriggerSources are standalone entities that can be created, managed, and then
15
+ * assigned to campaigns. This separation allows reuse across multiple campaigns.
16
+ *
17
+ * **Admin Only**: All create, update, and delete operations require admin authentication.
18
+ *
19
+ * @returns TriggerSource hook with CRUD operations
20
+ *
21
+ * @example Basic TriggerSource Operations
22
+ * ```typescript
23
+ * function TriggerSourceManager() {
24
+ * const {
25
+ * getAll,
26
+ * getById,
27
+ * create,
28
+ * update,
29
+ * remove
30
+ * } = useTriggerSources();
31
+ *
32
+ * // List all QR code trigger sources
33
+ * const loadQRSources = async () => {
34
+ * const { data: sources } = await getAll({ type: 'QR_CODE' });
35
+ * console.log('QR Sources:', sources);
36
+ * };
37
+ *
38
+ * // Create a new QR code for a store
39
+ * const createStoreQR = async () => {
40
+ * const source = await create({
41
+ * type: 'QR_CODE',
42
+ * name: 'Store Entrance QR',
43
+ * description: 'Scan at the entrance',
44
+ * businessId: 'business-123',
45
+ * coordsLatitude: 47.6062,
46
+ * coordsLongitude: -122.3321
47
+ * });
48
+ * console.log('Created:', source.id);
49
+ * };
50
+ * }
51
+ * ```
52
+ *
53
+ * @example GPS Geofence Trigger
54
+ * ```typescript
55
+ * const { create } = useTriggerSources();
56
+ *
57
+ * // Create a GPS geofence around a location
58
+ * const geofence = await create({
59
+ * type: 'GPS_GEOFENCE',
60
+ * name: 'Downtown Area',
61
+ * coordsLatitude: 47.6062,
62
+ * coordsLongitude: -122.3321,
63
+ * metadata: { radiusMeters: 100 }
64
+ * });
65
+ * ```
66
+ */
67
+ export declare const useTriggerSources: () => {
68
+ getAll: (options?: TriggerSourceQueryOptions) => Promise<PaginatedResponseDTO<TriggerSourceDTO>>;
69
+ getById: (triggerSourceId: string) => Promise<TriggerSourceDTO>;
70
+ create: (triggerSource: TriggerSourceCreateRequestDTO) => Promise<TriggerSourceDTO>;
71
+ update: (triggerSourceId: string, triggerSource: Partial<TriggerSourceCreateRequestDTO>) => Promise<TriggerSourceDTO>;
72
+ remove: (triggerSourceId: string) => Promise<boolean>;
73
+ isAvailable: boolean;
74
+ };
75
+ export type TriggerSourceHook = ReturnType<typeof useTriggerSources>;
76
+ //# sourceMappingURL=useTriggerSources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTriggerSources.d.ts","sourceRoot":"","sources":["../../src/hooks/useTriggerSources.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,6BAA6B,EAC7B,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAGpF,YAAY,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,eAAO,MAAM,iBAAiB;uBAiChB,yBAAyB,KAClC,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;+BAsC/B,MAAM,KACtB,QAAQ,gBAAgB,CAAC;4BA8CX,6BAA6B,KAC3C,QAAQ,gBAAgB,CAAC;8BAwCT,MAAM,iBACR,QAAQ,6BAA6B,CAAC,KACpD,QAAQ,gBAAgB,CAAC;8BAmCT,MAAM,KACtB,QAAQ,OAAO,CAAC;;CAyBpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC"}