@explorins/pers-sdk-react-native 2.1.12 → 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 +9 -3
- package/dist/hooks/useRedemptions.d.ts.map +1 -1
- package/dist/hooks/useRedemptions.js +62 -10
- 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 +245 -40
- 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 +68 -10
- package/src/hooks/useTokenBalances.ts +8 -1
- package/src/index.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -2882,12 +2882,21 @@ exports.SignedUrlType = void 0;
|
|
|
2882
2882
|
* Token Validity Type Enum
|
|
2883
2883
|
*
|
|
2884
2884
|
* Defines how token expiry is calculated:
|
|
2885
|
+
*
|
|
2886
|
+
* Static types (computed at issuance from template):
|
|
2885
2887
|
* - FIXED_DATE: Uses expiryDate directly as absolute expiration
|
|
2886
2888
|
* - DAYS_FROM_ISSUANCE: Computes expiry as issuance date + validityDuration days
|
|
2887
2889
|
* - HOURS_FROM_ISSUANCE: Computes expiry as issuance date + validityDuration hours
|
|
2888
2890
|
* - MONTHS_FROM_ISSUANCE: Computes expiry as issuance date + validityDuration months
|
|
2889
2891
|
* - END_OF_MONTH: Token expires at end of the month when issued
|
|
2890
2892
|
* - END_OF_YEAR: Token expires at end of the year when issued
|
|
2893
|
+
*
|
|
2894
|
+
* Trigger-based types (computed from runtime context):
|
|
2895
|
+
* - TRIGGER_DATE: Uses date from context.validityDate (e.g., hotel check-out date)
|
|
2896
|
+
* - TRIGGER_DATE_RANGE: Uses context.validityEndDate directly (for explicit start/end scenarios)
|
|
2897
|
+
* - DAYS_FROM_TRIGGER: Computes expiry as context.validityDate + duration days
|
|
2898
|
+
* Duration from context.validityDuration OR template.validityDuration
|
|
2899
|
+
* - HOURS_FROM_TRIGGER: Same as above but hours
|
|
2891
2900
|
*/
|
|
2892
2901
|
const TokenValidityTypes = {
|
|
2893
2902
|
FIXED_DATE: 'fixed_date',
|
|
@@ -2896,6 +2905,11 @@ const TokenValidityTypes = {
|
|
|
2896
2905
|
MONTHS_FROM_ISSUANCE: 'months_from_issuance',
|
|
2897
2906
|
END_OF_MONTH: 'end_of_month',
|
|
2898
2907
|
END_OF_YEAR: 'end_of_year',
|
|
2908
|
+
// Trigger-based types - require context at runtime
|
|
2909
|
+
TRIGGER_DATE: 'trigger_date',
|
|
2910
|
+
TRIGGER_DATE_RANGE: 'trigger_date_range',
|
|
2911
|
+
DAYS_FROM_TRIGGER: 'days_from_trigger',
|
|
2912
|
+
HOURS_FROM_TRIGGER: 'hours_from_trigger',
|
|
2899
2913
|
};
|
|
2900
2914
|
const TOKEN_VALIDITY_TYPE_VALUES = Object.values(TokenValidityTypes);
|
|
2901
2915
|
|
|
@@ -6516,12 +6530,11 @@ class RedemptionApi {
|
|
|
6516
6530
|
* - USER: Direct user redemption processing
|
|
6517
6531
|
* - ADMIN: Can process redemptions for any account type
|
|
6518
6532
|
* - BUSINESS: Process redemptions for customers
|
|
6533
|
+
*
|
|
6534
|
+
* @param request - Redemption request with optional context for dynamic NFT generation
|
|
6519
6535
|
*/
|
|
6520
|
-
async redeemRedemption(
|
|
6521
|
-
|
|
6522
|
-
redemptionId: redemptionId,
|
|
6523
|
-
};
|
|
6524
|
-
return this.apiClient.post(this.basePath + '/redeems', body);
|
|
6536
|
+
async redeemRedemption(request) {
|
|
6537
|
+
return this.apiClient.post(this.basePath + '/redeems', request);
|
|
6525
6538
|
}
|
|
6526
6539
|
// ==========================================
|
|
6527
6540
|
// REDEMPTION REDEEMS QUERIES (NEW ENDPOINTS)
|
|
@@ -6531,10 +6544,10 @@ class RedemptionApi {
|
|
|
6531
6544
|
*
|
|
6532
6545
|
* Role-based access with unified filtering:
|
|
6533
6546
|
* - Users: See only their own redeems (userId/businessId filters ignored)
|
|
6534
|
-
* - Admins: Can filter by userId, businessId, or
|
|
6547
|
+
* - Admins: Can filter by userId, businessId, redemptionId, or status
|
|
6535
6548
|
*
|
|
6536
|
-
* @param filters - Filter and pagination options (redemptionId, userId, businessId, myRedeems, page, limit, sortBy, sortOrder)
|
|
6537
|
-
* @param include - Optional relations to include (redemption, user, business)
|
|
6549
|
+
* @param filters - Filter and pagination options (redemptionId, userId, businessId, status, myRedeems, page, limit, sortBy, sortOrder)
|
|
6550
|
+
* @param include - Optional relations to include (redemption, user, business, transactions)
|
|
6538
6551
|
* @returns Paginated response with redemption redeems
|
|
6539
6552
|
*/
|
|
6540
6553
|
async getRedemptionRedeems(filters, include) {
|
|
@@ -6546,6 +6559,9 @@ class RedemptionApi {
|
|
|
6546
6559
|
if (filters?.redemptionId) {
|
|
6547
6560
|
params.append('redemptionId', filters.redemptionId);
|
|
6548
6561
|
}
|
|
6562
|
+
if (filters?.status) {
|
|
6563
|
+
params.append('status', filters.status);
|
|
6564
|
+
}
|
|
6549
6565
|
// Add include parameter
|
|
6550
6566
|
if (include && include.length > 0) {
|
|
6551
6567
|
include.forEach(relation => params.append('include', relation));
|
|
@@ -6560,6 +6576,8 @@ class RedemptionApi {
|
|
|
6560
6576
|
params.append('userId', filters.userId);
|
|
6561
6577
|
if (filters?.businessId)
|
|
6562
6578
|
params.append('businessId', filters.businessId);
|
|
6579
|
+
if (filters?.status)
|
|
6580
|
+
params.append('status', filters.status);
|
|
6563
6581
|
// Add include parameter
|
|
6564
6582
|
if (include && include.length > 0) {
|
|
6565
6583
|
include.forEach(relation => params.append('include', relation));
|
|
@@ -6588,13 +6606,13 @@ class RedemptionApi {
|
|
|
6588
6606
|
* UNIFIED: Get user redemption history
|
|
6589
6607
|
*
|
|
6590
6608
|
* Uses convenience endpoint /redemption-redeems/me with optional filtering
|
|
6591
|
-
* @param
|
|
6609
|
+
* @param filters - Optional filters (redemptionId, status)
|
|
6592
6610
|
* @param options - Pagination options (page, limit, sortBy, sortOrder)
|
|
6593
|
-
* @param include - Optional relations to include (redemption, user, business)
|
|
6611
|
+
* @param include - Optional relations to include (redemption, user, business, transactions)
|
|
6594
6612
|
* @returns Paginated response with user's redemption redeems
|
|
6595
6613
|
*/
|
|
6596
|
-
async getUserRedeems(
|
|
6597
|
-
return this.getRedemptionRedeems({ myRedeems: true,
|
|
6614
|
+
async getUserRedeems(filters, options, include) {
|
|
6615
|
+
return this.getRedemptionRedeems({ myRedeems: true, ...filters, ...options }, include);
|
|
6598
6616
|
}
|
|
6599
6617
|
// ==========================================
|
|
6600
6618
|
// ADMIN OPERATIONS (Tenant Admin JWT)
|
|
@@ -6720,26 +6738,33 @@ class RedemptionService {
|
|
|
6720
6738
|
// AUTHENTICATED OPERATIONS
|
|
6721
6739
|
// ==========================================
|
|
6722
6740
|
/**
|
|
6723
|
-
* AUTH: Redeem a redemption
|
|
6741
|
+
* AUTH: Redeem a redemption with optional dynamic context
|
|
6742
|
+
*
|
|
6743
|
+
* @param request - Redemption request (can be just redemptionId string or full request with context)
|
|
6724
6744
|
*/
|
|
6725
|
-
async redeemRedemption(
|
|
6726
|
-
|
|
6745
|
+
async redeemRedemption(request) {
|
|
6746
|
+
// Support both simple string and full request object
|
|
6747
|
+
const requestBody = typeof request === 'string'
|
|
6748
|
+
? { redemptionId: request }
|
|
6749
|
+
: request;
|
|
6750
|
+
return this.redemptionApi.redeemRedemption(requestBody);
|
|
6727
6751
|
}
|
|
6728
6752
|
/**
|
|
6729
6753
|
* UNIFIED: Get redemption redeems with filtering and pagination
|
|
6730
|
-
* @param filters - Filter options
|
|
6731
|
-
* @param include - Optional relations to include (redemption, user, business)
|
|
6754
|
+
* @param filters - Filter options (redemptionId, userId, businessId, status, myRedeems)
|
|
6755
|
+
* @param include - Optional relations to include (redemption, user, business, transactions)
|
|
6732
6756
|
*/
|
|
6733
6757
|
async getRedemptionRedeems(filters, include) {
|
|
6734
6758
|
return this.redemptionApi.getRedemptionRedeems(filters, include);
|
|
6735
6759
|
}
|
|
6736
6760
|
/**
|
|
6737
|
-
* Convenience: Get user redemptions with pagination
|
|
6761
|
+
* Convenience: Get user redemptions with pagination and filtering
|
|
6762
|
+
* @param filters - Optional filters (redemptionId, status)
|
|
6738
6763
|
* @param options - Pagination options
|
|
6739
|
-
* @param include - Optional relations to include (redemption, user, business)
|
|
6764
|
+
* @param include - Optional relations to include (redemption, user, business, transactions)
|
|
6740
6765
|
*/
|
|
6741
|
-
async getUserRedeems(options, include) {
|
|
6742
|
-
return this.redemptionApi.getUserRedeems(
|
|
6766
|
+
async getUserRedeems(filters, options, include) {
|
|
6767
|
+
return this.redemptionApi.getUserRedeems(filters, options, include);
|
|
6743
6768
|
}
|
|
6744
6769
|
// ==========================================
|
|
6745
6770
|
// ADMIN OPERATIONS
|
|
@@ -7281,7 +7306,7 @@ function buildAccountSelector(data) {
|
|
|
7281
7306
|
* 🎯 Build a MINT transaction request (admin/business endpoint)
|
|
7282
7307
|
* Creates tokens and assigns them to a recipient account
|
|
7283
7308
|
*
|
|
7284
|
-
* @example
|
|
7309
|
+
* @example Basic Mint
|
|
7285
7310
|
* ```typescript
|
|
7286
7311
|
* const request = buildMintRequest({
|
|
7287
7312
|
* amount: 100,
|
|
@@ -7292,6 +7317,27 @@ function buildAccountSelector(data) {
|
|
|
7292
7317
|
* engagedBusinessId: 'business-456' // optional: for tracking which business triggered the mint
|
|
7293
7318
|
* });
|
|
7294
7319
|
* ```
|
|
7320
|
+
*
|
|
7321
|
+
* @example ERC721 Mint with Dynamic Context
|
|
7322
|
+
* ```typescript
|
|
7323
|
+
* const request = buildMintRequest({
|
|
7324
|
+
* amount: 1,
|
|
7325
|
+
* contractAddress: '0x...',
|
|
7326
|
+
* contractTokenId: '123', // TokenMetadata ID
|
|
7327
|
+
* chainId: 137,
|
|
7328
|
+
* recipientAccountId: 'user-123',
|
|
7329
|
+
* recipientAccountType: AccountOwnerType.USER,
|
|
7330
|
+
* context: {
|
|
7331
|
+
* // Validity control
|
|
7332
|
+
* validityDate: '2026-04-15T14:00:00Z',
|
|
7333
|
+
* validityEndDate: '2026-04-20T11:00:00Z',
|
|
7334
|
+
* // AI prompt placeholders (available as {{context.xxx}})
|
|
7335
|
+
* guestName: 'John Doe',
|
|
7336
|
+
* roomNumber: '305',
|
|
7337
|
+
* awardReason: 'Employee of the Month'
|
|
7338
|
+
* }
|
|
7339
|
+
* });
|
|
7340
|
+
* ```
|
|
7295
7341
|
*/
|
|
7296
7342
|
function buildMintRequest(data) {
|
|
7297
7343
|
return {
|
|
@@ -7305,7 +7351,8 @@ function buildMintRequest(data) {
|
|
|
7305
7351
|
accountAddress: data.recipientAccountAddress
|
|
7306
7352
|
})
|
|
7307
7353
|
},
|
|
7308
|
-
...(data.engagedBusinessId && { engagedBusinessId: data.engagedBusinessId })
|
|
7354
|
+
...(data.engagedBusinessId && { engagedBusinessId: data.engagedBusinessId }),
|
|
7355
|
+
...(data.context && { context: data.context })
|
|
7309
7356
|
};
|
|
7310
7357
|
}
|
|
7311
7358
|
/**
|
|
@@ -12987,7 +13034,12 @@ class RedemptionManager {
|
|
|
12987
13034
|
* redemption confirmation details. Creates a permanent redemption record
|
|
12988
13035
|
* and may generate voucher codes or instructions.
|
|
12989
13036
|
*
|
|
13037
|
+
* Supports dynamic context for personalized NFT generation when the redemption
|
|
13038
|
+
* issues ERC721 tokens. Context can include validity dates, AI prompt placeholders,
|
|
13039
|
+
* and custom metadata.
|
|
13040
|
+
*
|
|
12990
13041
|
* @param redemptionId - ID of the redemption offer to redeem
|
|
13042
|
+
* @param context - Optional dynamic context for NFT personalization (validity dates, AI prompts)
|
|
12991
13043
|
* @returns Promise resolving to redemption result with confirmation details
|
|
12992
13044
|
* @throws {PersApiError} When redemption is not available or user lacks required tokens
|
|
12993
13045
|
*
|
|
@@ -13035,6 +13087,30 @@ class RedemptionManager {
|
|
|
13035
13087
|
* }
|
|
13036
13088
|
* ```
|
|
13037
13089
|
*
|
|
13090
|
+
* @example Redemption with Dynamic Context (Personalized NFT)
|
|
13091
|
+
* ```typescript
|
|
13092
|
+
* // Event ticket with dynamic validity and personalization
|
|
13093
|
+
* const result = await sdk.redemptions.redeem('event-ticket-123', {
|
|
13094
|
+
* // Validity - token valid for event duration + 2 hours
|
|
13095
|
+
* validityDate: new Date().toISOString(),
|
|
13096
|
+
* validityDuration: 8, // 8 hours
|
|
13097
|
+
*
|
|
13098
|
+
* // AI prompt context - available as {{context.xxx}} in prompts
|
|
13099
|
+
* attendeeName: 'John Doe',
|
|
13100
|
+
* ticketTier: 'VIP',
|
|
13101
|
+
* seatSection: 'A12',
|
|
13102
|
+
* });
|
|
13103
|
+
*
|
|
13104
|
+
* // Hotel stay NFT with check-in/check-out dates
|
|
13105
|
+
* const hotelResult = await sdk.redemptions.redeem('hotel-nft-456', {
|
|
13106
|
+
* validityDate: '2026-04-15T14:00:00Z', // Check-in
|
|
13107
|
+
* validityEndDate: '2026-04-20T11:00:00Z', // Check-out
|
|
13108
|
+
* guestName: 'Jane Smith',
|
|
13109
|
+
* roomNumber: '305',
|
|
13110
|
+
* roomType: 'Suite',
|
|
13111
|
+
* });
|
|
13112
|
+
* ```
|
|
13113
|
+
*
|
|
13038
13114
|
* @example Redemption with Pre-Validation
|
|
13039
13115
|
* ```typescript
|
|
13040
13116
|
* // Get offer details first
|
|
@@ -13058,13 +13134,16 @@ class RedemptionManager {
|
|
|
13058
13134
|
* }
|
|
13059
13135
|
* ```
|
|
13060
13136
|
*/
|
|
13061
|
-
async redeem(redemptionId) {
|
|
13062
|
-
const
|
|
13137
|
+
async redeem(redemptionId, context) {
|
|
13138
|
+
const request = context
|
|
13139
|
+
? { redemptionId, context }
|
|
13140
|
+
: { redemptionId };
|
|
13141
|
+
const result = await this.redemptionService.redeemRedemption(request);
|
|
13063
13142
|
this.events?.emitSuccess({
|
|
13064
13143
|
domain: 'redemption',
|
|
13065
13144
|
type: 'redeem_success',
|
|
13066
13145
|
userMessage: 'Reward redeemed successfully',
|
|
13067
|
-
details: { redemptionId }
|
|
13146
|
+
details: { redemptionId, hasContext: !!context }
|
|
13068
13147
|
});
|
|
13069
13148
|
return result;
|
|
13070
13149
|
}
|
|
@@ -13127,9 +13206,19 @@ class RedemptionManager {
|
|
|
13127
13206
|
* console.log(`${type}: ${count} redemptions`);
|
|
13128
13207
|
* });
|
|
13129
13208
|
* ```
|
|
13209
|
+
*
|
|
13210
|
+
* @example Filter by Status
|
|
13211
|
+
* ```typescript
|
|
13212
|
+
* import { ProcessRecordStatus } from '@explorins/pers-sdk';
|
|
13213
|
+
*
|
|
13214
|
+
* // Get only completed redemptions
|
|
13215
|
+
* const { data: completed } = await sdk.redemptions.getUserRedemptions(
|
|
13216
|
+
* { status: ProcessRecordStatus.COMPLETED }
|
|
13217
|
+
* );
|
|
13218
|
+
* ```
|
|
13130
13219
|
*/
|
|
13131
|
-
async getUserRedemptions(options, include) {
|
|
13132
|
-
return this.redemptionService.getUserRedeems(options, include);
|
|
13220
|
+
async getUserRedemptions(filters, options, include) {
|
|
13221
|
+
return this.redemptionService.getUserRedeems(filters, options, include);
|
|
13133
13222
|
}
|
|
13134
13223
|
/**
|
|
13135
13224
|
* Admin: Get all redemption redeems with filtering and enriched data
|
|
@@ -40125,10 +40214,17 @@ const useWeb3 = () => {
|
|
|
40125
40214
|
* **Basic Usage:**
|
|
40126
40215
|
* ```typescript
|
|
40127
40216
|
* import { useTokenBalances, useTokens, usePersSDK } from '@explorins/pers-sdk-react-native';
|
|
40217
|
+
* import { useState, useEffect } from 'react';
|
|
40128
40218
|
*
|
|
40129
40219
|
* function TokenBalancesScreen() {
|
|
40130
40220
|
* const { user } = usePersSDK();
|
|
40131
|
-
* const {
|
|
40221
|
+
* const { getTokens } = useTokens();
|
|
40222
|
+
* const [availableTokens, setAvailableTokens] = useState([]);
|
|
40223
|
+
*
|
|
40224
|
+
* // Load tokens on mount
|
|
40225
|
+
* useEffect(() => {
|
|
40226
|
+
* getTokens().then(result => setAvailableTokens(result.data));
|
|
40227
|
+
* }, []);
|
|
40132
40228
|
*
|
|
40133
40229
|
* // App explicitly selects which wallet to use
|
|
40134
40230
|
* const walletAddress = user?.wallets?.[0]?.address;
|
|
@@ -41408,6 +41504,63 @@ const useCampaigns = () => {
|
|
|
41408
41504
|
throw error;
|
|
41409
41505
|
}
|
|
41410
41506
|
}, [sdk, isInitialized]);
|
|
41507
|
+
/**
|
|
41508
|
+
* Claim a campaign reward with optional dynamic context
|
|
41509
|
+
*
|
|
41510
|
+
* Triggers a campaign claim for the authenticated user. The campaign must be active
|
|
41511
|
+
* and the user must meet all eligibility requirements. Supports dynamic context for
|
|
41512
|
+
* personalized NFT generation when the campaign issues ERC721 tokens.
|
|
41513
|
+
*
|
|
41514
|
+
* @param request - Campaign claim request with optional context
|
|
41515
|
+
* @param request.campaignId - ID of the campaign to claim (optional if using triggerSourceId)
|
|
41516
|
+
* @param request.triggerSourceId - ID of trigger source (QR, NFC, etc.)
|
|
41517
|
+
* @param request.context - Dynamic context for NFT personalization
|
|
41518
|
+
* @param request.metadata - Additional metadata for the claim
|
|
41519
|
+
* @param request.latitude - User's latitude for geo-validated claims
|
|
41520
|
+
* @param request.longitude - User's longitude for geo-validated claims
|
|
41521
|
+
* @returns Promise resolving to campaign claim result
|
|
41522
|
+
*
|
|
41523
|
+
* @example Basic campaign claim
|
|
41524
|
+
* ```typescript
|
|
41525
|
+
* const claim = await claimCampaign({
|
|
41526
|
+
* triggerSourceId: 'qr-code-123',
|
|
41527
|
+
* });
|
|
41528
|
+
* ```
|
|
41529
|
+
*
|
|
41530
|
+
* @example Campaign claim with dynamic context (personalized NFT)
|
|
41531
|
+
* ```typescript
|
|
41532
|
+
* import { DynamicContext } from '@explorins/pers-sdk-react-native';
|
|
41533
|
+
*
|
|
41534
|
+
* const context: DynamicContext = {
|
|
41535
|
+
* // Validity - token valid for 30 days
|
|
41536
|
+
* validityDate: new Date().toISOString(),
|
|
41537
|
+
* validityDuration: 30,
|
|
41538
|
+
*
|
|
41539
|
+
* // AI prompt context - available as {{context.xxx}} in prompts
|
|
41540
|
+
* visitorName: 'John Doe',
|
|
41541
|
+
* visitLocation: 'Grand Hotel Lobby',
|
|
41542
|
+
* membershipTier: 'Gold',
|
|
41543
|
+
* };
|
|
41544
|
+
*
|
|
41545
|
+
* const claim = await claimCampaign({
|
|
41546
|
+
* triggerSourceId: 'hotel-checkin-qr',
|
|
41547
|
+
* context,
|
|
41548
|
+
* });
|
|
41549
|
+
* ```
|
|
41550
|
+
*
|
|
41551
|
+
* @example Geo-validated claim with context
|
|
41552
|
+
* ```typescript
|
|
41553
|
+
* const claim = await claimCampaign({
|
|
41554
|
+
* triggerSourceId: 'museum-entrance-nfc',
|
|
41555
|
+
* latitude: 48.8606,
|
|
41556
|
+
* longitude: 2.3376,
|
|
41557
|
+
* context: {
|
|
41558
|
+
* visitorType: 'Adult',
|
|
41559
|
+
* ticketCategory: 'General Admission',
|
|
41560
|
+
* }
|
|
41561
|
+
* });
|
|
41562
|
+
* ```
|
|
41563
|
+
*/
|
|
41411
41564
|
const claimCampaign = react.useCallback(async (request) => {
|
|
41412
41565
|
if (!isInitialized || !sdk) {
|
|
41413
41566
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
@@ -41435,7 +41588,7 @@ const useCampaigns = () => {
|
|
|
41435
41588
|
* // Get user's claims with campaign details
|
|
41436
41589
|
* const { data: claims } = await getUserClaims({ include: ['campaign', 'business'] });
|
|
41437
41590
|
* claims.forEach(claim => {
|
|
41438
|
-
* console.log('Campaign:', claim.included?.campaign?.
|
|
41591
|
+
* console.log('Campaign:', claim.included?.campaign?.name);
|
|
41439
41592
|
* });
|
|
41440
41593
|
*
|
|
41441
41594
|
* // With pagination
|
|
@@ -41692,27 +41845,32 @@ const useRedemptions = () => {
|
|
|
41692
41845
|
}
|
|
41693
41846
|
}, [sdk, isInitialized]);
|
|
41694
41847
|
/**
|
|
41695
|
-
* Get user's redemption history with optional pagination and include relations
|
|
41848
|
+
* Get user's redemption history with optional filters, pagination and include relations
|
|
41696
41849
|
*
|
|
41850
|
+
* @param filters - Optional filters (redemptionId, status)
|
|
41697
41851
|
* @param options - Pagination options (page, limit, sortBy, sortOrder)
|
|
41698
|
-
* @param include - Relations to include: 'redemption', 'user', 'business'
|
|
41852
|
+
* @param include - Relations to include: 'redemption', 'user', 'business', 'transactions'
|
|
41699
41853
|
* @returns Promise resolving to paginated redemption history
|
|
41700
41854
|
*
|
|
41701
41855
|
* @example
|
|
41702
41856
|
* ```typescript
|
|
41703
41857
|
* // Get first page of user redemptions
|
|
41704
|
-
* const { data: redeems, pagination } = await getUserRedemptions({ page: 1, limit: 10 });
|
|
41858
|
+
* const { data: redeems, pagination } = await getUserRedemptions({}, { page: 1, limit: 10 });
|
|
41705
41859
|
* console.log(`Page ${pagination.page} of ${pagination.pages}`);
|
|
41706
41860
|
*
|
|
41861
|
+
* // Get only completed redemptions
|
|
41862
|
+
* import { ProcessRecordStatus } from '@explorins/pers-shared';
|
|
41863
|
+
* const { data: completed } = await getUserRedemptions({ status: ProcessRecordStatus.COMPLETED });
|
|
41864
|
+
*
|
|
41707
41865
|
* // Get user redemptions with full redemption details
|
|
41708
|
-
* const { data: redeems } = await getUserRedemptions({}, ['redemption', 'business']);
|
|
41866
|
+
* const { data: redeems } = await getUserRedemptions({}, {}, ['redemption', 'business']);
|
|
41709
41867
|
* redeems.forEach(redeem => {
|
|
41710
|
-
* console.log('Redemption:', redeem.included?.redemption?.
|
|
41868
|
+
* console.log('Redemption:', redeem.included?.redemption?.name);
|
|
41711
41869
|
* console.log('Business:', redeem.included?.business?.displayName);
|
|
41712
41870
|
* });
|
|
41713
41871
|
* ```
|
|
41714
41872
|
*/
|
|
41715
|
-
const getUserRedemptions = react.useCallback(async (options, include) => {
|
|
41873
|
+
const getUserRedemptions = react.useCallback(async (filters, options, include) => {
|
|
41716
41874
|
if (!isInitialized || !sdk) {
|
|
41717
41875
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
41718
41876
|
}
|
|
@@ -41721,7 +41879,7 @@ const useRedemptions = () => {
|
|
|
41721
41879
|
return { data: [], pagination: { page: 1, limit: 0, total: 0, pages: 0, hasNext: false, hasPrev: false } };
|
|
41722
41880
|
}
|
|
41723
41881
|
try {
|
|
41724
|
-
const result = await sdk.redemptions.getUserRedemptions(options, include);
|
|
41882
|
+
const result = await sdk.redemptions.getUserRedemptions(filters, options, include);
|
|
41725
41883
|
return result;
|
|
41726
41884
|
}
|
|
41727
41885
|
catch (error) {
|
|
@@ -41729,7 +41887,54 @@ const useRedemptions = () => {
|
|
|
41729
41887
|
throw error;
|
|
41730
41888
|
}
|
|
41731
41889
|
}, [sdk, isInitialized, isAuthenticated]);
|
|
41732
|
-
|
|
41890
|
+
/**
|
|
41891
|
+
* Redeem a redemption offer with optional dynamic context
|
|
41892
|
+
*
|
|
41893
|
+
* Supports dynamic context for personalized NFT generation when the redemption
|
|
41894
|
+
* issues ERC721 tokens. Context can include validity dates, AI prompt placeholders,
|
|
41895
|
+
* and custom metadata.
|
|
41896
|
+
*
|
|
41897
|
+
* @param redemptionId - ID of the redemption to redeem
|
|
41898
|
+
* @param options - Optional settings
|
|
41899
|
+
* @param options.context - Dynamic context for NFT personalization (validity dates, AI prompts)
|
|
41900
|
+
* @param options.onStatusUpdate - Callback for transaction signing status updates
|
|
41901
|
+
* @returns Promise resolving to redemption result
|
|
41902
|
+
*
|
|
41903
|
+
* @example Basic redemption
|
|
41904
|
+
* ```typescript
|
|
41905
|
+
* const result = await redeem('redemption-123');
|
|
41906
|
+
* ```
|
|
41907
|
+
*
|
|
41908
|
+
* @example Redemption with dynamic context (personalized NFT)
|
|
41909
|
+
* ```typescript
|
|
41910
|
+
* const result = await redeem('event-ticket-123', {
|
|
41911
|
+
* context: {
|
|
41912
|
+
* // Validity - token valid for event duration
|
|
41913
|
+
* validityDate: new Date().toISOString(),
|
|
41914
|
+
* validityDuration: 8, // 8 hours
|
|
41915
|
+
*
|
|
41916
|
+
* // AI prompt context - available as {{context.xxx}} in prompts
|
|
41917
|
+
* attendeeName: 'John Doe',
|
|
41918
|
+
* ticketTier: 'VIP',
|
|
41919
|
+
* seatSection: 'A12',
|
|
41920
|
+
* }
|
|
41921
|
+
* });
|
|
41922
|
+
* ```
|
|
41923
|
+
*
|
|
41924
|
+
* @example Hotel stay NFT with check-in/check-out dates
|
|
41925
|
+
* ```typescript
|
|
41926
|
+
* const result = await redeem('hotel-nft-456', {
|
|
41927
|
+
* context: {
|
|
41928
|
+
* validityDate: '2026-04-15T14:00:00Z', // Check-in
|
|
41929
|
+
* validityEndDate: '2026-04-20T11:00:00Z', // Check-out
|
|
41930
|
+
* guestName: 'Jane Smith',
|
|
41931
|
+
* roomNumber: '305',
|
|
41932
|
+
* roomType: 'Suite',
|
|
41933
|
+
* }
|
|
41934
|
+
* });
|
|
41935
|
+
* ```
|
|
41936
|
+
*/
|
|
41937
|
+
const redeem = react.useCallback(async (redemptionId, options) => {
|
|
41733
41938
|
if (!isInitialized || !sdk) {
|
|
41734
41939
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
41735
41940
|
}
|
|
@@ -41737,11 +41942,11 @@ const useRedemptions = () => {
|
|
|
41737
41942
|
throw new Error('SDK not authenticated. redeem requires authentication.');
|
|
41738
41943
|
}
|
|
41739
41944
|
try {
|
|
41740
|
-
const result = await sdk.redemptions.redeem(redemptionId);
|
|
41945
|
+
const result = await sdk.redemptions.redeem(redemptionId, options?.context);
|
|
41741
41946
|
const txToken = result.senderTransaction?.actionable?.authToken;
|
|
41742
41947
|
if (txToken && isSignerAvailable) {
|
|
41743
41948
|
try {
|
|
41744
|
-
const signingResult = await signAndSubmitTransactionWithJWT(txToken, onStatusUpdate);
|
|
41949
|
+
const signingResult = await signAndSubmitTransactionWithJWT(txToken, options?.onStatusUpdate);
|
|
41745
41950
|
if (signingResult.success) {
|
|
41746
41951
|
// Return enhanced result with signing information
|
|
41747
41952
|
return {
|