@explorins/pers-sdk-react-native 2.1.11 → 2.1.13
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/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useCampaigns.d.ts.map +1 -1
- package/dist/hooks/useCampaigns.js +58 -1
- package/dist/hooks/useRedemptions.d.ts +10 -3
- package/dist/hooks/useRedemptions.d.ts.map +1 -1
- package/dist/hooks/useRedemptions.js +66 -9
- package/dist/hooks/useTokenBalances.d.ts +8 -1
- package/dist/hooks/useTokenBalances.d.ts.map +1 -1
- package/dist/hooks/useTokenBalances.js +8 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +249 -39
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useCampaigns.ts +60 -2
- package/src/hooks/useRedemptions.ts +74 -9
- package/src/hooks/useTokenBalances.ts +8 -1
- package/src/index.ts +1 -1
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.13",
|
|
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.20",
|
|
41
41
|
"@explorins/pers-signer": "^1.0.33",
|
|
42
42
|
"buffer": "^6.0.3",
|
|
43
43
|
"ethers": "^6.15.0",
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"@ethersproject/scrypt": false
|
|
156
156
|
},
|
|
157
157
|
"devDependencies": {
|
|
158
|
-
"@explorins/pers-shared": "^2.1.
|
|
158
|
+
"@explorins/pers-shared": "^2.1.123",
|
|
159
159
|
"@react-native-async-storage/async-storage": "^3.0.2",
|
|
160
160
|
"@rollup/plugin-commonjs": "^25.0.7",
|
|
161
161
|
"@rollup/plugin-json": "^6.1.0",
|
package/src/hooks/index.ts
CHANGED
|
@@ -38,7 +38,7 @@ export type {
|
|
|
38
38
|
} from './useTokenBalances';
|
|
39
39
|
|
|
40
40
|
// Export campaign-related types
|
|
41
|
-
export type { CampaignClaimFilters, CampaignHook } from './useCampaigns';
|
|
41
|
+
export type { CampaignClaimFilters, CampaignHook, GetCampaignsOptions } from './useCampaigns';
|
|
42
42
|
|
|
43
43
|
// Export redemption-related types
|
|
44
44
|
export type { RedemptionRedeemFilters, RedemptionHook } from './useRedemptions';
|
|
@@ -8,7 +8,8 @@ import type {
|
|
|
8
8
|
PaginatedResponseDTO,
|
|
9
9
|
CampaignClaimIncludeRelation,
|
|
10
10
|
CampaignIncludeRelation,
|
|
11
|
-
SortOrder
|
|
11
|
+
SortOrder,
|
|
12
|
+
// DynamicContext
|
|
12
13
|
} from '@explorins/pers-shared';
|
|
13
14
|
import type { CampaignClaimFilters } from '@explorins/pers-sdk/campaign';
|
|
14
15
|
|
|
@@ -113,6 +114,63 @@ export const useCampaigns = () => {
|
|
|
113
114
|
}
|
|
114
115
|
}, [sdk, isInitialized]);
|
|
115
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Claim a campaign reward with optional dynamic context
|
|
119
|
+
*
|
|
120
|
+
* Triggers a campaign claim for the authenticated user. The campaign must be active
|
|
121
|
+
* and the user must meet all eligibility requirements. Supports dynamic context for
|
|
122
|
+
* personalized NFT generation when the campaign issues ERC721 tokens.
|
|
123
|
+
*
|
|
124
|
+
* @param request - Campaign claim request with optional context
|
|
125
|
+
* @param request.campaignId - ID of the campaign to claim (optional if using triggerSourceId)
|
|
126
|
+
* @param request.triggerSourceId - ID of trigger source (QR, NFC, etc.)
|
|
127
|
+
* @param request.context - Dynamic context for NFT personalization
|
|
128
|
+
* @param request.metadata - Additional metadata for the claim
|
|
129
|
+
* @param request.latitude - User's latitude for geo-validated claims
|
|
130
|
+
* @param request.longitude - User's longitude for geo-validated claims
|
|
131
|
+
* @returns Promise resolving to campaign claim result
|
|
132
|
+
*
|
|
133
|
+
* @example Basic campaign claim
|
|
134
|
+
* ```typescript
|
|
135
|
+
* const claim = await claimCampaign({
|
|
136
|
+
* triggerSourceId: 'qr-code-123',
|
|
137
|
+
* });
|
|
138
|
+
* ```
|
|
139
|
+
*
|
|
140
|
+
* @example Campaign claim with dynamic context (personalized NFT)
|
|
141
|
+
* ```typescript
|
|
142
|
+
* import { DynamicContext } from '@explorins/pers-sdk-react-native';
|
|
143
|
+
*
|
|
144
|
+
* const context: DynamicContext = {
|
|
145
|
+
* // Validity - token valid for 30 days
|
|
146
|
+
* validityDate: new Date().toISOString(),
|
|
147
|
+
* validityDuration: 30,
|
|
148
|
+
*
|
|
149
|
+
* // AI prompt context - available as {{context.xxx}} in prompts
|
|
150
|
+
* visitorName: 'John Doe',
|
|
151
|
+
* visitLocation: 'Grand Hotel Lobby',
|
|
152
|
+
* membershipTier: 'Gold',
|
|
153
|
+
* };
|
|
154
|
+
*
|
|
155
|
+
* const claim = await claimCampaign({
|
|
156
|
+
* triggerSourceId: 'hotel-checkin-qr',
|
|
157
|
+
* context,
|
|
158
|
+
* });
|
|
159
|
+
* ```
|
|
160
|
+
*
|
|
161
|
+
* @example Geo-validated claim with context
|
|
162
|
+
* ```typescript
|
|
163
|
+
* const claim = await claimCampaign({
|
|
164
|
+
* triggerSourceId: 'museum-entrance-nfc',
|
|
165
|
+
* latitude: 48.8606,
|
|
166
|
+
* longitude: 2.3376,
|
|
167
|
+
* context: {
|
|
168
|
+
* visitorType: 'Adult',
|
|
169
|
+
* ticketCategory: 'General Admission',
|
|
170
|
+
* }
|
|
171
|
+
* });
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
116
174
|
const claimCampaign = useCallback(async (request: CampaignClaimRequestDTO): Promise<CampaignClaimDTO | null> => {
|
|
117
175
|
if (!isInitialized || !sdk) {
|
|
118
176
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
@@ -141,7 +199,7 @@ export const useCampaigns = () => {
|
|
|
141
199
|
* // Get user's claims with campaign details
|
|
142
200
|
* const { data: claims } = await getUserClaims({ include: ['campaign', 'business'] });
|
|
143
201
|
* claims.forEach(claim => {
|
|
144
|
-
* console.log('Campaign:', claim.included?.campaign?.
|
|
202
|
+
* console.log('Campaign:', claim.included?.campaign?.name);
|
|
145
203
|
* });
|
|
146
204
|
*
|
|
147
205
|
* // With pagination
|
|
@@ -8,9 +8,12 @@ import type {
|
|
|
8
8
|
RedemptionRedeemRequestResponseDTO,
|
|
9
9
|
RedemptionTypeDTO,
|
|
10
10
|
PaginatedResponseDTO,
|
|
11
|
-
RedemptionRedeemIncludeRelation
|
|
11
|
+
RedemptionRedeemIncludeRelation,
|
|
12
|
+
ProcessRecordStatus,
|
|
13
|
+
DynamicContext
|
|
12
14
|
} from '@explorins/pers-shared';
|
|
13
15
|
import type { RedemptionRedeemFilters } from '@explorins/pers-sdk/redemption';
|
|
16
|
+
import type { PaginationOptions } from '@explorins/pers-sdk';
|
|
14
17
|
|
|
15
18
|
// Re-export for consumers
|
|
16
19
|
export type { RedemptionRedeemFilters } from '@explorins/pers-sdk/redemption';
|
|
@@ -42,22 +45,34 @@ export const useRedemptions = () => {
|
|
|
42
45
|
}, [sdk, isInitialized]);
|
|
43
46
|
|
|
44
47
|
/**
|
|
45
|
-
* Get user's redemption history with optional include relations
|
|
48
|
+
* Get user's redemption history with optional filters, pagination and include relations
|
|
46
49
|
*
|
|
47
|
-
* @param
|
|
50
|
+
* @param filters - Optional filters (redemptionId, status)
|
|
51
|
+
* @param options - Pagination options (page, limit, sortBy, sortOrder)
|
|
52
|
+
* @param include - Relations to include: 'redemption', 'user', 'business', 'transactions'
|
|
48
53
|
* @returns Promise resolving to paginated redemption history
|
|
49
54
|
*
|
|
50
55
|
* @example
|
|
51
56
|
* ```typescript
|
|
57
|
+
* // Get first page of user redemptions
|
|
58
|
+
* const { data: redeems, pagination } = await getUserRedemptions({}, { page: 1, limit: 10 });
|
|
59
|
+
* console.log(`Page ${pagination.page} of ${pagination.pages}`);
|
|
60
|
+
*
|
|
61
|
+
* // Get only completed redemptions
|
|
62
|
+
* import { ProcessRecordStatus } from '@explorins/pers-shared';
|
|
63
|
+
* const { data: completed } = await getUserRedemptions({ status: ProcessRecordStatus.COMPLETED });
|
|
64
|
+
*
|
|
52
65
|
* // Get user redemptions with full redemption details
|
|
53
|
-
* const { data: redeems } = await getUserRedemptions(['redemption', 'business']);
|
|
66
|
+
* const { data: redeems } = await getUserRedemptions({}, {}, ['redemption', 'business']);
|
|
54
67
|
* redeems.forEach(redeem => {
|
|
55
|
-
* console.log('Redemption:', redeem.included?.redemption?.
|
|
68
|
+
* console.log('Redemption:', redeem.included?.redemption?.name);
|
|
56
69
|
* console.log('Business:', redeem.included?.business?.displayName);
|
|
57
70
|
* });
|
|
58
71
|
* ```
|
|
59
72
|
*/
|
|
60
73
|
const getUserRedemptions = useCallback(async (
|
|
74
|
+
filters?: { redemptionId?: string; status?: ProcessRecordStatus },
|
|
75
|
+
options?: PaginationOptions,
|
|
61
76
|
include?: RedemptionRedeemIncludeRelation[]
|
|
62
77
|
): Promise<PaginatedResponseDTO<RedemptionRedeemDTO>> => {
|
|
63
78
|
if (!isInitialized || !sdk) {
|
|
@@ -69,7 +84,7 @@ export const useRedemptions = () => {
|
|
|
69
84
|
}
|
|
70
85
|
|
|
71
86
|
try {
|
|
72
|
-
const result = await sdk.redemptions.getUserRedemptions(
|
|
87
|
+
const result = await sdk.redemptions.getUserRedemptions(filters, options, include);
|
|
73
88
|
return result;
|
|
74
89
|
} catch (error) {
|
|
75
90
|
console.error('Failed to fetch user redemptions:', error);
|
|
@@ -77,7 +92,57 @@ export const useRedemptions = () => {
|
|
|
77
92
|
}
|
|
78
93
|
}, [sdk, isInitialized, isAuthenticated]);
|
|
79
94
|
|
|
80
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Redeem a redemption offer with optional dynamic context
|
|
97
|
+
*
|
|
98
|
+
* Supports dynamic context for personalized NFT generation when the redemption
|
|
99
|
+
* issues ERC721 tokens. Context can include validity dates, AI prompt placeholders,
|
|
100
|
+
* and custom metadata.
|
|
101
|
+
*
|
|
102
|
+
* @param redemptionId - ID of the redemption to redeem
|
|
103
|
+
* @param options - Optional settings
|
|
104
|
+
* @param options.context - Dynamic context for NFT personalization (validity dates, AI prompts)
|
|
105
|
+
* @param options.onStatusUpdate - Callback for transaction signing status updates
|
|
106
|
+
* @returns Promise resolving to redemption result
|
|
107
|
+
*
|
|
108
|
+
* @example Basic redemption
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const result = await redeem('redemption-123');
|
|
111
|
+
* ```
|
|
112
|
+
*
|
|
113
|
+
* @example Redemption with dynamic context (personalized NFT)
|
|
114
|
+
* ```typescript
|
|
115
|
+
* const result = await redeem('event-ticket-123', {
|
|
116
|
+
* context: {
|
|
117
|
+
* // Validity - token valid for event duration
|
|
118
|
+
* validityDate: new Date().toISOString(),
|
|
119
|
+
* validityDuration: 8, // 8 hours
|
|
120
|
+
*
|
|
121
|
+
* // AI prompt context - available as {{context.xxx}} in prompts
|
|
122
|
+
* attendeeName: 'John Doe',
|
|
123
|
+
* ticketTier: 'VIP',
|
|
124
|
+
* seatSection: 'A12',
|
|
125
|
+
* }
|
|
126
|
+
* });
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
129
|
+
* @example Hotel stay NFT with check-in/check-out dates
|
|
130
|
+
* ```typescript
|
|
131
|
+
* const result = await redeem('hotel-nft-456', {
|
|
132
|
+
* context: {
|
|
133
|
+
* validityDate: '2026-04-15T14:00:00Z', // Check-in
|
|
134
|
+
* validityEndDate: '2026-04-20T11:00:00Z', // Check-out
|
|
135
|
+
* guestName: 'Jane Smith',
|
|
136
|
+
* roomNumber: '305',
|
|
137
|
+
* roomType: 'Suite',
|
|
138
|
+
* }
|
|
139
|
+
* });
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
const redeem = useCallback(async (
|
|
143
|
+
redemptionId: string,
|
|
144
|
+
options?: { context?: DynamicContext; onStatusUpdate?: OnStatusUpdateFn }
|
|
145
|
+
): Promise<RedemptionRedeemRequestResponseDTO> => {
|
|
81
146
|
if (!isInitialized || !sdk) {
|
|
82
147
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
83
148
|
}
|
|
@@ -86,12 +151,12 @@ export const useRedemptions = () => {
|
|
|
86
151
|
}
|
|
87
152
|
|
|
88
153
|
try {
|
|
89
|
-
const result = await sdk.redemptions.redeem(redemptionId);
|
|
154
|
+
const result = await sdk.redemptions.redeem(redemptionId, options?.context);
|
|
90
155
|
|
|
91
156
|
const txToken = result.senderTransaction?.actionable?.authToken;
|
|
92
157
|
if (txToken && isSignerAvailable) {
|
|
93
158
|
try {
|
|
94
|
-
const signingResult: SubmissionResult = await signAndSubmitTransactionWithJWT(txToken, onStatusUpdate);
|
|
159
|
+
const signingResult: SubmissionResult = await signAndSubmitTransactionWithJWT(txToken, options?.onStatusUpdate);
|
|
95
160
|
if (signingResult.success) {
|
|
96
161
|
// Return enhanced result with signing information
|
|
97
162
|
return {
|
|
@@ -95,10 +95,17 @@ export interface UseTokenBalancesResult {
|
|
|
95
95
|
* **Basic Usage:**
|
|
96
96
|
* ```typescript
|
|
97
97
|
* import { useTokenBalances, useTokens, usePersSDK } from '@explorins/pers-sdk-react-native';
|
|
98
|
+
* import { useState, useEffect } from 'react';
|
|
98
99
|
*
|
|
99
100
|
* function TokenBalancesScreen() {
|
|
100
101
|
* const { user } = usePersSDK();
|
|
101
|
-
* const {
|
|
102
|
+
* const { getTokens } = useTokens();
|
|
103
|
+
* const [availableTokens, setAvailableTokens] = useState([]);
|
|
104
|
+
*
|
|
105
|
+
* // Load tokens on mount
|
|
106
|
+
* useEffect(() => {
|
|
107
|
+
* getTokens().then(result => setAvailableTokens(result.data));
|
|
108
|
+
* }, []);
|
|
102
109
|
*
|
|
103
110
|
* // App explicitly selects which wallet to use
|
|
104
111
|
* const walletAddress = user?.wallets?.[0]?.address;
|
package/src/index.ts
CHANGED
|
@@ -284,7 +284,7 @@ export type { EventsHook, PersEvent, EventHandler, EventFilter, Unsubscribe } fr
|
|
|
284
284
|
export type { TokenBalanceWithToken, UseTokenBalancesOptions, UseTokenBalancesResult } from './hooks';
|
|
285
285
|
|
|
286
286
|
// Re-export campaign types for convenience
|
|
287
|
-
export type { CampaignClaimFilters, CampaignHook } from './hooks';
|
|
287
|
+
export type { CampaignClaimFilters, CampaignHook, GetCampaignsOptions } from './hooks';
|
|
288
288
|
|
|
289
289
|
// Re-export redemption types for convenience
|
|
290
290
|
export type { RedemptionRedeemFilters, RedemptionHook } from './hooks';
|