@explorins/pers-sdk-react-native 2.0.0 → 2.0.2

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/index.d.ts CHANGED
@@ -240,10 +240,24 @@ export { initializeReactNativePolyfills } from './polyfills';
240
240
  * - Business and campaign types (BusinessDTO, CampaignDTO, etc.)
241
241
  * - API request/response types for all endpoints
242
242
  * - Error types and status enums
243
+ * - Utility functions for pagination, token display, etc.
243
244
  *
244
245
  * @see {@link https://github.com/eXplorins/pers-shared} - Shared library documentation
245
246
  */
246
247
  export * from '@explorins/pers-shared';
248
+ /**
249
+ * Token utilities re-exported from token module
250
+ *
251
+ * @see {@link getMetadataFromTokenUnitResponse} - Get full metadata object from token unit
252
+ */
253
+ export { getMetadataFromTokenUnitResponse } from '@explorins/pers-sdk/token';
254
+ /**
255
+ * Shared SDK utilities re-exported from base SDK
256
+ *
257
+ * Includes helper functions for:
258
+ * - Pagination utilities (buildPaginationParams, extractData, etc.)
259
+ */
260
+ export { buildPaginationParams, extractData, extractPagination, isPaginatedResponse, normalizeToPaginated, fetchAllPages, type PaginationOptions, type PaginationWithFilters, type ListResponse } from '@explorins/pers-sdk';
247
261
  /**
248
262
  * Re-export Web3 and blockchain-related types from base SDK
249
263
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAGH,OAAO,aAAa,CAAC;AAMrB;;;;;;;;GAQG;AACH,OAAO,EACL,6BAA6B,EAC7B,KAAK,qBAAqB,EAC3B,MAAM,wCAAwC,CAAC;AAMhD;;;;;;;;;;GAUG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAEvE;;;;;;;;GAQG;AACH,OAAO,EACL,wBAAwB,GACzB,MAAM,uCAAuC,CAAC;AAM/C;;;GAGG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAMvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EACL,eAAe,EACf,UAAU,EACV,KAAK,UAAU,EACf,KAAK,cAAc,EACpB,MAAM,6BAA6B,CAAC;AAMrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FG;AACH,OAAO,EACL,OAAO,EACP,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,YAAY,EACZ,cAAc,EACd,OAAO,EACP,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,SAAS,EACV,MAAM,SAAS,CAAC;AAGjB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAGrF,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAM7F;;;;;;GAMG;AACH,OAAO,EACL,qBAAqB,EACtB,MAAM,sCAAsC,CAAC;AAM9C;;;;;;;;GAQG;AACH,OAAO,EACL,8BAA8B,EAC/B,MAAM,aAAa,CAAC;AAMrB;;;;;;;;;;;;;;;GAeG;AACH,cAAc,wBAAwB,CAAC;AAEvC;;;;;;;;;;;GAWG;AACH,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAMlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,iCAAiC,CAAC;AAEzC,YAAY,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAM/E;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAGH,OAAO,aAAa,CAAC;AAMrB;;;;;;;;GAQG;AACH,OAAO,EACL,6BAA6B,EAC7B,KAAK,qBAAqB,EAC3B,MAAM,wCAAwC,CAAC;AAMhD;;;;;;;;;;GAUG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAEvE;;;;;;;;GAQG;AACH,OAAO,EACL,wBAAwB,GACzB,MAAM,uCAAuC,CAAC;AAM/C;;;GAGG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAMvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EACL,eAAe,EACf,UAAU,EACV,KAAK,UAAU,EACf,KAAK,cAAc,EACpB,MAAM,6BAA6B,CAAC;AAMrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FG;AACH,OAAO,EACL,OAAO,EACP,SAAS,EACT,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,YAAY,EACZ,cAAc,EACd,OAAO,EACP,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,SAAS,EACV,MAAM,SAAS,CAAC;AAGjB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAGrF,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAM7F;;;;;;GAMG;AACH,OAAO,EACL,qBAAqB,EACtB,MAAM,sCAAsC,CAAC;AAM9C;;;;;;;;GAQG;AACH,OAAO,EACL,8BAA8B,EAC/B,MAAM,aAAa,CAAC;AAMrB;;;;;;;;;;;;;;;;GAgBG;AACH,cAAc,wBAAwB,CAAC;AAEvC;;;;GAIG;AACH,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAC;AAE7E;;;;;GAKG;AACH,OAAO,EAEL,qBAAqB,EACrB,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAE7B;;;;;;;;;;;GAWG;AACH,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAMlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,iCAAiC,CAAC;AAEzC,YAAY,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAM/E;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -23381,6 +23381,43 @@ function isPaginatedResponse(response) {
23381
23381
  'data' in response &&
23382
23382
  'pagination' in response);
23383
23383
  }
23384
+ /**
23385
+ * Extract data array from either array or paginated response
23386
+ * Use during hybrid backend phase to safely handle both response shapes
23387
+ *
23388
+ * @param response - Either an array or paginated response
23389
+ * @returns Data array
23390
+ *
23391
+ * @example
23392
+ * ```typescript
23393
+ * const response = await api.getItems(); // Could be T[] or PaginatedResponseDTO<T>
23394
+ * const items = extractData(response); // Always T[]
23395
+ * ```
23396
+ */
23397
+ function extractData(response) {
23398
+ if (Array.isArray(response)) {
23399
+ return response;
23400
+ }
23401
+ return (response?.data ?? []);
23402
+ }
23403
+ /**
23404
+ * Extract pagination metadata (returns null for array responses)
23405
+ *
23406
+ * @param response - Either an array or paginated response
23407
+ * @returns Pagination metadata or null
23408
+ *
23409
+ * @example
23410
+ * ```typescript
23411
+ * const response = await api.getItems();
23412
+ * const pagination = extractPagination(response);
23413
+ * if (pagination) {
23414
+ * console.log(`Total: ${pagination.total}`);
23415
+ * }
23416
+ * ```
23417
+ */
23418
+ function extractPagination(response) {
23419
+ return isPaginatedResponse(response) ? response.pagination : null;
23420
+ }
23384
23421
  /**
23385
23422
  * Normalize any list response to PaginatedResponseDTO format
23386
23423
  * Converts array responses to paginated format during hybrid backend phase
@@ -23419,6 +23456,39 @@ function normalizeToPaginated(response) {
23419
23456
  }
23420
23457
  };
23421
23458
  }
23459
+ /**
23460
+ * Fetch all pages automatically (useful for infinite scroll or complete datasets)
23461
+ *
23462
+ * ⚠️ WARNING: Use with caution on large datasets. This will make multiple API calls
23463
+ * and load all items into memory. Consider using pagination UI instead.
23464
+ *
23465
+ * @param fetchFn - Function that fetches a page (must return PaginatedResponseDTO)
23466
+ * @param limit - Items per page (default: 50)
23467
+ * @param maxPages - Safety limit to prevent infinite loops (default: 100)
23468
+ * @returns All items from all pages
23469
+ *
23470
+ * @example
23471
+ * ```typescript
23472
+ * // Fetch all campaigns (use with caution!)
23473
+ * const allCampaigns = await fetchAllPages(
23474
+ * (page, limit) => sdk.campaigns.getCampaigns({ page, limit }),
23475
+ * 50, // items per page
23476
+ * 100 // max 100 pages (5000 items)
23477
+ * );
23478
+ * ```
23479
+ */
23480
+ async function fetchAllPages(fetchFn, limit = 50, maxPages = 100) {
23481
+ const allItems = [];
23482
+ let page = 1;
23483
+ let hasMore = true;
23484
+ while (hasMore && page <= maxPages) {
23485
+ const response = await fetchFn(page, limit);
23486
+ allItems.push(...(response.data || []));
23487
+ hasMore = response.pagination.hasNext;
23488
+ page++;
23489
+ }
23490
+ return allItems;
23491
+ }
23422
23492
 
23423
23493
  /**
23424
23494
  * Platform-Agnostic User API Client
@@ -33483,10 +33553,16 @@ class Web3Manager {
33483
33553
  const ownedTokens = token.type === NativeTokenTypes.ERC721
33484
33554
  ? collection.tokens
33485
33555
  : collection.tokens.filter(t => t.hasBalance);
33556
+ // Calculate total owned:
33557
+ // - ERC-1155: sum balances (can own multiple copies of same tokenId)
33558
+ // - ERC-721: count unique tokens (each token is unique, balance always 1)
33559
+ const totalOwned = token.type === NativeTokenTypes.ERC1155
33560
+ ? ownedTokens.reduce((sum, t) => sum + (t.balance || 0), 0)
33561
+ : ownedTokens.length;
33486
33562
  return {
33487
33563
  token,
33488
33564
  ownedTokens,
33489
- totalOwned: ownedTokens.length
33565
+ totalOwned
33490
33566
  };
33491
33567
  }
33492
33568
  /**
@@ -37452,6 +37528,69 @@ const useEvents = () => {
37452
37528
  };
37453
37529
  };
37454
37530
 
37531
+ // ==========================================
37532
+ // TOKEN UTILITY FUNCTIONS
37533
+ // ==========================================
37534
+ /**
37535
+ * Get metadata from a token unit response
37536
+ * Handles metadata-based tokens (ERC-1155 with metadata array)
37537
+ *
37538
+ * For metadata-based tokens:
37539
+ * - Returns the metadata object from token.metadata array
37540
+ * - Uses provided incrementalId or tokenMetadataIncrementalId from tokenUnit
37541
+ * - Defaults to index 0 if no incrementalId specified
37542
+ *
37543
+ * For standard tokens (no metadata):
37544
+ * - Returns null
37545
+ *
37546
+ * @param tokenUnit - The token unit from campaign or balance
37547
+ * @param incrementalId - Optional metadata index to use (overrides tokenUnit.tokenMetadataIncrementalId)
37548
+ * @returns Token metadata object or null
37549
+ *
37550
+ * @example
37551
+ * ```typescript
37552
+ * // Get metadata using tokenUnit's incrementalId
37553
+ * const tokenUnit = {
37554
+ * tokenMetadataIncrementalId: 3,
37555
+ * token: {
37556
+ * metadata: [
37557
+ * { name: 'Bronze Pass', imageUrl: '...' },
37558
+ * { name: 'Silver Pass', imageUrl: '...' },
37559
+ * { name: 'Gold Pass', imageUrl: '...' }
37560
+ * ]
37561
+ * }
37562
+ * };
37563
+ * const metadata = getMetadataFromTokenUnitResponse(tokenUnit);
37564
+ * // Returns: { name: 'Bronze Pass', imageUrl: '...' } (index 0 - default)
37565
+ *
37566
+ * // Override incrementalId
37567
+ * const metadata2 = getMetadataFromTokenUnitResponse(tokenUnit, 2);
37568
+ * // Returns: { name: 'Gold Pass', imageUrl: '...' } (index 2)
37569
+ *
37570
+ * // Standard token (no metadata)
37571
+ * const tokenUnit2 = {
37572
+ * token: { symbol: 'VQP', name: 'Visit Qatar Points' }
37573
+ * };
37574
+ * const metadata3 = getMetadataFromTokenUnitResponse(tokenUnit2);
37575
+ * // Returns: null
37576
+ *
37577
+ * // Display name with fallback
37578
+ * const displayName = metadata?.name || tokenUnit.token?.symbol || 'Reward';
37579
+ *
37580
+ * // Display image
37581
+ * const imageUrl = metadata?.imageUrl;
37582
+ * ```
37583
+ */
37584
+ function getMetadataFromTokenUnitResponse(tokenUnit, incrementalId) {
37585
+ // If no metadata array exists, return null
37586
+ if (!tokenUnit.token?.metadata || tokenUnit.token.metadata.length === 0) {
37587
+ return null;
37588
+ }
37589
+ // Use provided incrementalId, or tokenUnit's incrementalId, or default to 0
37590
+ const index = incrementalId ?? tokenUnit.tokenMetadataIncrementalId ?? 0;
37591
+ return tokenUnit.token.metadata[index] ?? null;
37592
+ }
37593
+
37455
37594
  // ============================================================================
37456
37595
  // SHARED HELPERS (internal)
37457
37596
  // ============================================================================
@@ -37764,14 +37903,21 @@ exports.buildBurnRequest = buildBurnRequest;
37764
37903
  exports.buildMintRequest = buildMintRequest;
37765
37904
  exports.buildPOSBurnRequest = buildPOSBurnRequest;
37766
37905
  exports.buildPOSTransferRequest = buildPOSTransferRequest;
37906
+ exports.buildPaginationParams = buildPaginationParams;
37767
37907
  exports.buildSubmissionRequest = buildSubmissionRequest;
37768
37908
  exports.buildTransferRequest = buildTransferRequest;
37769
37909
  exports.createReactNativeAuthProvider = createReactNativeAuthProvider;
37770
37910
  exports.createUserIdentifierObject = createUserIdentifierObject;
37771
37911
  exports.detectIdentifierType = detectIdentifierType;
37912
+ exports.extractData = extractData;
37913
+ exports.extractPagination = extractPagination;
37914
+ exports.fetchAllPages = fetchAllPages;
37915
+ exports.getMetadataFromTokenUnitResponse = getMetadataFromTokenUnitResponse;
37772
37916
  exports.hasMinimumRole = hasMinimumRole;
37773
37917
  exports.initializeReactNativePolyfills = initializeReactNativePolyfills;
37918
+ exports.isPaginatedResponse = isPaginatedResponse;
37774
37919
  exports.isUserIdentifierObject = isUserIdentifierObject;
37920
+ exports.normalizeToPaginated = normalizeToPaginated;
37775
37921
  exports.registerIdentifierType = registerIdentifierType;
37776
37922
  exports.testnetPrefix = testnetPrefix;
37777
37923
  exports.testnetShortPrefix = testnetShortPrefix;