@explorins/pers-sdk-react-native 2.1.19 → 2.1.21
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 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useIPFSUrl.d.ts +68 -0
- package/dist/hooks/useIPFSUrl.d.ts.map +1 -0
- package/dist/hooks/useIPFSUrl.js +127 -0
- package/dist/hooks/useTransactions.d.ts.map +1 -1
- package/dist/hooks/useTransactions.js +2 -4
- package/dist/hooks/useWeb3.d.ts.map +1 -1
- package/dist/hooks/useWeb3.js +13 -4
- package/dist/index.js +443 -89
- package/dist/index.js.map +1 -1
- package/dist/providers/react-native-auth-provider.d.ts.map +1 -1
- package/dist/providers/react-native-auth-provider.js +0 -4
- package/package.json +2 -2
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useIPFSUrl.ts +139 -0
- package/src/hooks/useTransactions.ts +2 -5
- package/src/hooks/useWeb3.ts +13 -4
- package/src/providers/react-native-auth-provider.ts +0 -5
package/dist/index.js
CHANGED
|
@@ -3717,6 +3717,109 @@ const TRANSACTION_FORMAT_DESCRIPTIONS = {
|
|
|
3717
3717
|
[TRANSACTION_FORMATS.EIP_712]: 'EIP-712 structured data for smart wallet meta-transactions'
|
|
3718
3718
|
};
|
|
3719
3719
|
|
|
3720
|
+
/**
|
|
3721
|
+
* Error Codes extracted from actual domain error classes
|
|
3722
|
+
*
|
|
3723
|
+
* This object maps all error codes from domain error classes to provide
|
|
3724
|
+
* type-safe constants for API documentation and usage.
|
|
3725
|
+
*
|
|
3726
|
+
* Using object pattern for better performance and developer experience:
|
|
3727
|
+
* - Single export vs 50+ individual exports
|
|
3728
|
+
* - Namespaced access: CommonErrorCodes.USER_NOT_FOUND
|
|
3729
|
+
* - Better tree-shaking and bundle optimization
|
|
3730
|
+
* - Cleaner type definition
|
|
3731
|
+
*/
|
|
3732
|
+
const CommonErrorCodes = {
|
|
3733
|
+
// User domain
|
|
3734
|
+
USER_NOT_FOUND: 'USER_NOT_FOUND',
|
|
3735
|
+
USER_ALREADY_EXISTS: 'USER_ALREADY_EXISTS',
|
|
3736
|
+
USER_NOT_AUTHORIZED: 'USER_NOT_AUTHORIZED',
|
|
3737
|
+
// Token domain
|
|
3738
|
+
TOKEN_NOT_FOUND: 'TOKEN_NOT_FOUND',
|
|
3739
|
+
TOKEN_NOT_ACTIVE: 'TOKEN_NOT_ACTIVE',
|
|
3740
|
+
TOKEN_ID_REQUIRED: 'TOKEN_ID_REQUIRED',
|
|
3741
|
+
TOKEN_TYPE_NOT_FOUND: 'TOKEN_TYPE_NOT_FOUND',
|
|
3742
|
+
// Wallet domain
|
|
3743
|
+
WALLET_MISSING_SIGNING: 'WALLET_MISSING_SIGNING',
|
|
3744
|
+
WALLET_NOT_FOUND: 'WALLET_NOT_FOUND',
|
|
3745
|
+
SMART_WALLET_PROCESSING_FAILED: 'SMART_WALLET_PROCESSING_FAILED',
|
|
3746
|
+
// Balance domain
|
|
3747
|
+
INSUFFICIENT_BALANCE: 'INSUFFICIENT_BALANCE',
|
|
3748
|
+
// Contract domain
|
|
3749
|
+
CONTRACT_NOT_FOUND: 'CONTRACT_NOT_FOUND',
|
|
3750
|
+
// Business domain
|
|
3751
|
+
BUSINESS_NOT_FOUND: 'BUSINESS_NOT_FOUND',
|
|
3752
|
+
BUSINESS_NOT_MINTER: 'BUSINESS_NOT_MINTER',
|
|
3753
|
+
// Membership domain
|
|
3754
|
+
MEMBERSHIP_NOT_FOUND: 'MEMBERSHIP_NOT_FOUND',
|
|
3755
|
+
MEMBERSHIP_ALREADY_EXISTS: 'MEMBERSHIP_ALREADY_EXISTS',
|
|
3756
|
+
MEMBERSHIP_LAST_OWNER: 'MEMBERSHIP_LAST_OWNER',
|
|
3757
|
+
// Transaction domain
|
|
3758
|
+
TRANSACTION_NOT_FOUND: 'TRANSACTION_NOT_FOUND',
|
|
3759
|
+
TRANSACTION_SIGNATURE_INVALID: 'TRANSACTION_SIGNATURE_INVALID',
|
|
3760
|
+
TRANSACTION_ALREADY_COMPLETED: 'TRANSACTION_ALREADY_COMPLETED',
|
|
3761
|
+
TRANSACTION_NOT_PENDING: 'TRANSACTION_NOT_PENDING',
|
|
3762
|
+
TRANSACTION_EXPIRED: 'TRANSACTION_EXPIRED',
|
|
3763
|
+
TRANSACTION_VALIDATION_ERROR: 'TRANSACTION_VALIDATION_ERROR',
|
|
3764
|
+
UNEXPECTED_VALIDATION_SCENARIO: 'UNEXPECTED_VALIDATION_SCENARIO',
|
|
3765
|
+
// Campaign domain
|
|
3766
|
+
CAMPAIGN_USER_INFO_REQUIRED: 'CAMPAIGN_USER_INFO_REQUIRED',
|
|
3767
|
+
CAMPAIGN_BUSINESS_REQUIRED: 'CAMPAIGN_BUSINESS_REQUIRED',
|
|
3768
|
+
CAMPAIGN_CONDITION_NOT_MET: 'CAMPAIGN_CONDITION_NOT_MET',
|
|
3769
|
+
CAMPAIGN_ALREADY_CLAIMED: 'CAMPAIGN_ALREADY_CLAIMED',
|
|
3770
|
+
CAMPAIGN_NO_TRIGGER: 'CAMPAIGN_NO_TRIGGER',
|
|
3771
|
+
CAMPAIGN_LOCATION_REQUIRED: 'CAMPAIGN_LOCATION_REQUIRED',
|
|
3772
|
+
CAMPAIGN_DISTANCE_EXCEEDED: 'CAMPAIGN_DISTANCE_EXCEEDED',
|
|
3773
|
+
CAMPAIGN_NOT_ACTIVE: 'CAMPAIGN_NOT_ACTIVE',
|
|
3774
|
+
CAMPAIGN_ENDED: 'CAMPAIGN_ENDED',
|
|
3775
|
+
CAMPAIGN_NOT_STARTED: 'CAMPAIGN_NOT_STARTED',
|
|
3776
|
+
CAMPAIGN_CLAIM_LIMIT_REACHED: 'CAMPAIGN_CLAIM_LIMIT_REACHED',
|
|
3777
|
+
CAMPAIGN_COOLDOWN_ACTIVE: 'CAMPAIGN_COOLDOWN_ACTIVE',
|
|
3778
|
+
CAMPAIGN_DAILY_LIMIT_REACHED: 'CAMPAIGN_DAILY_LIMIT_REACHED',
|
|
3779
|
+
CAMPAIGN_GLOBAL_LIMIT_REACHED: 'CAMPAIGN_GLOBAL_LIMIT_REACHED',
|
|
3780
|
+
CAMPAIGN_GLOBAL_DAILY_LIMIT_REACHED: 'CAMPAIGN_GLOBAL_DAILY_LIMIT_REACHED',
|
|
3781
|
+
// Trigger domain
|
|
3782
|
+
TRIGGER_NOT_FOUND: 'TRIGGER_NOT_FOUND',
|
|
3783
|
+
// Trigger Source domain
|
|
3784
|
+
TRIGGER_SOURCE_NOT_FOUND: 'TRIGGER_SOURCE_NOT_FOUND',
|
|
3785
|
+
// Generic domain errors
|
|
3786
|
+
RESOURCE_ALREADY_EXISTS: 'RESOURCE_ALREADY_EXISTS',
|
|
3787
|
+
RESOURCE_IN_USE: 'RESOURCE_IN_USE',
|
|
3788
|
+
// Technical errors
|
|
3789
|
+
TECHNICAL_ERROR: 'TECHNICAL_ERROR',
|
|
3790
|
+
ORCHESTRATION_ERROR: 'ORCHESTRATION_ERROR',
|
|
3791
|
+
// System errors
|
|
3792
|
+
SYSTEM_ERROR: 'SYSTEM_ERROR',
|
|
3793
|
+
EXTERNAL_SERVICE_ERROR: 'EXTERNAL_SERVICE_ERROR',
|
|
3794
|
+
AUTHENTICATION_REQUIRED: 'AUTHENTICATION_REQUIRED',
|
|
3795
|
+
AUTHORIZATION_FAILED: 'AUTHORIZATION_FAILED',
|
|
3796
|
+
// Authentication errors
|
|
3797
|
+
INVALID_TOKEN: 'INVALID_TOKEN',
|
|
3798
|
+
TOKEN_EXPIRED: 'TOKEN_EXPIRED',
|
|
3799
|
+
TOKEN_REVOKED: 'TOKEN_REVOKED',
|
|
3800
|
+
REFRESH_TOKEN_EXPIRED: 'REFRESH_TOKEN_EXPIRED',
|
|
3801
|
+
REFRESH_TOKEN_REVOKED: 'REFRESH_TOKEN_REVOKED',
|
|
3802
|
+
FIREBASE_AUTH_ERROR: 'FIREBASE_AUTH_ERROR',
|
|
3803
|
+
// Generic fallbacks
|
|
3804
|
+
INTERNAL_ERROR: 'INTERNAL_ERROR',
|
|
3805
|
+
VALIDATION_ERROR: 'VALIDATION_ERROR',
|
|
3806
|
+
BUSINESS_RULE_VIOLATION: 'BUSINESS_RULE_VIOLATION',
|
|
3807
|
+
RESOURCE_NOT_FOUND: 'RESOURCE_NOT_FOUND',
|
|
3808
|
+
// Webhook domain
|
|
3809
|
+
WEBHOOK_NOT_FOUND: 'WEBHOOK_NOT_FOUND',
|
|
3810
|
+
WEBHOOK_INACTIVE: 'WEBHOOK_INACTIVE',
|
|
3811
|
+
WEBHOOK_SOURCE_NOT_ALLOWED: 'WEBHOOK_SOURCE_NOT_ALLOWED',
|
|
3812
|
+
WEBHOOK_SIGNATURE_INVALID: 'WEBHOOK_SIGNATURE_INVALID',
|
|
3813
|
+
WEBHOOK_FORWARD_FAILED: 'WEBHOOK_FORWARD_FAILED',
|
|
3814
|
+
WEBHOOK_TIMEOUT: 'WEBHOOK_TIMEOUT',
|
|
3815
|
+
// Conflict errors (409)
|
|
3816
|
+
RESOURCE_CONFLICT: 'RESOURCE_CONFLICT',
|
|
3817
|
+
CONCURRENT_MODIFICATION: 'CONCURRENT_MODIFICATION',
|
|
3818
|
+
// Timeout errors (504)
|
|
3819
|
+
REQUEST_TIMEOUT: 'REQUEST_TIMEOUT',
|
|
3820
|
+
GATEWAY_TIMEOUT: 'GATEWAY_TIMEOUT'
|
|
3821
|
+
};
|
|
3822
|
+
|
|
3720
3823
|
/**
|
|
3721
3824
|
* JWT token expiration utilities
|
|
3722
3825
|
* Native implementation without external dependencies for optimal performance
|
|
@@ -6817,6 +6920,22 @@ class RedemptionApi {
|
|
|
6817
6920
|
async createRedemptionType(redemptionType) {
|
|
6818
6921
|
return this.apiClient.post(this.typesPath, redemptionType);
|
|
6819
6922
|
}
|
|
6923
|
+
/**
|
|
6924
|
+
* ADMIN: Update redemption type
|
|
6925
|
+
*
|
|
6926
|
+
* @param redemptionType - Updated redemption type data (must include id)
|
|
6927
|
+
*/
|
|
6928
|
+
async updateRedemptionType(redemptionType) {
|
|
6929
|
+
return this.apiClient.put(`${this.typesPath}/${redemptionType.id}`, redemptionType);
|
|
6930
|
+
}
|
|
6931
|
+
/**
|
|
6932
|
+
* ADMIN: Delete redemption type
|
|
6933
|
+
*
|
|
6934
|
+
* @param id - Redemption type ID to delete
|
|
6935
|
+
*/
|
|
6936
|
+
async deleteRedemptionType(id) {
|
|
6937
|
+
return this.apiClient.delete(`${this.typesPath}/${id}`);
|
|
6938
|
+
}
|
|
6820
6939
|
// ==========================================
|
|
6821
6940
|
// TOKEN UNIT MANAGEMENT (Admin)
|
|
6822
6941
|
// ==========================================
|
|
@@ -6974,6 +7093,27 @@ class RedemptionService {
|
|
|
6974
7093
|
async deleteRedemptionTokenUnit(redemptionId, redemptionTokenUnitId) {
|
|
6975
7094
|
return this.redemptionApi.deleteRedemptionTokenUnit(redemptionId, redemptionTokenUnitId);
|
|
6976
7095
|
}
|
|
7096
|
+
// ==========================================
|
|
7097
|
+
// REDEMPTION TYPE MANAGEMENT (Admin)
|
|
7098
|
+
// ==========================================
|
|
7099
|
+
/**
|
|
7100
|
+
* ADMIN: Create redemption type
|
|
7101
|
+
*/
|
|
7102
|
+
async createRedemptionType(data) {
|
|
7103
|
+
return this.redemptionApi.createRedemptionType(data);
|
|
7104
|
+
}
|
|
7105
|
+
/**
|
|
7106
|
+
* ADMIN: Update redemption type
|
|
7107
|
+
*/
|
|
7108
|
+
async updateRedemptionType(data) {
|
|
7109
|
+
return this.redemptionApi.updateRedemptionType(data);
|
|
7110
|
+
}
|
|
7111
|
+
/**
|
|
7112
|
+
* ADMIN: Delete redemption type
|
|
7113
|
+
*/
|
|
7114
|
+
async deleteRedemptionType(id) {
|
|
7115
|
+
return this.redemptionApi.deleteRedemptionType(id);
|
|
7116
|
+
}
|
|
6977
7117
|
}
|
|
6978
7118
|
|
|
6979
7119
|
/**
|
|
@@ -8236,8 +8376,6 @@ class TenantService {
|
|
|
8236
8376
|
*
|
|
8237
8377
|
* Provides a simplified API for common tenant management tasks while maintaining
|
|
8238
8378
|
* access to the full tenant SDK for advanced use cases.
|
|
8239
|
-
*
|
|
8240
|
-
* Also provides chain-agnostic IPFS URL resolution using tenant configuration.
|
|
8241
8379
|
*/
|
|
8242
8380
|
class TenantManager {
|
|
8243
8381
|
constructor(apiClient) {
|
|
@@ -8281,52 +8419,6 @@ class TenantManager {
|
|
|
8281
8419
|
async getClientConfig() {
|
|
8282
8420
|
return this.cache.getOrSet('clientConfig', () => this.tenantService.getRemoteClientConfig(), CacheTTL.LONG);
|
|
8283
8421
|
}
|
|
8284
|
-
// ==========================================
|
|
8285
|
-
// IPFS OPERATIONS (Chain-agnostic)
|
|
8286
|
-
// ==========================================
|
|
8287
|
-
/**
|
|
8288
|
-
* Resolve IPFS URL to HTTPS URL using tenant's configured gateway.
|
|
8289
|
-
*
|
|
8290
|
-
* This is chain-agnostic - IPFS gateway is configured at the tenant level,
|
|
8291
|
-
* not per-chain. Use this for resolving any ipfs:// URLs (images, metadata, etc.).
|
|
8292
|
-
*
|
|
8293
|
-
* @param url - URL to resolve (can be ipfs:// or https://)
|
|
8294
|
-
* @returns Resolved HTTPS URL
|
|
8295
|
-
* @throws Error if tenant's ipfsGatewayDomain is not configured
|
|
8296
|
-
*
|
|
8297
|
-
* @example
|
|
8298
|
-
* ```typescript
|
|
8299
|
-
* const imageUrl = await sdk.tenant.resolveIPFSUrl('ipfs://QmXxx.../image.png');
|
|
8300
|
-
* // Returns: 'https://pers.mypinata.cloud/ipfs/QmXxx.../image.png'
|
|
8301
|
-
*
|
|
8302
|
-
* // Non-IPFS URLs pass through unchanged
|
|
8303
|
-
* const httpUrl = await sdk.tenant.resolveIPFSUrl('https://example.com/image.png');
|
|
8304
|
-
* // Returns: 'https://example.com/image.png'
|
|
8305
|
-
* ```
|
|
8306
|
-
*/
|
|
8307
|
-
async resolveIPFSUrl(url) {
|
|
8308
|
-
if (!url || !url.startsWith('ipfs://')) {
|
|
8309
|
-
return url;
|
|
8310
|
-
}
|
|
8311
|
-
const gateway = await this.getIpfsGatewayDomain();
|
|
8312
|
-
return url.replace('ipfs://', `https://${gateway}/ipfs/`);
|
|
8313
|
-
}
|
|
8314
|
-
/**
|
|
8315
|
-
* Get IPFS gateway domain from tenant configuration (cached).
|
|
8316
|
-
*
|
|
8317
|
-
* @returns IPFS gateway domain (e.g., 'pers.mypinata.cloud')
|
|
8318
|
-
* @throws Error if ipfsGatewayDomain is not configured for this tenant
|
|
8319
|
-
*/
|
|
8320
|
-
async getIpfsGatewayDomain() {
|
|
8321
|
-
return this.cache.getOrSet('ipfsGateway', async () => {
|
|
8322
|
-
const config = await this.getClientConfig();
|
|
8323
|
-
if (!config.ipfsGatewayDomain) {
|
|
8324
|
-
throw new Error('IPFS gateway domain not configured for tenant. ' +
|
|
8325
|
-
'Please configure ipfsGatewayDomain in tenant settings.');
|
|
8326
|
-
}
|
|
8327
|
-
return config.ipfsGatewayDomain;
|
|
8328
|
-
}, CacheTTL.GATEWAY);
|
|
8329
|
-
}
|
|
8330
8422
|
/**
|
|
8331
8423
|
* Get Google API key from tenant configuration (cached).
|
|
8332
8424
|
*
|
|
@@ -9144,6 +9236,19 @@ exports.AuthStatus = void 0;
|
|
|
9144
9236
|
function isExtendedProvider(provider) {
|
|
9145
9237
|
return 'setAuthType' in provider && typeof provider.setAuthType === 'function';
|
|
9146
9238
|
}
|
|
9239
|
+
/**
|
|
9240
|
+
* Fatal auth error codes that require immediate logout.
|
|
9241
|
+
* These indicate the session is completely invalid and cannot be recovered.
|
|
9242
|
+
* TOKEN_EXPIRED is NOT in this list - it's the normal "please refresh" case.
|
|
9243
|
+
*
|
|
9244
|
+
* Values validated against CommonErrorCodes from @explorins/pers-shared at compile time.
|
|
9245
|
+
*/
|
|
9246
|
+
const FATAL_AUTH_CODES = [
|
|
9247
|
+
'REFRESH_TOKEN_EXPIRED',
|
|
9248
|
+
'REFRESH_TOKEN_REVOKED',
|
|
9249
|
+
'INVALID_TOKEN',
|
|
9250
|
+
'TOKEN_REVOKED'
|
|
9251
|
+
];
|
|
9147
9252
|
/**
|
|
9148
9253
|
* Platform-agnostic authentication service
|
|
9149
9254
|
* Handles login, token refresh, and storage operations
|
|
@@ -9153,6 +9258,7 @@ class AuthService {
|
|
|
9153
9258
|
this.authApi = authApi;
|
|
9154
9259
|
this.authProvider = authProvider;
|
|
9155
9260
|
this.activeRefreshPromise = null;
|
|
9261
|
+
this.activeAuthFailurePromise = null;
|
|
9156
9262
|
this.currentAuthStatus = exports.AuthStatus.UNAUTHENTICATED;
|
|
9157
9263
|
}
|
|
9158
9264
|
/**
|
|
@@ -9291,13 +9397,42 @@ class AuthService {
|
|
|
9291
9397
|
}
|
|
9292
9398
|
}
|
|
9293
9399
|
/**
|
|
9294
|
-
*
|
|
9295
|
-
*
|
|
9400
|
+
* Check if an error code indicates a fatal auth failure.
|
|
9401
|
+
* Fatal errors require immediate logout - the session cannot be recovered.
|
|
9402
|
+
*/
|
|
9403
|
+
isFatalAuthError(errorCode) {
|
|
9404
|
+
return FATAL_AUTH_CODES.includes(errorCode);
|
|
9405
|
+
}
|
|
9406
|
+
/**
|
|
9407
|
+
* Handle authentication failure with proper cleanup.
|
|
9408
|
+
* Called when backend returns fatal auth error codes or refresh fails.
|
|
9296
9409
|
*/
|
|
9297
9410
|
async handleAuthFailure() {
|
|
9411
|
+
// Already failed - nothing to do
|
|
9298
9412
|
if (this.currentAuthStatus === exports.AuthStatus.AUTH_FAILED) {
|
|
9299
9413
|
return;
|
|
9300
9414
|
}
|
|
9415
|
+
// If refresh is currently in progress, don't fail - wait for refresh result
|
|
9416
|
+
if (this.activeRefreshPromise) {
|
|
9417
|
+
return;
|
|
9418
|
+
}
|
|
9419
|
+
// If auth failure is already in progress, wait for it
|
|
9420
|
+
if (this.activeAuthFailurePromise) {
|
|
9421
|
+
return await this.activeAuthFailurePromise;
|
|
9422
|
+
}
|
|
9423
|
+
// Create the failure promise to deduplicate concurrent calls
|
|
9424
|
+
this.activeAuthFailurePromise = this.performAuthFailure();
|
|
9425
|
+
try {
|
|
9426
|
+
await this.activeAuthFailurePromise;
|
|
9427
|
+
}
|
|
9428
|
+
finally {
|
|
9429
|
+
this.activeAuthFailurePromise = null;
|
|
9430
|
+
}
|
|
9431
|
+
}
|
|
9432
|
+
/**
|
|
9433
|
+
* Performs the actual auth failure cleanup
|
|
9434
|
+
*/
|
|
9435
|
+
async performAuthFailure() {
|
|
9301
9436
|
// Clear active refresh operations to prevent hanging promises
|
|
9302
9437
|
this.activeRefreshPromise = null;
|
|
9303
9438
|
// Clear all stored tokens
|
|
@@ -9419,10 +9554,8 @@ class TokenRefreshManager {
|
|
|
9419
9554
|
return true;
|
|
9420
9555
|
}
|
|
9421
9556
|
catch (error) {
|
|
9422
|
-
|
|
9423
|
-
|
|
9424
|
-
await this.authService.handleAuthFailure();
|
|
9425
|
-
}
|
|
9557
|
+
// Don't call handleAuthFailure here - let the caller decide
|
|
9558
|
+
// This prevents duplicate auth failure handling in race conditions
|
|
9426
9559
|
return false;
|
|
9427
9560
|
}
|
|
9428
9561
|
}
|
|
@@ -9948,11 +10081,15 @@ class DefaultAuthProvider {
|
|
|
9948
10081
|
this.config = config;
|
|
9949
10082
|
this.authTypeCache = null;
|
|
9950
10083
|
this.authType = config.authType || exports.AccountOwnerType.USER;
|
|
9951
|
-
// Determine if DPoP can be enabled
|
|
9952
|
-
|
|
10084
|
+
// Determine if DPoP can be enabled:
|
|
10085
|
+
// 1. Custom crypto provider is supplied (e.g., React Native), OR
|
|
10086
|
+
// 2. IndexedDB is available for browser CryptoKey persistence
|
|
10087
|
+
const hasCustomCryptoProvider = !!config.dpop?.cryptoProvider;
|
|
10088
|
+
const hasIndexedDB = this.canEnableDPoP();
|
|
10089
|
+
const canUseDPoP = hasCustomCryptoProvider || hasIndexedDB;
|
|
9953
10090
|
this.dpopEnabled = !!(config.dpop?.enabled && canUseDPoP);
|
|
9954
10091
|
if (config.dpop?.enabled && !canUseDPoP) {
|
|
9955
|
-
console.warn('[DefaultAuthProvider] DPoP disabled: IndexedDB not available. CryptoKey persistence requires IndexedDB.');
|
|
10092
|
+
console.warn('[DefaultAuthProvider] DPoP disabled: IndexedDB not available and no custom crypto provider supplied. CryptoKey persistence requires IndexedDB or a custom provider.');
|
|
9956
10093
|
}
|
|
9957
10094
|
const storage = config.storage || this.createStorage();
|
|
9958
10095
|
this.tokenManager = new AuthTokenManager(storage);
|
|
@@ -10121,7 +10258,7 @@ class DefaultAuthProvider {
|
|
|
10121
10258
|
/** SDK package name */
|
|
10122
10259
|
const SDK_NAME = "@explorins/pers-sdk";
|
|
10123
10260
|
/** SDK version - injected from package.json at build time */
|
|
10124
|
-
const SDK_VERSION = "2.1.
|
|
10261
|
+
const SDK_VERSION = "2.1.31";
|
|
10125
10262
|
/** Full SDK identifier for headers */
|
|
10126
10263
|
const SDK_USER_AGENT = `${SDK_NAME}/${SDK_VERSION}`;
|
|
10127
10264
|
|
|
@@ -10270,12 +10407,21 @@ class PersApiClient {
|
|
|
10270
10407
|
// Handle 401 errors centrally through AuthService
|
|
10271
10408
|
if (status === 401) {
|
|
10272
10409
|
const backendError = ErrorUtils.extractBackendErrorDetails(error);
|
|
10410
|
+
// Check for fatal auth errors that require immediate logout
|
|
10411
|
+
if (this.authService.isFatalAuthError(backendError.code)) {
|
|
10412
|
+
// Definitive auth failure - no retry, session is invalid
|
|
10413
|
+
await this.authService.handleAuthFailure();
|
|
10414
|
+
this.emitErrorEvent(backendError, errorMessage, endpoint, method, status, error);
|
|
10415
|
+
throw new AuthenticationError(errorMessage, endpoint, method, backendError);
|
|
10416
|
+
}
|
|
10273
10417
|
// If this IS a refresh request that failed with 401, don't retry to avoid infinite loop
|
|
10274
10418
|
if (options?.isRefreshRequest) {
|
|
10419
|
+
// Refresh failed - this is a real auth failure
|
|
10420
|
+
await this.authService.handleAuthFailure();
|
|
10275
10421
|
this.emitErrorEvent(backendError, errorMessage, endpoint, method, status, error);
|
|
10276
10422
|
throw new AuthenticationError(errorMessage, endpoint, method, backendError);
|
|
10277
10423
|
}
|
|
10278
|
-
//
|
|
10424
|
+
// TOKEN_EXPIRED or unknown 401: try refresh once, then retry
|
|
10279
10425
|
if (retryCount === 0 && this.mergedConfig.authProvider) {
|
|
10280
10426
|
try {
|
|
10281
10427
|
const refreshSuccessful = await this.refreshManager.attemptInternalRefresh();
|
|
@@ -10286,13 +10432,15 @@ class PersApiClient {
|
|
|
10286
10432
|
domain: 'authentication',
|
|
10287
10433
|
userMessage: 'Authentication token refreshed',
|
|
10288
10434
|
});
|
|
10435
|
+
// Retry with new token
|
|
10289
10436
|
return await this.request(method, endpoint, body, { ...options, retryCount: 1 });
|
|
10290
10437
|
}
|
|
10291
10438
|
}
|
|
10292
10439
|
catch (refreshError) {
|
|
10293
|
-
//
|
|
10440
|
+
// Refresh failed - fall through to handleAuthFailure
|
|
10294
10441
|
}
|
|
10295
10442
|
}
|
|
10443
|
+
// All recovery attempts failed
|
|
10296
10444
|
await this.authService.handleAuthFailure();
|
|
10297
10445
|
this.emitErrorEvent(backendError, errorMessage, endpoint, method, status, error);
|
|
10298
10446
|
throw new AuthenticationError(errorMessage, endpoint, method, backendError);
|
|
@@ -12253,6 +12401,69 @@ class BusinessManager {
|
|
|
12253
12401
|
async getBusinessTypes(options) {
|
|
12254
12402
|
return this.businessService.getBusinessTypes();
|
|
12255
12403
|
}
|
|
12404
|
+
/**
|
|
12405
|
+
* Admin: Create a new business type
|
|
12406
|
+
*
|
|
12407
|
+
* Creates a new business type category in the system.
|
|
12408
|
+
* Requires administrator privileges.
|
|
12409
|
+
*
|
|
12410
|
+
* @param data - Business type data (name, description, code, iconUrl)
|
|
12411
|
+
* @returns Promise resolving to the created business type
|
|
12412
|
+
* @throws {PersApiError} When not authenticated as admin or validation fails
|
|
12413
|
+
*
|
|
12414
|
+
* @example
|
|
12415
|
+
* ```typescript
|
|
12416
|
+
* const newType = await sdk.business.createBusinessType({
|
|
12417
|
+
* name: 'Restaurant',
|
|
12418
|
+
* description: 'Food service establishments',
|
|
12419
|
+
* code: 'RESTAURANT',
|
|
12420
|
+
* iconUrl: 'https://example.com/restaurant-icon.png'
|
|
12421
|
+
* });
|
|
12422
|
+
* ```
|
|
12423
|
+
*/
|
|
12424
|
+
async createBusinessType(data) {
|
|
12425
|
+
return this.businessApi.createBusinessType(data);
|
|
12426
|
+
}
|
|
12427
|
+
/**
|
|
12428
|
+
* Admin: Update an existing business type
|
|
12429
|
+
*
|
|
12430
|
+
* Updates a business type's properties.
|
|
12431
|
+
* Requires administrator privileges.
|
|
12432
|
+
*
|
|
12433
|
+
* @param data - Updated business type data (must include id)
|
|
12434
|
+
* @returns Promise resolving to the updated business type
|
|
12435
|
+
* @throws {PersApiError} When not authenticated as admin or type not found
|
|
12436
|
+
*
|
|
12437
|
+
* @example
|
|
12438
|
+
* ```typescript
|
|
12439
|
+
* const updated = await sdk.business.updateBusinessType({
|
|
12440
|
+
* id: 123,
|
|
12441
|
+
* name: 'Fine Dining Restaurant',
|
|
12442
|
+
* description: 'Upscale dining establishments'
|
|
12443
|
+
* });
|
|
12444
|
+
* ```
|
|
12445
|
+
*/
|
|
12446
|
+
async updateBusinessType(data) {
|
|
12447
|
+
return this.businessApi.updateBusinessType(data);
|
|
12448
|
+
}
|
|
12449
|
+
/**
|
|
12450
|
+
* Admin: Delete a business type
|
|
12451
|
+
*
|
|
12452
|
+
* Deletes a business type. Will fail if type is in use by businesses.
|
|
12453
|
+
* Requires administrator privileges.
|
|
12454
|
+
*
|
|
12455
|
+
* @param id - Business type ID to delete
|
|
12456
|
+
* @returns Promise resolving to true if deleted successfully
|
|
12457
|
+
* @throws {PersApiError} When not authenticated as admin or type not found/in use
|
|
12458
|
+
*
|
|
12459
|
+
* @example
|
|
12460
|
+
* ```typescript
|
|
12461
|
+
* const success = await sdk.business.deleteBusinessType(123);
|
|
12462
|
+
* ```
|
|
12463
|
+
*/
|
|
12464
|
+
async deleteBusinessType(id) {
|
|
12465
|
+
return this.businessApi.deleteBusinessType(id);
|
|
12466
|
+
}
|
|
12256
12467
|
/**
|
|
12257
12468
|
* Get businesses by type
|
|
12258
12469
|
*
|
|
@@ -14261,6 +14472,77 @@ class RedemptionManager {
|
|
|
14261
14472
|
async deleteRedemptionTokenUnit(redemptionId, tokenUnitId) {
|
|
14262
14473
|
return this.redemptionService.deleteRedemptionTokenUnit(redemptionId, tokenUnitId);
|
|
14263
14474
|
}
|
|
14475
|
+
// ==========================================
|
|
14476
|
+
// REDEMPTION TYPE MANAGEMENT (Admin)
|
|
14477
|
+
// ==========================================
|
|
14478
|
+
/**
|
|
14479
|
+
* Admin: Create redemption type
|
|
14480
|
+
*
|
|
14481
|
+
* Creates a new redemption type category for organizing redemption offers.
|
|
14482
|
+
* Requires administrator privileges.
|
|
14483
|
+
*
|
|
14484
|
+
* @param data - Redemption type data (name, description, imageUrl)
|
|
14485
|
+
* @returns Promise resolving to created redemption type
|
|
14486
|
+
* @throws {PersApiError} When not authenticated as admin or validation fails
|
|
14487
|
+
*
|
|
14488
|
+
* @example
|
|
14489
|
+
* ```typescript
|
|
14490
|
+
* const newType = await sdk.redemptions.createRedemptionType({
|
|
14491
|
+
* name: 'Premium Rewards',
|
|
14492
|
+
* description: 'High-value exclusive rewards',
|
|
14493
|
+
* imageUrl: 'https://example.com/premium-icon.png'
|
|
14494
|
+
* });
|
|
14495
|
+
*
|
|
14496
|
+
* console.log('Created type:', newType.name);
|
|
14497
|
+
* ```
|
|
14498
|
+
*/
|
|
14499
|
+
async createRedemptionType(data) {
|
|
14500
|
+
return this.redemptionService.createRedemptionType(data);
|
|
14501
|
+
}
|
|
14502
|
+
/**
|
|
14503
|
+
* Admin: Update redemption type
|
|
14504
|
+
*
|
|
14505
|
+
* Updates an existing redemption type's properties.
|
|
14506
|
+
* Requires administrator privileges.
|
|
14507
|
+
*
|
|
14508
|
+
* @param data - Updated redemption type data (must include id)
|
|
14509
|
+
* @returns Promise resolving to updated redemption type
|
|
14510
|
+
* @throws {PersApiError} When not authenticated as admin or type not found
|
|
14511
|
+
*
|
|
14512
|
+
* @example
|
|
14513
|
+
* ```typescript
|
|
14514
|
+
* const updated = await sdk.redemptions.updateRedemptionType({
|
|
14515
|
+
* id: 123,
|
|
14516
|
+
* name: 'VIP Rewards',
|
|
14517
|
+
* description: 'Updated description',
|
|
14518
|
+
* imageUrl: 'https://example.com/vip-icon.png'
|
|
14519
|
+
* });
|
|
14520
|
+
*
|
|
14521
|
+
* console.log('Updated type:', updated.name);
|
|
14522
|
+
* ```
|
|
14523
|
+
*/
|
|
14524
|
+
async updateRedemptionType(data) {
|
|
14525
|
+
return this.redemptionService.updateRedemptionType(data);
|
|
14526
|
+
}
|
|
14527
|
+
/**
|
|
14528
|
+
* Admin: Delete redemption type
|
|
14529
|
+
*
|
|
14530
|
+
* Deletes a redemption type. Will fail if type is in use by redemptions.
|
|
14531
|
+
* Requires administrator privileges.
|
|
14532
|
+
*
|
|
14533
|
+
* @param id - Redemption type ID to delete
|
|
14534
|
+
* @returns Promise resolving to true if deleted successfully
|
|
14535
|
+
* @throws {PersApiError} When not authenticated as admin or type not found/in use
|
|
14536
|
+
*
|
|
14537
|
+
* @example
|
|
14538
|
+
* ```typescript
|
|
14539
|
+
* const success = await sdk.redemptions.deleteRedemptionType(123);
|
|
14540
|
+
* console.log('Deleted:', success);
|
|
14541
|
+
* ```
|
|
14542
|
+
*/
|
|
14543
|
+
async deleteRedemptionType(id) {
|
|
14544
|
+
return this.redemptionService.deleteRedemptionType(id);
|
|
14545
|
+
}
|
|
14264
14546
|
/**
|
|
14265
14547
|
* Get the full redemption service for advanced operations
|
|
14266
14548
|
*
|
|
@@ -19416,10 +19698,6 @@ function createReactNativeAuthProvider(projectKey, config = {}) {
|
|
|
19416
19698
|
enabled: dpop.enabled ?? true,
|
|
19417
19699
|
cryptoProvider: dpop.cryptoProvider
|
|
19418
19700
|
} : undefined;
|
|
19419
|
-
// DEBUG LOGGING
|
|
19420
|
-
if (debug) {
|
|
19421
|
-
console.log('[ReactNativeAuthProvider] Creating provider with DPoP config:', JSON.stringify(dpopConfig));
|
|
19422
|
-
}
|
|
19423
19701
|
// Return DefaultAuthProvider configured with platform-appropriate storage
|
|
19424
19702
|
return new DefaultAuthProvider({
|
|
19425
19703
|
authType,
|
|
@@ -40254,6 +40532,13 @@ class MetadataDomainService {
|
|
|
40254
40532
|
const cacheKey = `resolve:${url}`;
|
|
40255
40533
|
return this.cache.getOrSet(cacheKey, () => this.ipfsApi.resolveIPFSUrl(url), CacheTTL.GATEWAY);
|
|
40256
40534
|
}
|
|
40535
|
+
/**
|
|
40536
|
+
* Get IPFS gateway domain from tenant configuration.
|
|
40537
|
+
* Useful for pipes that need to resolve URLs synchronously after initial fetch.
|
|
40538
|
+
*/
|
|
40539
|
+
async getIpfsGatewayDomain() {
|
|
40540
|
+
return this.ipfsApi.getIpfsGatewayDomain();
|
|
40541
|
+
}
|
|
40257
40542
|
/**
|
|
40258
40543
|
* Clear all cached metadata and URLs for this service
|
|
40259
40544
|
*/
|
|
@@ -40359,6 +40644,15 @@ class Web3ApplicationService {
|
|
|
40359
40644
|
async resolveIPFSUrl(url) {
|
|
40360
40645
|
return this.metadataDomainService.resolveIPFSUrl(url);
|
|
40361
40646
|
}
|
|
40647
|
+
/**
|
|
40648
|
+
* Get IPFS gateway domain from tenant configuration.
|
|
40649
|
+
* Useful for pipes that need to resolve URLs synchronously after initial fetch.
|
|
40650
|
+
*
|
|
40651
|
+
* @returns Gateway domain (e.g., 'pers.mypinata.cloud')
|
|
40652
|
+
*/
|
|
40653
|
+
async getIpfsGatewayDomain() {
|
|
40654
|
+
return this.metadataDomainService.getIpfsGatewayDomain();
|
|
40655
|
+
}
|
|
40362
40656
|
/**
|
|
40363
40657
|
* Fetch and process metadata from any URI with IPFS conversion.
|
|
40364
40658
|
*
|
|
@@ -40479,25 +40773,26 @@ class IPFSInfrastructureApi {
|
|
|
40479
40773
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
40480
40774
|
}
|
|
40481
40775
|
const rawMetadata = await response.json();
|
|
40482
|
-
// Resolve IPFS URLs
|
|
40483
|
-
const
|
|
40484
|
-
|
|
40485
|
-
|
|
40486
|
-
|
|
40487
|
-
|
|
40488
|
-
|
|
40776
|
+
// Resolve any IPFS URLs in string fields
|
|
40777
|
+
for (const key of Object.keys(rawMetadata)) {
|
|
40778
|
+
const value = rawMetadata[key];
|
|
40779
|
+
if (typeof value === 'string' && value.startsWith('ipfs://')) {
|
|
40780
|
+
rawMetadata[key] = await this.resolveIPFSUrl(value);
|
|
40781
|
+
}
|
|
40782
|
+
}
|
|
40489
40783
|
// Extract custom properties (anything not in ERC standard)
|
|
40490
40784
|
const customProperties = Object.fromEntries(Object.entries(rawMetadata).filter(([key]) => !['name', 'description', 'image', 'animation_url', 'external_url', 'attributes'].includes(key)));
|
|
40491
|
-
// Return normalized SDK format
|
|
40492
|
-
|
|
40493
|
-
name: rawMetadata.name
|
|
40494
|
-
description: rawMetadata.description
|
|
40495
|
-
imageUrl:
|
|
40496
|
-
animationUrl:
|
|
40497
|
-
externalUrl: rawMetadata.external_url
|
|
40498
|
-
attributes: rawMetadata.attributes
|
|
40785
|
+
// Return normalized SDK format
|
|
40786
|
+
const result = {
|
|
40787
|
+
name: String(rawMetadata.name ?? ''),
|
|
40788
|
+
description: String(rawMetadata.description ?? ''),
|
|
40789
|
+
imageUrl: String(rawMetadata.image ?? ''),
|
|
40790
|
+
animationUrl: rawMetadata.animation_url ? String(rawMetadata.animation_url) : undefined,
|
|
40791
|
+
externalUrl: rawMetadata.external_url ? String(rawMetadata.external_url) : undefined,
|
|
40792
|
+
attributes: Array.isArray(rawMetadata.attributes) ? rawMetadata.attributes : [],
|
|
40499
40793
|
...customProperties
|
|
40500
40794
|
};
|
|
40795
|
+
return result;
|
|
40501
40796
|
}
|
|
40502
40797
|
catch (error) {
|
|
40503
40798
|
console.error('Error fetching metadata:', error);
|
|
@@ -40620,8 +40915,20 @@ async function getExplorerUrlByChainId(getChainData, chainId, address, type) {
|
|
|
40620
40915
|
*
|
|
40621
40916
|
* ## IPFS Resolution
|
|
40622
40917
|
*
|
|
40623
|
-
*
|
|
40624
|
-
*
|
|
40918
|
+
* Use `sdk.web3.resolveIPFSUrl()` to resolve IPFS URLs to HTTPS:
|
|
40919
|
+
*
|
|
40920
|
+
* ```typescript
|
|
40921
|
+
* const httpsUrl = await sdk.web3.resolveIPFSUrl('ipfs://QmXxx.../image.png');
|
|
40922
|
+
* // Returns: 'https://pers.mypinata.cloud/ipfs/QmXxx.../image.png'
|
|
40923
|
+
* ```
|
|
40924
|
+
*
|
|
40925
|
+
* Or fetch full metadata with resolved URLs:
|
|
40926
|
+
*
|
|
40927
|
+
* ```typescript
|
|
40928
|
+
* const metadata = await sdk.web3.fetchAndProcessMetadata('ipfs://QmXxx.../metadata.json');
|
|
40929
|
+
* // All IPFS URLs in metadata are resolved to HTTPS
|
|
40930
|
+
* // Returns SDK format: { imageUrl, animationUrl, externalUrl, ... }
|
|
40931
|
+
* ```
|
|
40625
40932
|
*/
|
|
40626
40933
|
class Web3Manager {
|
|
40627
40934
|
// TODO: Add PersEventEmitter support for blockchain events
|
|
@@ -40679,6 +40986,45 @@ class Web3Manager {
|
|
|
40679
40986
|
async fetchAndProcessMetadata(tokenUri) {
|
|
40680
40987
|
return this.web3ApplicationService.fetchAndProcessMetadata(tokenUri);
|
|
40681
40988
|
}
|
|
40989
|
+
// ==========================================
|
|
40990
|
+
// IPFS OPERATIONS
|
|
40991
|
+
// ==========================================
|
|
40992
|
+
/**
|
|
40993
|
+
* Resolve IPFS URL to HTTPS URL using tenant's configured gateway.
|
|
40994
|
+
*
|
|
40995
|
+
* @param url - URL to resolve (can be ipfs:// or https://)
|
|
40996
|
+
* @returns Resolved HTTPS URL
|
|
40997
|
+
* @throws Error if tenant's ipfsGatewayDomain is not configured
|
|
40998
|
+
*
|
|
40999
|
+
* @example
|
|
41000
|
+
* ```typescript
|
|
41001
|
+
* const imageUrl = await sdk.web3.resolveIPFSUrl('ipfs://QmXxx.../image.png');
|
|
41002
|
+
* // Returns: 'https://pers.mypinata.cloud/ipfs/QmXxx.../image.png'
|
|
41003
|
+
*
|
|
41004
|
+
* // Non-IPFS URLs pass through unchanged
|
|
41005
|
+
* const httpUrl = await sdk.web3.resolveIPFSUrl('https://example.com/image.png');
|
|
41006
|
+
* // Returns: 'https://example.com/image.png'
|
|
41007
|
+
* ```
|
|
41008
|
+
*/
|
|
41009
|
+
async resolveIPFSUrl(url) {
|
|
41010
|
+
return this.web3ApplicationService.resolveIPFSUrl(url);
|
|
41011
|
+
}
|
|
41012
|
+
/**
|
|
41013
|
+
* Get IPFS gateway domain from tenant configuration.
|
|
41014
|
+
* Useful for pipes that need to resolve URLs synchronously after initial fetch.
|
|
41015
|
+
*
|
|
41016
|
+
* @returns Gateway domain (e.g., 'pers.mypinata.cloud')
|
|
41017
|
+
* @throws Error if tenant's ipfsGatewayDomain is not configured
|
|
41018
|
+
*
|
|
41019
|
+
* @example
|
|
41020
|
+
* ```typescript
|
|
41021
|
+
* const gateway = await sdk.web3.getIpfsGatewayDomain();
|
|
41022
|
+
* // Use gateway for sync resolution: `https://${gateway}/ipfs/${cid}`
|
|
41023
|
+
* ```
|
|
41024
|
+
*/
|
|
41025
|
+
async getIpfsGatewayDomain() {
|
|
41026
|
+
return this.web3ApplicationService.getIpfsGatewayDomain();
|
|
41027
|
+
}
|
|
40682
41028
|
/**
|
|
40683
41029
|
* Get blockchain chain data by chain ID
|
|
40684
41030
|
*
|
|
@@ -40985,23 +41331,32 @@ const useWeb3 = () => {
|
|
|
40985
41331
|
/**
|
|
40986
41332
|
* Resolve IPFS URL to HTTP gateway URL
|
|
40987
41333
|
*
|
|
40988
|
-
*
|
|
41334
|
+
* Converts an ipfs:// URL to an HTTPS URL using the tenant's configured IPFS gateway.
|
|
41335
|
+
* Non-IPFS URLs are returned unchanged.
|
|
41336
|
+
*
|
|
40989
41337
|
* @param url - IPFS URL to resolve (ipfs://...)
|
|
40990
41338
|
* @returns Promise resolving to HTTP gateway URL
|
|
41339
|
+
*
|
|
41340
|
+
* @example
|
|
41341
|
+
* ```typescript
|
|
41342
|
+
* const { resolveIPFSUrl } = useWeb3();
|
|
41343
|
+
* const httpsUrl = await resolveIPFSUrl('ipfs://QmHash...');
|
|
41344
|
+
* // Returns: 'https://gateway.pinata.cloud/ipfs/QmHash...'
|
|
41345
|
+
* ```
|
|
40991
41346
|
*/
|
|
40992
41347
|
const resolveIPFSUrl = react.useCallback(async (url) => {
|
|
40993
|
-
if (!isInitialized || !
|
|
41348
|
+
if (!isInitialized || !web3) {
|
|
40994
41349
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
40995
41350
|
}
|
|
40996
41351
|
try {
|
|
40997
|
-
const result = await
|
|
41352
|
+
const result = await web3.resolveIPFSUrl(url);
|
|
40998
41353
|
return result;
|
|
40999
41354
|
}
|
|
41000
41355
|
catch (error) {
|
|
41001
41356
|
console.error('Failed to resolve IPFS URL:', error);
|
|
41002
41357
|
throw error;
|
|
41003
41358
|
}
|
|
41004
|
-
}, [
|
|
41359
|
+
}, [web3, isInitialized]);
|
|
41005
41360
|
/**
|
|
41006
41361
|
* Fetch and process token metadata from a URI
|
|
41007
41362
|
*
|
|
@@ -42655,8 +43010,7 @@ const useTransactions = () => {
|
|
|
42655
43010
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
42656
43011
|
}
|
|
42657
43012
|
try {
|
|
42658
|
-
|
|
42659
|
-
return result;
|
|
43013
|
+
return await sdk.transactions.getTransactionById(transactionId, include);
|
|
42660
43014
|
}
|
|
42661
43015
|
catch (error) {
|
|
42662
43016
|
console.error('Failed to fetch transaction:', error);
|
|
@@ -42705,8 +43059,7 @@ const useTransactions = () => {
|
|
|
42705
43059
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
42706
43060
|
}
|
|
42707
43061
|
try {
|
|
42708
|
-
|
|
42709
|
-
return result;
|
|
43062
|
+
return await sdk.transactions.getUserTransactionHistory(options);
|
|
42710
43063
|
}
|
|
42711
43064
|
catch (error) {
|
|
42712
43065
|
console.error('Failed to fetch transaction history:', error);
|
|
@@ -45176,6 +45529,7 @@ exports.CampaignManager = CampaignManager;
|
|
|
45176
45529
|
exports.CampaignService = CampaignService;
|
|
45177
45530
|
exports.ChainTypes = ChainTypes;
|
|
45178
45531
|
exports.ClientTransactionType = ClientTransactionType;
|
|
45532
|
+
exports.CommonErrorCodes = CommonErrorCodes;
|
|
45179
45533
|
exports.DEFAULT_PERS_CONFIG = DEFAULT_PERS_CONFIG;
|
|
45180
45534
|
exports.DPOP_STORAGE_KEYS = DPOP_STORAGE_KEYS;
|
|
45181
45535
|
exports.DPoPManager = DPoPManager;
|