@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.
- package/README.md +7 -7
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useAnalytics.d.ts +37 -14
- package/dist/hooks/useAnalytics.d.ts.map +1 -1
- package/dist/hooks/useAnalytics.js +239 -19
- package/dist/hooks/useCampaigns.d.ts +14 -6
- package/dist/hooks/useCampaigns.d.ts.map +1 -1
- package/dist/hooks/useCampaigns.js +144 -10
- package/dist/hooks/useEvents.d.ts +17 -5
- package/dist/hooks/useEvents.d.ts.map +1 -1
- package/dist/hooks/useEvents.js +17 -5
- package/dist/hooks/useRedemptions.d.ts +5 -2
- package/dist/hooks/useRedemptions.d.ts.map +1 -1
- package/dist/hooks/useRedemptions.js +53 -2
- package/dist/hooks/useTokenBalances.d.ts +24 -0
- package/dist/hooks/useTokenBalances.d.ts.map +1 -1
- package/dist/hooks/useTokenBalances.js +42 -2
- package/dist/hooks/useTransactions.d.ts +8 -5
- package/dist/hooks/useTransactions.d.ts.map +1 -1
- package/dist/hooks/useTransactions.js +70 -27
- package/dist/hooks/useTriggerSources.d.ts +76 -0
- package/dist/hooks/useTriggerSources.d.ts.map +1 -0
- package/dist/hooks/useTriggerSources.js +272 -0
- package/dist/hooks/useUsers.d.ts +5 -4
- package/dist/hooks/useUsers.d.ts.map +1 -1
- package/dist/hooks/useUsers.js +47 -8
- package/dist/hooks/useWeb3.d.ts +6 -5
- package/dist/hooks/useWeb3.d.ts.map +1 -1
- package/dist/hooks/useWeb3.js +23 -10
- package/dist/index.d.ts +12 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5500 -893
- package/dist/index.js.map +1 -1
- package/dist/providers/PersSDKProvider.d.ts +38 -0
- package/dist/providers/PersSDKProvider.d.ts.map +1 -1
- package/dist/providers/PersSDKProvider.js +29 -1
- package/package.json +3 -2
- package/src/hooks/index.ts +17 -1
- package/src/hooks/useAnalytics.ts +268 -21
- package/src/hooks/useCampaigns.ts +176 -14
- package/src/hooks/useEvents.ts +17 -5
- package/src/hooks/useRedemptions.ts +66 -3
- package/src/hooks/useTokenBalances.ts +60 -2
- package/src/hooks/useTransactions.ts +84 -29
- package/src/hooks/useTriggerSources.ts +301 -0
- package/src/hooks/useUsers.ts +51 -9
- package/src/hooks/useWeb3.ts +28 -13
- package/src/index.ts +33 -3
- 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;
|
|
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
|
-
|
|
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
|
+
"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.
|
|
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",
|
package/src/hooks/index.ts
CHANGED
|
@@ -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
|
|
12
|
-
*
|
|
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
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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 (
|
|
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
|
};
|