@explorins/pers-sdk-react-native 2.3.5 → 2.3.7
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/useTransactions.d.ts.map +1 -1
- package/dist/hooks/useTransactions.js +13 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +308 -24
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/hooks/useTransactions.ts +15 -6
- package/src/index.ts +4 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTransactions.d.ts","sourceRoot":"","sources":["../../src/hooks/useTransactions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,KAAK,EACV,qBAAqB,EACrB,6BAA6B,EAC7B,cAAc,EACd,+BAA+B,EAC/B,oBAAoB,EACpB,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"useTransactions.d.ts","sourceRoot":"","sources":["../../src/hooks/useTransactions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,KAAK,EACV,qBAAqB,EACrB,6BAA6B,EAC7B,cAAc,EACd,+BAA+B,EAC/B,oBAAoB,EACpB,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAI/E,YAAY,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,eAAe;iCAgC4B,qBAAqB,mBAAmB,gBAAgB,KAAG,QAAQ,6BAA6B,CAAC;wCA2EtI,MAAM,YACX,0BAA0B,EAAE,KACrC,QAAQ,cAAc,GAAG,IAAI,CAAC;0CAmDrB,uBAAuB,KAChC,QAAQ,qBAAqB,cAAc,CAAC,CAAC;wCAyCrC,+BAA+B,GAAG;QACzC,OAAO,CAAC,EAAE,0BAA0B,EAAE,CAAC;KACxC,KACA,QAAQ,qBAAqB,cAAc,CAAC,CAAC;iCAcI,QAAQ,IAAI,CAAC;;;;CAyBlE,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useCallback } from 'react';
|
|
2
2
|
import { usePersSDK } from '../providers/PersSDKProvider';
|
|
3
3
|
import { useTransactionSigner } from './useTransactionSigner';
|
|
4
|
+
import { needsSubmission } from '@explorins/pers-sdk/transaction';
|
|
4
5
|
/**
|
|
5
6
|
* React hook for transaction operations in the PERS SDK
|
|
6
7
|
*
|
|
@@ -73,15 +74,22 @@ export const useTransactions = () => {
|
|
|
73
74
|
}
|
|
74
75
|
try {
|
|
75
76
|
const result = await sdk.transactions.createTransaction(request);
|
|
76
|
-
//
|
|
77
|
+
// If backend already signed custodially, return as-is so caller can build QR
|
|
78
|
+
// from result.signatureData directly (no client signing needed)
|
|
79
|
+
if (needsSubmission(result)) {
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
// If client signer is unavailable, return as-is so caller can fall back to
|
|
83
|
+
// result.actionable.actionUrl (external signing URL) if present
|
|
84
|
+
if (!isSignerAvailable) {
|
|
85
|
+
console.warn('[useTransactions] Transaction signer not available, returning result for caller to handle');
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
// Check if transaction requires client signing (contains actionable authToken)
|
|
77
89
|
// Type assertion needed as TransactionRequestResponseDTO type may not include all dynamic properties
|
|
78
90
|
const txToken = result?.actionable?.authToken;
|
|
79
91
|
if (txToken) {
|
|
80
92
|
try {
|
|
81
|
-
if (!isSignerAvailable) {
|
|
82
|
-
console.warn('[useTransactions] Transaction signer not available, skipping automatic signing');
|
|
83
|
-
return result;
|
|
84
|
-
}
|
|
85
93
|
// Automatically sign the transaction using the authToken
|
|
86
94
|
const signingResult = await signAndSubmitTransactionWithJWT(txToken, onStatusUpdate);
|
|
87
95
|
if (signingResult.success) {
|
package/dist/index.d.ts
CHANGED
|
@@ -325,7 +325,7 @@ export type { TokenBalanceRequest, TokenBalance, TokenMetadata, TokenCollection,
|
|
|
325
325
|
* @see {@link buildPOSBurnRequest} - Create POS burn requests (business submits burn on behalf of user)
|
|
326
326
|
* @see {@link buildSubmissionRequest} - Create submission requests from QR/signature data
|
|
327
327
|
*/
|
|
328
|
-
export { buildMintRequest, buildBurnRequest, buildTransferRequest, buildPOSTransferRequest, buildPOSBurnRequest, buildSubmissionRequest, ClientTransactionType, extractDeadlineFromSigningData, buildPendingTransactionData } from '@explorins/pers-sdk/transaction';
|
|
328
|
+
export { buildMintRequest, buildBurnRequest, buildTransferRequest, buildPOSTransferRequest, buildPOSBurnRequest, buildSubmissionRequest, ClientTransactionType, extractDeadlineFromSigningData, buildPendingTransactionData, needsSubmission, needsExternalSigning, getSigningUrl } from '@explorins/pers-sdk/transaction';
|
|
329
329
|
export type { POSAuthorizationOptions, PendingTransactionParams } from '@explorins/pers-sdk/transaction';
|
|
330
330
|
/**
|
|
331
331
|
* Structured error handling for PERS SDK
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4317,14 +4317,15 @@ function computeBookingStatus(checkInDate, checkOutDate, referenceDate = new Dat
|
|
|
4317
4317
|
*
|
|
4318
4318
|
* ## Example Scenarios
|
|
4319
4319
|
*
|
|
4320
|
-
* | Scenario | channel |
|
|
4321
|
-
*
|
|
4322
|
-
* |
|
|
4323
|
-
* | Mobile
|
|
4324
|
-
* |
|
|
4325
|
-
* |
|
|
4326
|
-
* |
|
|
4327
|
-
* |
|
|
4320
|
+
* | Scenario | channel | platform.deviceType | platform.app/browser | Notes |
|
|
4321
|
+
* |-----------------------------|-----------|---------------------|----------------------|-------|
|
|
4322
|
+
* | Desktop browser | `web` | `desktop` | `browser: Chrome` | - |
|
|
4323
|
+
* | Mobile browser (Safari) | `web` | `phone` | `browser: Safari` | NOT 'mobile' channel |
|
|
4324
|
+
* | Native iOS app | `mobile` | `phone` | `app: MyApp` | Requires x-source-channel |
|
|
4325
|
+
* | Native Android app | `mobile` | `phone` | `app: MyApp` | Requires x-source-channel |
|
|
4326
|
+
* | Partner API integration | `api` | - | - | - |
|
|
4327
|
+
* | Admin creates user | `admin` | - | - | - |
|
|
4328
|
+
* | Webhook from Stripe | `webhook` | - | - | - |
|
|
4328
4329
|
*
|
|
4329
4330
|
* @example
|
|
4330
4331
|
* // Simple usage - just channel
|
|
@@ -4341,10 +4342,14 @@ function computeBookingStatus(checkInDate, checkOutDate, referenceDate = new Dat
|
|
|
4341
4342
|
*/
|
|
4342
4343
|
/**
|
|
4343
4344
|
* Primary ingestion channels for data source tracking.
|
|
4345
|
+
*
|
|
4346
|
+
* IMPORTANT:
|
|
4347
|
+
* - 'web' = ANY browser (desktop OR mobile) - use platform.deviceType to distinguish
|
|
4348
|
+
* - 'mobile' = Native apps ONLY (iOS/Android) - must include platform.app
|
|
4344
4349
|
*/
|
|
4345
4350
|
const DATA_SOURCE_CHANNELS = [
|
|
4346
|
-
'web', // Web
|
|
4347
|
-
'mobile', //
|
|
4351
|
+
'web', // Web browser (desktop or mobile) - check platform.deviceType
|
|
4352
|
+
'mobile', // Native mobile app ONLY (iOS/Android) - requires platform.app
|
|
4348
4353
|
'api', // Direct API integration
|
|
4349
4354
|
'admin', // Admin panel/back-office
|
|
4350
4355
|
'system', // System-generated (automated)
|
|
@@ -4472,17 +4477,114 @@ function detectSourceFromReferrer(referrer) {
|
|
|
4472
4477
|
return undefined;
|
|
4473
4478
|
}
|
|
4474
4479
|
}
|
|
4480
|
+
/**
|
|
4481
|
+
* Parse User-Agent string for platform information (fallback when SDK doesn't provide).
|
|
4482
|
+
*
|
|
4483
|
+
* Extracts OS, browser, device type from standard User-Agent patterns.
|
|
4484
|
+
* This is best-effort - SDK headers are authoritative.
|
|
4485
|
+
*
|
|
4486
|
+
* @param userAgent - User-Agent header value
|
|
4487
|
+
* @returns Platform object with detected fields, or undefined if unparseable
|
|
4488
|
+
*
|
|
4489
|
+
* @example
|
|
4490
|
+
* parseUserAgentForPlatform('Mozilla/5.0 (iPhone; CPU iPhone OS 17_4...')
|
|
4491
|
+
* // { os: 'iOS', osVersion: '17.4', browser: 'Safari', deviceType: 'phone' }
|
|
4492
|
+
*/
|
|
4493
|
+
function parseUserAgentForPlatform(userAgent) {
|
|
4494
|
+
if (!userAgent)
|
|
4495
|
+
return undefined;
|
|
4496
|
+
const ua = userAgent;
|
|
4497
|
+
const platform = {};
|
|
4498
|
+
// Detect OS and device type
|
|
4499
|
+
if (/iPhone|iPod/i.test(ua)) {
|
|
4500
|
+
platform.os = 'iOS';
|
|
4501
|
+
const match = ua.match(/OS (\d+)[_\.](\d+)/);
|
|
4502
|
+
if (match)
|
|
4503
|
+
platform.osVersion = `${match[1]}.${match[2]}`;
|
|
4504
|
+
platform.deviceType = 'phone';
|
|
4505
|
+
}
|
|
4506
|
+
else if (/iPad/i.test(ua)) {
|
|
4507
|
+
platform.os = 'iOS';
|
|
4508
|
+
const match = ua.match(/OS (\d+)[_\.](\d+)/);
|
|
4509
|
+
if (match)
|
|
4510
|
+
platform.osVersion = `${match[1]}.${match[2]}`;
|
|
4511
|
+
platform.deviceType = 'tablet';
|
|
4512
|
+
}
|
|
4513
|
+
else if (/Android/i.test(ua)) {
|
|
4514
|
+
platform.os = 'Android';
|
|
4515
|
+
const match = ua.match(/Android ([\d\.]+)/);
|
|
4516
|
+
if (match)
|
|
4517
|
+
platform.osVersion = match[1];
|
|
4518
|
+
platform.deviceType = /Mobile/i.test(ua) ? 'phone' : 'tablet';
|
|
4519
|
+
}
|
|
4520
|
+
else if (/Windows NT/i.test(ua)) {
|
|
4521
|
+
platform.os = 'Windows';
|
|
4522
|
+
const match = ua.match(/Windows NT ([\d\.]+)/);
|
|
4523
|
+
if (match)
|
|
4524
|
+
platform.osVersion = match[1];
|
|
4525
|
+
platform.deviceType = 'desktop';
|
|
4526
|
+
}
|
|
4527
|
+
else if (/Macintosh|Mac OS X/i.test(ua)) {
|
|
4528
|
+
platform.os = 'macOS';
|
|
4529
|
+
const match = ua.match(/Mac OS X ([\d_]+)/);
|
|
4530
|
+
if (match)
|
|
4531
|
+
platform.osVersion = match[1].replace(/_/g, '.');
|
|
4532
|
+
platform.deviceType = 'desktop';
|
|
4533
|
+
}
|
|
4534
|
+
else if (/Linux/i.test(ua) && !/Android/i.test(ua)) {
|
|
4535
|
+
platform.os = 'Linux';
|
|
4536
|
+
platform.deviceType = 'desktop';
|
|
4537
|
+
}
|
|
4538
|
+
// Detect browser (web channel)
|
|
4539
|
+
if (/Edg\//i.test(ua)) {
|
|
4540
|
+
platform.browser = 'Edge';
|
|
4541
|
+
const match = ua.match(/Edg\/([\d\.]+)/);
|
|
4542
|
+
if (match)
|
|
4543
|
+
platform.browserVersion = match[1];
|
|
4544
|
+
}
|
|
4545
|
+
else if (/Chrome\//i.test(ua) && !/Edg/i.test(ua)) {
|
|
4546
|
+
platform.browser = 'Chrome';
|
|
4547
|
+
const match = ua.match(/Chrome\/([\d\.]+)/);
|
|
4548
|
+
if (match)
|
|
4549
|
+
platform.browserVersion = match[1];
|
|
4550
|
+
}
|
|
4551
|
+
else if (/Safari\//i.test(ua) && !/Chrome/i.test(ua)) {
|
|
4552
|
+
platform.browser = 'Safari';
|
|
4553
|
+
const match = ua.match(/Version\/([\d\.]+)/);
|
|
4554
|
+
if (match)
|
|
4555
|
+
platform.browserVersion = match[1];
|
|
4556
|
+
}
|
|
4557
|
+
else if (/Firefox\//i.test(ua)) {
|
|
4558
|
+
platform.browser = 'Firefox';
|
|
4559
|
+
const match = ua.match(/Firefox\/([\d\.]+)/);
|
|
4560
|
+
if (match)
|
|
4561
|
+
platform.browserVersion = match[1];
|
|
4562
|
+
}
|
|
4563
|
+
else if (/Opera|OPR\//i.test(ua)) {
|
|
4564
|
+
platform.browser = 'Opera';
|
|
4565
|
+
const match = ua.match(/(?:Opera|OPR)\/([\d\.]+)/);
|
|
4566
|
+
if (match)
|
|
4567
|
+
platform.browserVersion = match[1];
|
|
4568
|
+
}
|
|
4569
|
+
return Object.keys(platform).length > 0 ? platform : undefined;
|
|
4570
|
+
}
|
|
4475
4571
|
/**
|
|
4476
4572
|
* Auto-detect channel from User-Agent string.
|
|
4477
4573
|
*
|
|
4574
|
+
* IMPORTANT DESIGN:
|
|
4575
|
+
* - Mobile browsers (Safari on iPhone, Chrome on Android) → 'web' (NOT 'mobile')
|
|
4576
|
+
* - Native apps MUST send explicit x-source-channel: mobile header
|
|
4577
|
+
* - Use platform.deviceType to distinguish mobile web from desktop web
|
|
4578
|
+
*
|
|
4478
4579
|
* @param userAgent - User-Agent header value
|
|
4479
4580
|
* @param path - Optional request path for webhook detection
|
|
4480
4581
|
* @returns Detected channel
|
|
4481
4582
|
*
|
|
4482
4583
|
* @example
|
|
4483
|
-
* detectChannelFromUserAgent('Mozilla/5.0 (iPhone; ...)') // 'mobile
|
|
4484
|
-
* detectChannelFromUserAgent('Mozilla/5.0 (Windows NT...)') // 'web'
|
|
4584
|
+
* detectChannelFromUserAgent('Mozilla/5.0 (iPhone; ...) Safari') // 'web' (mobile browser)
|
|
4585
|
+
* detectChannelFromUserAgent('Mozilla/5.0 (Windows NT...)') // 'web' (desktop browser)
|
|
4485
4586
|
* detectChannelFromUserAgent('', '/webhook/stripe') // 'webhook'
|
|
4587
|
+
* detectChannelFromUserAgent('MyApp/1.0') // 'unknown' (native app without header)
|
|
4486
4588
|
*/
|
|
4487
4589
|
function detectChannelFromUserAgent(userAgent, path) {
|
|
4488
4590
|
// Check for webhook paths
|
|
@@ -4490,16 +4592,18 @@ function detectChannelFromUserAgent(userAgent, path) {
|
|
|
4490
4592
|
return 'webhook';
|
|
4491
4593
|
}
|
|
4492
4594
|
const ua = (userAgent || '').toLowerCase();
|
|
4493
|
-
// Check for mobile user-agents
|
|
4494
|
-
if (/mobile|android|iphone|ipad|ipod|blackberry|windows phone/i.test(ua)) {
|
|
4495
|
-
return 'mobile';
|
|
4496
|
-
}
|
|
4497
4595
|
// Check for bot/crawler patterns (system)
|
|
4498
4596
|
if (/bot|crawler|spider|scraper|curl|wget|python|node-fetch|axios/i.test(ua)) {
|
|
4499
4597
|
return 'api';
|
|
4500
4598
|
}
|
|
4501
|
-
//
|
|
4502
|
-
|
|
4599
|
+
// Check for ANY browser pattern (desktop OR mobile)
|
|
4600
|
+
// Mobile browsers are 'web' channel - use platform.deviceType to distinguish
|
|
4601
|
+
if (ua && /mozilla|chrome|safari|firefox|edge|opera|msie|trident/i.test(ua)) {
|
|
4602
|
+
return 'web';
|
|
4603
|
+
}
|
|
4604
|
+
// Unknown: Native apps MUST send x-source-channel: mobile header
|
|
4605
|
+
// If we see 'unknown', it means SDK integration is incomplete
|
|
4606
|
+
return 'unknown';
|
|
4503
4607
|
}
|
|
4504
4608
|
/**
|
|
4505
4609
|
* Parse UTM parameters from a URL (deep link, referrer, etc.).
|
|
@@ -6347,6 +6451,43 @@ class TokenApi {
|
|
|
6347
6451
|
async deleteTokenMetadata(metadataId) {
|
|
6348
6452
|
return this.apiClient.delete(`${this.basePath}/metadata/${metadataId}`);
|
|
6349
6453
|
}
|
|
6454
|
+
// ==========================================
|
|
6455
|
+
// 📊 CSV EXPORT
|
|
6456
|
+
// ==========================================
|
|
6457
|
+
/**
|
|
6458
|
+
* ADMIN: Export token metadata to CSV
|
|
6459
|
+
*
|
|
6460
|
+
* Returns a CSV file with all token metadata for the tenant.
|
|
6461
|
+
* Supports date range filtering.
|
|
6462
|
+
*
|
|
6463
|
+
* Endpoint: GET /tokens/metadata/export/csv
|
|
6464
|
+
* Auth: @TenantAdmin()
|
|
6465
|
+
*
|
|
6466
|
+
* @param options - Export options (dateFrom, dateTo)
|
|
6467
|
+
* @returns CSV blob
|
|
6468
|
+
*
|
|
6469
|
+
* @example
|
|
6470
|
+
* ```typescript
|
|
6471
|
+
* // Export all token metadata
|
|
6472
|
+
* const csvBlob = await tokenApi.exportMetadataCSV();
|
|
6473
|
+
*
|
|
6474
|
+
* // Export metadata created in date range
|
|
6475
|
+
* const csvBlob = await tokenApi.exportMetadataCSV({
|
|
6476
|
+
* dateFrom: '2026-01-01',
|
|
6477
|
+
* dateTo: '2026-06-30'
|
|
6478
|
+
* });
|
|
6479
|
+
* ```
|
|
6480
|
+
*/
|
|
6481
|
+
async exportMetadataCSV(options) {
|
|
6482
|
+
const params = new URLSearchParams();
|
|
6483
|
+
if (options?.dateFrom)
|
|
6484
|
+
params.append('dateFrom', options.dateFrom);
|
|
6485
|
+
if (options?.dateTo)
|
|
6486
|
+
params.append('dateTo', options.dateTo);
|
|
6487
|
+
const queryString = params.toString();
|
|
6488
|
+
const url = `${this.basePath}/metadata/export/csv${queryString ? `?${queryString}` : ''}`;
|
|
6489
|
+
return this.apiClient.get(url, 'blob');
|
|
6490
|
+
}
|
|
6350
6491
|
}
|
|
6351
6492
|
|
|
6352
6493
|
/**
|
|
@@ -6519,6 +6660,22 @@ class TokenService {
|
|
|
6519
6660
|
async deleteTokenMetadata(metadataId) {
|
|
6520
6661
|
return this.tokenApi.deleteTokenMetadata(metadataId);
|
|
6521
6662
|
}
|
|
6663
|
+
// ==========================================
|
|
6664
|
+
// 📊 CSV EXPORT
|
|
6665
|
+
// ==========================================
|
|
6666
|
+
/**
|
|
6667
|
+
* ADMIN: Export token metadata to CSV
|
|
6668
|
+
*
|
|
6669
|
+
* Returns a CSV file containing all token metadata for the tenant.
|
|
6670
|
+
* Supports date range filtering.
|
|
6671
|
+
*
|
|
6672
|
+
* @param options - Export options (dateFrom, dateTo)
|
|
6673
|
+
* @returns Promise resolving to CSV blob
|
|
6674
|
+
* @throws {PersApiError} When not authenticated as tenant admin
|
|
6675
|
+
*/
|
|
6676
|
+
async exportMetadataCSV(options) {
|
|
6677
|
+
return this.tokenApi.exportMetadataCSV(options);
|
|
6678
|
+
}
|
|
6522
6679
|
}
|
|
6523
6680
|
|
|
6524
6681
|
/**
|
|
@@ -6734,6 +6891,55 @@ class BusinessApi {
|
|
|
6734
6891
|
async toggleBusinessStatus(id, dto) {
|
|
6735
6892
|
return this.apiClient.put(`${this.basePath}/${id}/status`, dto);
|
|
6736
6893
|
}
|
|
6894
|
+
/**
|
|
6895
|
+
* ADMIN: Generate new business API key (CURRENTLY DISABLED)
|
|
6896
|
+
*
|
|
6897
|
+
* NOTE: This endpoint is commented out in the backend controller.
|
|
6898
|
+
* Uncomment the controller method first before using this.
|
|
6899
|
+
*
|
|
6900
|
+
* Endpoint: PUT /businesses/{id}/api-key
|
|
6901
|
+
* Auth: @TenantAdmin()
|
|
6902
|
+
*/
|
|
6903
|
+
// async generateNewBusinessApiKey(id: string): Promise<string> {
|
|
6904
|
+
// return this.apiClient.put<string>(`${this.basePath}/${id}/api-key`, {});
|
|
6905
|
+
// }
|
|
6906
|
+
// ==========================================
|
|
6907
|
+
// 📊 CSV EXPORT
|
|
6908
|
+
// ==========================================
|
|
6909
|
+
/**
|
|
6910
|
+
* ADMIN: Export businesses to CSV
|
|
6911
|
+
*
|
|
6912
|
+
* Returns a CSV file with all business data for the tenant.
|
|
6913
|
+
* Supports date range filtering.
|
|
6914
|
+
*
|
|
6915
|
+
* Endpoint: GET /businesses/export/csv
|
|
6916
|
+
* Auth: @TenantAdmin()
|
|
6917
|
+
*
|
|
6918
|
+
* @param options - Export options (dateFrom, dateTo)
|
|
6919
|
+
* @returns CSV blob
|
|
6920
|
+
*
|
|
6921
|
+
* @example
|
|
6922
|
+
* ```typescript
|
|
6923
|
+
* // Export all businesses
|
|
6924
|
+
* const csvBlob = await businessApi.exportCSV();
|
|
6925
|
+
*
|
|
6926
|
+
* // Export businesses created in date range
|
|
6927
|
+
* const csvBlob = await businessApi.exportCSV({
|
|
6928
|
+
* dateFrom: '2026-01-01',
|
|
6929
|
+
* dateTo: '2026-06-30'
|
|
6930
|
+
* });
|
|
6931
|
+
* ```
|
|
6932
|
+
*/
|
|
6933
|
+
async exportCSV(options) {
|
|
6934
|
+
const params = new URLSearchParams();
|
|
6935
|
+
if (options?.dateFrom)
|
|
6936
|
+
params.append('dateFrom', options.dateFrom);
|
|
6937
|
+
if (options?.dateTo)
|
|
6938
|
+
params.append('dateTo', options.dateTo);
|
|
6939
|
+
const queryString = params.toString();
|
|
6940
|
+
const url = `${this.basePath}/export/csv${queryString ? `?${queryString}` : ''}`;
|
|
6941
|
+
return this.apiClient.get(url, 'blob');
|
|
6942
|
+
}
|
|
6737
6943
|
}
|
|
6738
6944
|
|
|
6739
6945
|
/**
|
|
@@ -12121,7 +12327,7 @@ class DefaultAuthProvider {
|
|
|
12121
12327
|
/** SDK package name */
|
|
12122
12328
|
const SDK_NAME = "@explorins/pers-sdk";
|
|
12123
12329
|
/** SDK version - injected from package.json at build time */
|
|
12124
|
-
const SDK_VERSION = "2.3.
|
|
12330
|
+
const SDK_VERSION = "2.3.12";
|
|
12125
12331
|
/** Full SDK identifier for headers */
|
|
12126
12332
|
const SDK_USER_AGENT = `${SDK_NAME}/${SDK_VERSION}`;
|
|
12127
12333
|
|
|
@@ -14427,6 +14633,41 @@ class TokenManager {
|
|
|
14427
14633
|
getTokenService() {
|
|
14428
14634
|
return this.tokenService;
|
|
14429
14635
|
}
|
|
14636
|
+
// ==========================================
|
|
14637
|
+
// 📊 CSV EXPORT
|
|
14638
|
+
// ==========================================
|
|
14639
|
+
/**
|
|
14640
|
+
* Admin: Export token metadata to CSV
|
|
14641
|
+
*
|
|
14642
|
+
* Returns a CSV file with all token metadata (rewards/stamps) for the tenant.
|
|
14643
|
+
* Supports date range filtering.
|
|
14644
|
+
*
|
|
14645
|
+
* @param options - Export options (dateFrom, dateTo)
|
|
14646
|
+
* @returns Promise resolving to CSV blob
|
|
14647
|
+
* @throws {PersApiError} When not authenticated as tenant admin
|
|
14648
|
+
*
|
|
14649
|
+
* @example
|
|
14650
|
+
* ```typescript
|
|
14651
|
+
* // Export all token metadata
|
|
14652
|
+
* const csvBlob = await sdk.tokens.exportMetadataCSV();
|
|
14653
|
+
*
|
|
14654
|
+
* // Export metadata created in date range
|
|
14655
|
+
* const csvBlob = await sdk.tokens.exportMetadataCSV({
|
|
14656
|
+
* dateFrom: '2026-01-01',
|
|
14657
|
+
* dateTo: '2026-06-30'
|
|
14658
|
+
* });
|
|
14659
|
+
*
|
|
14660
|
+
* // Download the CSV
|
|
14661
|
+
* const url = URL.createObjectURL(csvBlob);
|
|
14662
|
+
* const a = document.createElement('a');
|
|
14663
|
+
* a.href = url;
|
|
14664
|
+
* a.download = 'token-metadata.csv';
|
|
14665
|
+
* a.click();
|
|
14666
|
+
* ```
|
|
14667
|
+
*/
|
|
14668
|
+
async exportMetadataCSV(options) {
|
|
14669
|
+
return this.tokenService.exportMetadataCSV(options);
|
|
14670
|
+
}
|
|
14430
14671
|
}
|
|
14431
14672
|
|
|
14432
14673
|
/**
|
|
@@ -15068,6 +15309,41 @@ class BusinessManager {
|
|
|
15068
15309
|
getMembershipService() {
|
|
15069
15310
|
return this.membershipService;
|
|
15070
15311
|
}
|
|
15312
|
+
// ==========================================
|
|
15313
|
+
// 📊 CSV EXPORT
|
|
15314
|
+
// ==========================================
|
|
15315
|
+
/**
|
|
15316
|
+
* Admin: Export businesses to CSV
|
|
15317
|
+
*
|
|
15318
|
+
* Returns a CSV file with all business data for the tenant.
|
|
15319
|
+
* Supports date range filtering.
|
|
15320
|
+
*
|
|
15321
|
+
* @param options - Export options (dateFrom, dateTo)
|
|
15322
|
+
* @returns Promise resolving to CSV blob
|
|
15323
|
+
* @throws {PersApiError} When not authenticated as tenant admin
|
|
15324
|
+
*
|
|
15325
|
+
* @example
|
|
15326
|
+
* ```typescript
|
|
15327
|
+
* // Export all businesses
|
|
15328
|
+
* const csvBlob = await sdk.business.exportCSV();
|
|
15329
|
+
*
|
|
15330
|
+
* // Export businesses created in date range
|
|
15331
|
+
* const csvBlob = await sdk.business.exportCSV({
|
|
15332
|
+
* dateFrom: '2026-01-01',
|
|
15333
|
+
* dateTo: '2026-06-30'
|
|
15334
|
+
* });
|
|
15335
|
+
*
|
|
15336
|
+
* // Download the CSV
|
|
15337
|
+
* const url = URL.createObjectURL(csvBlob);
|
|
15338
|
+
* const a = document.createElement('a');
|
|
15339
|
+
* a.href = url;
|
|
15340
|
+
* a.download = 'businesses.csv';
|
|
15341
|
+
* a.click();
|
|
15342
|
+
* ```
|
|
15343
|
+
*/
|
|
15344
|
+
async exportCSV(options) {
|
|
15345
|
+
return this.businessApi.exportCSV(options);
|
|
15346
|
+
}
|
|
15071
15347
|
}
|
|
15072
15348
|
|
|
15073
15349
|
/**
|
|
@@ -47572,15 +47848,22 @@ const useTransactions = () => {
|
|
|
47572
47848
|
}
|
|
47573
47849
|
try {
|
|
47574
47850
|
const result = await sdk.transactions.createTransaction(request);
|
|
47575
|
-
//
|
|
47851
|
+
// If backend already signed custodially, return as-is so caller can build QR
|
|
47852
|
+
// from result.signatureData directly (no client signing needed)
|
|
47853
|
+
if (needsSubmission(result)) {
|
|
47854
|
+
return result;
|
|
47855
|
+
}
|
|
47856
|
+
// If client signer is unavailable, return as-is so caller can fall back to
|
|
47857
|
+
// result.actionable.actionUrl (external signing URL) if present
|
|
47858
|
+
if (!isSignerAvailable) {
|
|
47859
|
+
console.warn('[useTransactions] Transaction signer not available, returning result for caller to handle');
|
|
47860
|
+
return result;
|
|
47861
|
+
}
|
|
47862
|
+
// Check if transaction requires client signing (contains actionable authToken)
|
|
47576
47863
|
// Type assertion needed as TransactionRequestResponseDTO type may not include all dynamic properties
|
|
47577
47864
|
const txToken = result?.actionable?.authToken;
|
|
47578
47865
|
if (txToken) {
|
|
47579
47866
|
try {
|
|
47580
|
-
if (!isSignerAvailable) {
|
|
47581
|
-
console.warn('[useTransactions] Transaction signer not available, skipping automatic signing');
|
|
47582
|
-
return result;
|
|
47583
|
-
}
|
|
47584
47867
|
// Automatically sign the transaction using the authToken
|
|
47585
47868
|
const signingResult = await signAndSubmitTransactionWithJWT(txToken, onStatusUpdate);
|
|
47586
47869
|
if (signingResult.success) {
|
|
@@ -50749,6 +51032,7 @@ exports.needsSubmission = needsSubmission;
|
|
|
50749
51032
|
exports.normalizeFilters = normalizeFilters;
|
|
50750
51033
|
exports.normalizeToPaginated = normalizeToPaginated;
|
|
50751
51034
|
exports.operatorText = operatorText;
|
|
51035
|
+
exports.parseUserAgentForPlatform = parseUserAgentForPlatform;
|
|
50752
51036
|
exports.parseUtmParams = parseUtmParams;
|
|
50753
51037
|
exports.registerIdentifierType = registerIdentifierType;
|
|
50754
51038
|
exports.selectOptionsSourceEntities = selectOptionsSourceEntities;
|