@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
@@ -2,6 +2,15 @@ import React, { ReactNode } from 'react';
2
2
  import { PersSDK, PersConfig, DefaultAuthProvider } from '@explorins/pers-sdk/core';
3
3
  import { UserDTO, AdminDTO } from '@explorins/pers-shared';
4
4
  export type { PersConfig } from '@explorins/pers-sdk/core';
5
+ /**
6
+ * Context interface for PERS SDK React Native integration
7
+ *
8
+ * @property sdk - Main SDK instance (null until initialized)
9
+ * @property authProvider - Platform-specific auth provider
10
+ * @property isInitialized - Whether SDK has been initialized
11
+ * @property isAuthenticated - Whether user is currently authenticated
12
+ * @property user - Current user data (null if not authenticated)
13
+ */
5
14
  export interface PersSDKContext {
6
15
  sdk: PersSDK | null;
7
16
  authProvider: DefaultAuthProvider | null;
@@ -13,6 +22,35 @@ export interface PersSDKContext {
13
22
  refreshUserData: () => Promise<void>;
14
23
  restoreSession: () => Promise<UserDTO | null>;
15
24
  }
25
+ /**
26
+ * PERS SDK Provider for React Native
27
+ *
28
+ * Wraps your app to provide SDK context to all child components.
29
+ * Handles platform-specific initialization (DPoP, storage, etc.).
30
+ *
31
+ * @param config - SDK configuration (see PersConfig)
32
+ * @param config.apiProjectKey - Your PERS project key (required)
33
+ * @param config.environment - 'staging' | 'production' (default: 'staging')
34
+ * @param config.captureWalletEvents - Enable real-time blockchain events (default: true)
35
+ * @param config.dpop - DPoP configuration for enhanced security
36
+ *
37
+ * @example Basic usage
38
+ * ```tsx
39
+ * <PersSDKProvider config={{ apiProjectKey: 'my-project' }}>
40
+ * <App />
41
+ * </PersSDKProvider>
42
+ * ```
43
+ *
44
+ * @example Disable wallet events
45
+ * ```tsx
46
+ * <PersSDKProvider config={{
47
+ * apiProjectKey: 'my-project',
48
+ * captureWalletEvents: false // Disable auto-connect to blockchain events
49
+ * }}>
50
+ * <App />
51
+ * </PersSDKProvider>
52
+ * ```
53
+ */
16
54
  export declare const PersSDKProvider: React.FC<{
17
55
  children: ReactNode;
18
56
  config?: PersConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"PersSDKProvider.d.ts","sourceRoot":"","sources":["../../src/providers/PersSDKProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAuC,SAAS,EAA2C,MAAM,OAAO,CAAC;AAEvH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAIpF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAkB3D,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,MAAM,WAAW,cAAc;IAE7B,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IAGpB,YAAY,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAGzC,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;IAGhC,UAAU,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,sBAAsB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,EAAE,eAAe,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5F,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,cAAc,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAC/C;AAMD,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC;IACrC,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB,CAwOA,CAAC;AAGF,eAAO,MAAM,UAAU,QAAO,cAQ7B,CAAC"}
1
+ {"version":3,"file":"PersSDKProvider.d.ts","sourceRoot":"","sources":["../../src/providers/PersSDKProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAuC,SAAS,EAA2C,MAAM,OAAO,CAAC;AAEvH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAIpF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAkB3D,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAE7B,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IAGpB,YAAY,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAGzC,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;IAGhC,UAAU,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,sBAAsB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,EAAE,eAAe,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5F,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,cAAc,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAC/C;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC;IACrC,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB,CAwOA,CAAC;AAGF,eAAO,MAAM,UAAU,QAAO,cAQ7B,CAAC"}
@@ -7,7 +7,35 @@ import { createReactNativeAuthProvider } from './react-native-auth-provider';
7
7
  import { ReactNativeDPoPProvider } from './rn-dpop-provider';
8
8
  // Create the context
9
9
  const SDKContext = createContext(null);
10
- // Provider component
10
+ /**
11
+ * PERS SDK Provider for React Native
12
+ *
13
+ * Wraps your app to provide SDK context to all child components.
14
+ * Handles platform-specific initialization (DPoP, storage, etc.).
15
+ *
16
+ * @param config - SDK configuration (see PersConfig)
17
+ * @param config.apiProjectKey - Your PERS project key (required)
18
+ * @param config.environment - 'staging' | 'production' (default: 'staging')
19
+ * @param config.captureWalletEvents - Enable real-time blockchain events (default: true)
20
+ * @param config.dpop - DPoP configuration for enhanced security
21
+ *
22
+ * @example Basic usage
23
+ * ```tsx
24
+ * <PersSDKProvider config={{ apiProjectKey: 'my-project' }}>
25
+ * <App />
26
+ * </PersSDKProvider>
27
+ * ```
28
+ *
29
+ * @example Disable wallet events
30
+ * ```tsx
31
+ * <PersSDKProvider config={{
32
+ * apiProjectKey: 'my-project',
33
+ * captureWalletEvents: false // Disable auto-connect to blockchain events
34
+ * }}>
35
+ * <App />
36
+ * </PersSDKProvider>
37
+ * ```
38
+ */
11
39
  export const PersSDKProvider = ({ children, config }) => {
12
40
  const initializingRef = useRef(false);
13
41
  // State refs for stable functions to read current values
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@explorins/pers-sdk-react-native",
3
- "version": "2.1.3",
3
+ "version": "2.1.6",
4
4
  "description": "React Native SDK for PERS Platform - Tourism Loyalty System with Blockchain Transaction Signing and WebAuthn Authentication",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -37,7 +37,7 @@
37
37
  "author": "eXplorins",
38
38
  "license": "MIT",
39
39
  "dependencies": {
40
- "@explorins/pers-sdk": "^2.1.3",
40
+ "@explorins/pers-sdk": "^2.1.14",
41
41
  "@explorins/pers-signer": "^1.0.33",
42
42
  "buffer": "^6.0.3",
43
43
  "ethers": "^6.15.0",
@@ -155,6 +155,7 @@
155
155
  "@ethersproject/scrypt": false
156
156
  },
157
157
  "devDependencies": {
158
+ "@explorins/pers-shared": "^2.1.117",
158
159
  "@rollup/plugin-commonjs": "^25.0.7",
159
160
  "@rollup/plugin-json": "^6.1.0",
160
161
  "@rollup/plugin-node-resolve": "^15.2.3",
@@ -16,6 +16,7 @@ export { useFiles } from './useFiles';
16
16
  export { useAnalytics } from './useAnalytics';
17
17
  export { useDonations } from './useDonations';
18
18
  export { useEvents } from './useEvents';
19
+ export { useTriggerSources } from './useTriggerSources';
19
20
 
20
21
  // Re-export auth-related types for convenience
21
22
  export type { RawUserData } from './useAuth';
@@ -34,4 +35,19 @@ export type {
34
35
  TokenBalanceWithToken,
35
36
  UseTokenBalancesOptions,
36
37
  UseTokenBalancesResult
37
- } from './useTokenBalances';
38
+ } from './useTokenBalances';
39
+
40
+ // Export campaign-related types
41
+ export type { CampaignClaimFilters, CampaignHook } from './useCampaigns';
42
+
43
+ // Export redemption-related types
44
+ export type { RedemptionRedeemFilters, RedemptionHook } from './useRedemptions';
45
+
46
+ // Export transaction-related types
47
+ export type { TransactionQueryOptions, TransactionHook } from './useTransactions';
48
+
49
+ // Export trigger source-related types
50
+ export type { TriggerSourceQueryOptions, TriggerSourceHook } from './useTriggerSources';
51
+
52
+ // Export analytics-related types
53
+ export type { AnalyticsHook } from './useAnalytics';
@@ -2,35 +2,63 @@ import { useCallback } from 'react';
2
2
  import { usePersSDK } from '../providers/PersSDKProvider';
3
3
  import {
4
4
  TransactionAnalyticsRequestDTO,
5
- TransactionAnalyticsResponseDTO
5
+ TransactionAnalyticsResponseDTO,
6
+ CampaignClaimAnalyticsRequestDTO,
7
+ CampaignClaimAnalyticsResponseDTO,
8
+ UserAnalyticsRequestDTO,
9
+ UserAnalyticsResponseDTO,
10
+ UserRankingAnalyticsRequestDTO,
11
+ UserRankingAnalyticsResponseDTO,
12
+ BusinessRankingAnalyticsRequestDTO,
13
+ BusinessRankingAnalyticsResponseDTO,
14
+ RetentionAnalyticsRequestDTO,
15
+ RetentionAnalyticsResponseDTO
6
16
  } from '@explorins/pers-shared';
7
17
 
8
18
  /**
9
19
  * React hook for analytics operations in the PERS SDK
10
20
  *
11
- * Provides methods for retrieving transaction analytics and insights.
12
- * Supports various analytics queries for business intelligence and reporting.
21
+ * Provides comprehensive analytics and business intelligence capabilities:
22
+ * - **Transaction Analytics**: Volume, trends, business performance
23
+ * - **Campaign Claim Analytics**: Campaign performance and claim patterns
24
+ * - **User Analytics**: Engagement metrics with per-active-user averages
25
+ * - **User Ranking**: Leaderboards with full user details
26
+ * - **Business Ranking**: Business performance rankings
27
+ * - **Retention Analytics**: Monthly retention metrics
13
28
  *
14
29
  * @returns Analytics hook with methods for data analysis
15
30
  *
16
- * @example
31
+ * @example Basic Transaction Analytics
17
32
  * ```typescript
18
33
  * function AnalyticsComponent() {
19
34
  * const { getTransactionAnalytics } = useAnalytics();
20
35
  *
21
36
  * const loadAnalytics = async () => {
22
- * try {
23
- * const analytics = await getTransactionAnalytics({
24
- * timeRange: 'last_30_days',
25
- * groupBy: 'day'
26
- * });
27
- * console.log('Transaction analytics:', analytics);
28
- * } catch (error) {
29
- * console.error('Failed to load analytics:', error);
30
- * }
37
+ * const analytics = await getTransactionAnalytics({
38
+ * startDate: '2024-01-01',
39
+ * endDate: '2024-01-31',
40
+ * groupBy: 'day'
41
+ * });
42
+ * console.log('Transaction analytics:', analytics);
31
43
  * };
44
+ * }
45
+ * ```
32
46
  *
33
- * return <button onClick={loadAnalytics}>Load Analytics</button>;
47
+ * @example User Leaderboard
48
+ * ```typescript
49
+ * function LeaderboardScreen() {
50
+ * const { getUserRanking } = useAnalytics();
51
+ *
52
+ * const loadLeaderboard = async () => {
53
+ * const ranking = await getUserRanking({
54
+ * sortBy: 'totalTransactions',
55
+ * sortOrder: 'DESC',
56
+ * limit: 50
57
+ * });
58
+ * ranking.results.forEach((user, i) => {
59
+ * console.log(`#${i + 1}: ${user.email} - ${user.totalTransactions} txns`);
60
+ * });
61
+ * };
34
62
  * }
35
63
  * ```
36
64
  */
@@ -46,19 +74,17 @@ export const useAnalytics = () => {
46
74
  *
47
75
  * @example
48
76
  * ```typescript
49
- * const { getTransactionAnalytics } = useAnalytics();
50
77
  * const analytics = await getTransactionAnalytics({
51
- * groupBy: ['day'],
52
- * metrics: ['count', 'sum'],
53
78
  * startDate: '2024-01-01',
54
79
  * endDate: '2024-01-31',
55
- * filters: { status: 'completed' }
80
+ * groupBy: 'day',
81
+ * metrics: ['count', 'sum']
56
82
  * });
57
- * console.log('Daily transaction analytics:', analytics.results);
58
- * console.log('Execution time:', analytics.metadata.executionTime);
59
83
  * ```
60
84
  */
61
- const getTransactionAnalytics = useCallback(async (request: TransactionAnalyticsRequestDTO): Promise<TransactionAnalyticsResponseDTO> => {
85
+ const getTransactionAnalytics = useCallback(async (
86
+ request: TransactionAnalyticsRequestDTO
87
+ ): Promise<TransactionAnalyticsResponseDTO> => {
62
88
  if (!isInitialized || !sdk) {
63
89
  throw new Error('SDK not initialized. Call initialize() first.');
64
90
  }
@@ -72,8 +98,229 @@ export const useAnalytics = () => {
72
98
  }
73
99
  }, [sdk, isInitialized]);
74
100
 
101
+ /**
102
+ * Retrieves campaign claim analytics with aggregation
103
+ *
104
+ * Provides insights into campaign performance, claim patterns, and user engagement.
105
+ *
106
+ * @param request - Analytics request with filters, groupBy, and metrics
107
+ * @returns Promise resolving to campaign claim analytics data
108
+ *
109
+ * @example Claims per campaign
110
+ * ```typescript
111
+ * const analytics = await getCampaignClaimAnalytics({
112
+ * filters: { status: 'COMPLETED' },
113
+ * groupBy: ['campaignId'],
114
+ * metrics: ['count'],
115
+ * sortBy: 'count',
116
+ * sortOrder: 'DESC',
117
+ * limit: 10
118
+ * });
119
+ * console.log('Top campaigns:', analytics.results);
120
+ * ```
121
+ */
122
+ const getCampaignClaimAnalytics = useCallback(async (
123
+ request: CampaignClaimAnalyticsRequestDTO
124
+ ): Promise<CampaignClaimAnalyticsResponseDTO> => {
125
+ if (!isInitialized || !sdk) {
126
+ throw new Error('SDK not initialized. Call initialize() first.');
127
+ }
128
+
129
+ try {
130
+ const result = await sdk.analytics.getCampaignClaimAnalytics(request);
131
+ return result;
132
+ } catch (error) {
133
+ console.error('Failed to fetch campaign claim analytics:', error);
134
+ throw error;
135
+ }
136
+ }, [sdk, isInitialized]);
137
+
138
+ /**
139
+ * Retrieves user analytics with engagement metrics
140
+ *
141
+ * Includes both per-user and per-active-user metrics for accurate engagement insights.
142
+ * Per-active-user metrics show concentrated engagement among active users.
143
+ *
144
+ * @param request - Analytics request with optional filters and date range
145
+ * @returns Promise resolving to user analytics data
146
+ *
147
+ * @example Compare per-user vs per-active-user metrics
148
+ * ```typescript
149
+ * const analytics = await getUserAnalytics({
150
+ * startDate: new Date('2026-02-01'),
151
+ * endDate: new Date('2026-02-28')
152
+ * });
153
+ *
154
+ * console.log(`Active users: ${analytics.activeUsers} / ${analytics.totalUsers}`);
155
+ * console.log(`Engagement rate: ${analytics.engagementRate.toFixed(1)}%`);
156
+ *
157
+ * // Per-active-user metrics (more meaningful)
158
+ * console.log(`Avg transactions per active user: ${analytics.averageTransactionsPerActiveUser}`);
159
+ * ```
160
+ *
161
+ * @example Business-specific analytics
162
+ * ```typescript
163
+ * const analytics = await getUserAnalytics({
164
+ * filters: { businessId: 'business-123' },
165
+ * startDate: new Date('2026-01-01'),
166
+ * endDate: new Date('2026-12-31')
167
+ * });
168
+ * ```
169
+ */
170
+ const getUserAnalytics = useCallback(async (
171
+ request: UserAnalyticsRequestDTO = {}
172
+ ): Promise<UserAnalyticsResponseDTO> => {
173
+ if (!isInitialized || !sdk) {
174
+ throw new Error('SDK not initialized. Call initialize() first.');
175
+ }
176
+
177
+ try {
178
+ const result = await sdk.analytics.getUserAnalytics(request);
179
+ return result;
180
+ } catch (error) {
181
+ console.error('Failed to fetch user analytics:', error);
182
+ throw error;
183
+ }
184
+ }, [sdk, isInitialized]);
185
+
186
+ /**
187
+ * Retrieves user transaction ranking with enriched user data
188
+ *
189
+ * Returns ranked list of users with full user details (email, externalUserId)
190
+ * and transaction metrics. Ideal for leaderboards, engagement analysis,
191
+ * and identifying power users.
192
+ *
193
+ * @param request - Ranking request with filters, sorting, and limit
194
+ * @returns Promise resolving to ranked user list with transaction metrics
195
+ *
196
+ * @example Top 50 users by transaction count
197
+ * ```typescript
198
+ * const ranking = await getUserRanking({
199
+ * sortBy: 'totalTransactions',
200
+ * sortOrder: 'DESC',
201
+ * limit: 50
202
+ * });
203
+ *
204
+ * ranking.results.forEach((user, index) => {
205
+ * console.log(`#${index + 1}: ${user.email || user.externalUserId}`);
206
+ * console.log(` Transactions: ${user.totalTransactions}`);
207
+ * console.log(` Token spent: ${user.tokenSpent}`);
208
+ * });
209
+ * ```
210
+ *
211
+ * @example Top STAMP spenders
212
+ * ```typescript
213
+ * const ranking = await getUserRanking({
214
+ * filters: { tokenType: 'STAMP' },
215
+ * sortBy: 'tokenSpent',
216
+ * sortOrder: 'DESC',
217
+ * limit: 20
218
+ * });
219
+ * ```
220
+ */
221
+ const getUserRanking = useCallback(async (
222
+ request: UserRankingAnalyticsRequestDTO = {}
223
+ ): Promise<UserRankingAnalyticsResponseDTO> => {
224
+ if (!isInitialized || !sdk) {
225
+ throw new Error('SDK not initialized. Call initialize() first.');
226
+ }
227
+
228
+ try {
229
+ const result = await sdk.analytics.getUserRanking(request);
230
+ return result;
231
+ } catch (error) {
232
+ console.error('Failed to fetch user ranking:', error);
233
+ throw error;
234
+ }
235
+ }, [sdk, isInitialized]);
236
+
237
+ /**
238
+ * Retrieves business transaction ranking with enriched business data
239
+ *
240
+ * Returns ranked list of businesses with transaction metrics for
241
+ * partner analytics and performance dashboards.
242
+ *
243
+ * @param request - Ranking request with filters, sorting, and limit
244
+ * @returns Promise resolving to ranked business list
245
+ *
246
+ * @example Top businesses by transaction count
247
+ * ```typescript
248
+ * const ranking = await getBusinessRanking({
249
+ * sortBy: 'totalTransactions',
250
+ * sortOrder: 'DESC',
251
+ * limit: 20
252
+ * });
253
+ *
254
+ * ranking.results.forEach((business, index) => {
255
+ * console.log(`#${index + 1}: ${business.businessId}`);
256
+ * console.log(` Transactions: ${business.totalTransactions}`);
257
+ * console.log(` Token spent: ${business.tokenSpent}`);
258
+ * });
259
+ * ```
260
+ */
261
+ const getBusinessRanking = useCallback(async (
262
+ request: BusinessRankingAnalyticsRequestDTO = {}
263
+ ): Promise<BusinessRankingAnalyticsResponseDTO> => {
264
+ if (!isInitialized || !sdk) {
265
+ throw new Error('SDK not initialized. Call initialize() first.');
266
+ }
267
+
268
+ try {
269
+ const result = await sdk.analytics.getBusinessRanking(request);
270
+ return result;
271
+ } catch (error) {
272
+ console.error('Failed to fetch business ranking:', error);
273
+ throw error;
274
+ }
275
+ }, [sdk, isInitialized]);
276
+
277
+ /**
278
+ * Retrieves monthly user retention analytics
279
+ *
280
+ * Returns monthly retention data with active, new, and returning users
281
+ * along with retention rates. Useful for churn analysis and engagement trends.
282
+ *
283
+ * @param request - Retention request with monthsBack and filters
284
+ * @returns Promise resolving to monthly retention data
285
+ *
286
+ * @example Get 12 months of retention data
287
+ * ```typescript
288
+ * const retention = await getRetentionAnalytics({
289
+ * monthsBack: 12
290
+ * });
291
+ *
292
+ * retention.results.forEach(month => {
293
+ * console.log(`${month.month}:`);
294
+ * console.log(` Active: ${month.activeUsers}`);
295
+ * console.log(` New: ${month.newUsers}`);
296
+ * console.log(` Returning: ${month.returningUsers}`);
297
+ * console.log(` Retention Rate: ${month.retentionRate.toFixed(1)}%`);
298
+ * });
299
+ * ```
300
+ */
301
+ const getRetentionAnalytics = useCallback(async (
302
+ request: RetentionAnalyticsRequestDTO = {}
303
+ ): Promise<RetentionAnalyticsResponseDTO> => {
304
+ if (!isInitialized || !sdk) {
305
+ throw new Error('SDK not initialized. Call initialize() first.');
306
+ }
307
+
308
+ try {
309
+ const result = await sdk.analytics.getRetentionAnalytics(request);
310
+ return result;
311
+ } catch (error) {
312
+ console.error('Failed to fetch retention analytics:', error);
313
+ throw error;
314
+ }
315
+ }, [sdk, isInitialized]);
316
+
75
317
  return {
76
318
  getTransactionAnalytics,
319
+ getCampaignClaimAnalytics,
320
+ getUserAnalytics,
321
+ getUserRanking,
322
+ getBusinessRanking,
323
+ getRetentionAnalytics,
77
324
  isAvailable: isInitialized && !!sdk?.analytics,
78
325
  };
79
326
  };