@explorins/pers-sdk-react-native 2.1.7 → 2.1.10
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/dist/hooks/useCampaigns.d.ts +24 -3
- package/dist/hooks/useCampaigns.d.ts.map +1 -1
- package/dist/hooks/useCampaigns.js +58 -4
- package/dist/hooks/useTokenBalances.d.ts +6 -13
- package/dist/hooks/useTokenBalances.d.ts.map +1 -1
- package/dist/hooks/useTokenBalances.js +6 -27
- package/dist/index.js +186 -59
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/hooks/useCampaigns.ts +84 -5
- package/src/hooks/useTokenBalances.ts +11 -29
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.10",
|
|
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.16",
|
|
41
41
|
"@explorins/pers-signer": "^1.0.33",
|
|
42
42
|
"buffer": "^6.0.3",
|
|
43
43
|
"ethers": "^6.15.0",
|
|
@@ -7,23 +7,74 @@ import type {
|
|
|
7
7
|
CampaignTriggerDTO,
|
|
8
8
|
PaginatedResponseDTO,
|
|
9
9
|
CampaignClaimIncludeRelation,
|
|
10
|
-
CampaignIncludeRelation
|
|
10
|
+
CampaignIncludeRelation,
|
|
11
|
+
SortOrder
|
|
11
12
|
} from '@explorins/pers-shared';
|
|
12
13
|
import type { CampaignClaimFilters } from '@explorins/pers-sdk/campaign';
|
|
13
14
|
|
|
14
15
|
// Re-export for consumers
|
|
15
16
|
export type { CampaignClaimFilters } from '@explorins/pers-sdk/campaign';
|
|
16
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Options for fetching campaigns
|
|
20
|
+
*/
|
|
21
|
+
export interface GetCampaignsOptions {
|
|
22
|
+
/** Filter by tag */
|
|
23
|
+
tag?: string;
|
|
24
|
+
/** Filter by business ID */
|
|
25
|
+
businessId?: string;
|
|
26
|
+
/** Page number (1-indexed) */
|
|
27
|
+
page?: number;
|
|
28
|
+
/** Items per page */
|
|
29
|
+
limit?: number;
|
|
30
|
+
/** Sort field */
|
|
31
|
+
sortBy?: 'name' | 'createdAt' | 'startDate';
|
|
32
|
+
/** Sort order */
|
|
33
|
+
sortOrder?: SortOrder;
|
|
34
|
+
/** Relations to include: 'triggerSources', 'businesses' */
|
|
35
|
+
include?: CampaignIncludeRelation[];
|
|
36
|
+
}
|
|
37
|
+
|
|
17
38
|
export const useCampaigns = () => {
|
|
18
39
|
const { sdk, isInitialized, isAuthenticated } = usePersSDK();
|
|
19
40
|
|
|
20
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Get active campaigns with optional filters and include relations
|
|
43
|
+
*
|
|
44
|
+
* @param options - Filter, pagination, and include options
|
|
45
|
+
* @returns Promise resolving to paginated active campaigns
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* // Simple: get active campaigns with trigger sources
|
|
50
|
+
* const { data: campaigns } = await getActiveCampaigns({ include: ['triggerSources'] });
|
|
51
|
+
*
|
|
52
|
+
* // With pagination
|
|
53
|
+
* const { data, pagination } = await getActiveCampaigns({
|
|
54
|
+
* page: 1,
|
|
55
|
+
* limit: 10,
|
|
56
|
+
* include: ['triggerSources', 'businesses']
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* // Filter by tag
|
|
60
|
+
* const { data } = await getActiveCampaigns({ tag: 'summer-promo' });
|
|
61
|
+
*
|
|
62
|
+
* // Filter by business
|
|
63
|
+
* const { data } = await getActiveCampaigns({ businessId: 'business-123' });
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
const getActiveCampaigns = useCallback(async (
|
|
67
|
+
options?: GetCampaignsOptions
|
|
68
|
+
): Promise<PaginatedResponseDTO<CampaignDTO>> => {
|
|
21
69
|
if (!isInitialized || !sdk) {
|
|
22
70
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
23
71
|
}
|
|
24
72
|
|
|
25
73
|
try {
|
|
26
|
-
const result = await sdk.campaigns.getCampaigns({
|
|
74
|
+
const result = await sdk.campaigns.getCampaigns({
|
|
75
|
+
active: true,
|
|
76
|
+
...options
|
|
77
|
+
});
|
|
27
78
|
return result;
|
|
28
79
|
} catch (error) {
|
|
29
80
|
console.error('Failed to fetch active campaigns:', error);
|
|
@@ -134,13 +185,41 @@ export const useCampaigns = () => {
|
|
|
134
185
|
}, [sdk, isInitialized]);
|
|
135
186
|
|
|
136
187
|
// Admin methods
|
|
137
|
-
|
|
188
|
+
/**
|
|
189
|
+
* Admin: Get all campaigns with optional filters and include relations
|
|
190
|
+
*
|
|
191
|
+
* @param options - Filter, pagination, and include options (same as getActiveCampaigns but active is optional)
|
|
192
|
+
* @returns Promise resolving to paginated campaigns
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* // Get all campaigns
|
|
197
|
+
* const { data } = await getAllCampaigns();
|
|
198
|
+
*
|
|
199
|
+
* // Get only active campaigns with trigger sources
|
|
200
|
+
* const { data } = await getAllCampaigns({ active: true, include: ['triggerSources'] });
|
|
201
|
+
*
|
|
202
|
+
* // Get inactive campaigns
|
|
203
|
+
* const { data } = await getAllCampaigns({ active: false });
|
|
204
|
+
*
|
|
205
|
+
* // With pagination and sorting
|
|
206
|
+
* const { data } = await getAllCampaigns({
|
|
207
|
+
* page: 1,
|
|
208
|
+
* limit: 20,
|
|
209
|
+
* sortBy: 'createdAt',
|
|
210
|
+
* sortOrder: 'DESC'
|
|
211
|
+
* });
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
const getAllCampaigns = useCallback(async (
|
|
215
|
+
options?: GetCampaignsOptions & { active?: boolean }
|
|
216
|
+
): Promise<PaginatedResponseDTO<CampaignDTO>> => {
|
|
138
217
|
if (!isInitialized || !sdk) {
|
|
139
218
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
140
219
|
}
|
|
141
220
|
|
|
142
221
|
try {
|
|
143
|
-
const result = await sdk.campaigns.getCampaigns(
|
|
222
|
+
const result = await sdk.campaigns.getCampaigns(options);
|
|
144
223
|
return result;
|
|
145
224
|
} catch (error) {
|
|
146
225
|
console.error('Failed to fetch all campaigns:', error);
|
|
@@ -34,7 +34,11 @@ export interface UseTokenBalancesOptions {
|
|
|
34
34
|
availableTokens?: TokenDTO[];
|
|
35
35
|
/** Whether to automatically load balances on mount/auth/token changes */
|
|
36
36
|
autoLoad?: boolean;
|
|
37
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Fallback polling interval in milliseconds (0 = disabled)
|
|
39
|
+
* @deprecated Use wallet events instead (refreshOnWalletEvents). Polling kept as fallback only.
|
|
40
|
+
* @default 0
|
|
41
|
+
*/
|
|
38
42
|
refreshInterval?: number;
|
|
39
43
|
/**
|
|
40
44
|
* Auto-refresh balances when wallet events are received (Transfer, Approval, etc.)
|
|
@@ -127,18 +131,7 @@ export interface UseTokenBalancesResult {
|
|
|
127
131
|
* ```
|
|
128
132
|
*
|
|
129
133
|
* @example
|
|
130
|
-
* **With
|
|
131
|
-
* ```typescript
|
|
132
|
-
* const { tokenBalances, isLoading } = useTokenBalances({
|
|
133
|
-
* accountAddress: walletAddress!,
|
|
134
|
-
* availableTokens,
|
|
135
|
-
* autoLoad: true,
|
|
136
|
-
* refreshInterval: 30000 // Refresh every 30 seconds
|
|
137
|
-
* });
|
|
138
|
-
* ```
|
|
139
|
-
*
|
|
140
|
-
* @example
|
|
141
|
-
* **With Wallet Events (Real-time):**
|
|
134
|
+
* **With Wallet Events (Real-time):
|
|
142
135
|
* ```typescript
|
|
143
136
|
* // Auto-refresh on Transfer, Approval, and other blockchain events
|
|
144
137
|
* const { tokenBalances } = useTokenBalances({
|
|
@@ -297,30 +290,19 @@ export function useTokenBalances(options: UseTokenBalancesOptions): UseTokenBala
|
|
|
297
290
|
}
|
|
298
291
|
}, [autoLoad, isAvailable, availableTokens.length, loadBalances]);
|
|
299
292
|
|
|
300
|
-
//
|
|
293
|
+
// Deprecated: Fallback polling interval (prefer wallet events)
|
|
294
|
+
// Kept for backward compatibility and edge cases where events might not work
|
|
301
295
|
useEffect(() => {
|
|
302
|
-
if (
|
|
303
|
-
|
|
304
|
-
// Subscribe to transaction domain events
|
|
305
|
-
const unsubscribe = sdk.events.subscribe((event) => {
|
|
306
|
-
if (event.domain === 'transaction' && event.type === 'transaction_completed') {
|
|
307
|
-
console.log('[useTokenBalances] Transaction completed, refreshing balances...');
|
|
308
|
-
loadBalances();
|
|
309
|
-
}
|
|
310
|
-
}, { domains: ['transaction'] });
|
|
296
|
+
if (refreshInterval <= 0 || !isAvailable) return;
|
|
311
297
|
|
|
312
|
-
// Also set up a fallback polling interval (much longer than before)
|
|
313
|
-
// This handles cases where events might be missed
|
|
314
|
-
const fallbackInterval = Math.max(refreshInterval, 60000); // Minimum 1 minute
|
|
315
298
|
const intervalId = setInterval(() => {
|
|
316
299
|
loadBalances();
|
|
317
|
-
},
|
|
300
|
+
}, refreshInterval);
|
|
318
301
|
|
|
319
302
|
return () => {
|
|
320
|
-
unsubscribe();
|
|
321
303
|
clearInterval(intervalId);
|
|
322
304
|
};
|
|
323
|
-
}, [
|
|
305
|
+
}, [refreshInterval, isAvailable, loadBalances]);
|
|
324
306
|
|
|
325
307
|
// Wallet events refresh: listen for real-time blockchain events
|
|
326
308
|
// Refreshes on ANY wallet domain event (Transfer, TransferSingle, etc.)
|