@explorins/pers-sdk-react-native 2.1.20 → 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 +436 -107
- package/dist/index.js.map +1 -1
- package/dist/providers/PersSDKProvider.d.ts.map +1 -1
- package/dist/providers/PersSDKProvider.js +0 -7
- package/dist/providers/react-native-auth-provider.d.ts.map +1 -1
- package/dist/providers/react-native-auth-provider.js +0 -9
- 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/PersSDKProvider.tsx +0 -8
- package/src/providers/react-native-auth-provider.ts +0 -10
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
|
}
|
|
@@ -9955,15 +10088,6 @@ class DefaultAuthProvider {
|
|
|
9955
10088
|
const hasIndexedDB = this.canEnableDPoP();
|
|
9956
10089
|
const canUseDPoP = hasCustomCryptoProvider || hasIndexedDB;
|
|
9957
10090
|
this.dpopEnabled = !!(config.dpop?.enabled && canUseDPoP);
|
|
9958
|
-
// Debug logging for DPoP configuration
|
|
9959
|
-
console.log('[DefaultAuthProvider] DPoP config:', {
|
|
9960
|
-
requestedEnabled: config.dpop?.enabled ?? false,
|
|
9961
|
-
hasCustomCryptoProvider,
|
|
9962
|
-
hasIndexedDB,
|
|
9963
|
-
canUseDPoP,
|
|
9964
|
-
finalEnabled: this.dpopEnabled,
|
|
9965
|
-
cryptoProviderType: config.dpop?.cryptoProvider?.constructor?.name || 'none'
|
|
9966
|
-
});
|
|
9967
10091
|
if (config.dpop?.enabled && !canUseDPoP) {
|
|
9968
10092
|
console.warn('[DefaultAuthProvider] DPoP disabled: IndexedDB not available and no custom crypto provider supplied. CryptoKey persistence requires IndexedDB or a custom provider.');
|
|
9969
10093
|
}
|
|
@@ -10134,7 +10258,7 @@ class DefaultAuthProvider {
|
|
|
10134
10258
|
/** SDK package name */
|
|
10135
10259
|
const SDK_NAME = "@explorins/pers-sdk";
|
|
10136
10260
|
/** SDK version - injected from package.json at build time */
|
|
10137
|
-
const SDK_VERSION = "2.1.
|
|
10261
|
+
const SDK_VERSION = "2.1.31";
|
|
10138
10262
|
/** Full SDK identifier for headers */
|
|
10139
10263
|
const SDK_USER_AGENT = `${SDK_NAME}/${SDK_VERSION}`;
|
|
10140
10264
|
|
|
@@ -10283,12 +10407,21 @@ class PersApiClient {
|
|
|
10283
10407
|
// Handle 401 errors centrally through AuthService
|
|
10284
10408
|
if (status === 401) {
|
|
10285
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
|
+
}
|
|
10286
10417
|
// If this IS a refresh request that failed with 401, don't retry to avoid infinite loop
|
|
10287
10418
|
if (options?.isRefreshRequest) {
|
|
10419
|
+
// Refresh failed - this is a real auth failure
|
|
10420
|
+
await this.authService.handleAuthFailure();
|
|
10288
10421
|
this.emitErrorEvent(backendError, errorMessage, endpoint, method, status, error);
|
|
10289
10422
|
throw new AuthenticationError(errorMessage, endpoint, method, backendError);
|
|
10290
10423
|
}
|
|
10291
|
-
//
|
|
10424
|
+
// TOKEN_EXPIRED or unknown 401: try refresh once, then retry
|
|
10292
10425
|
if (retryCount === 0 && this.mergedConfig.authProvider) {
|
|
10293
10426
|
try {
|
|
10294
10427
|
const refreshSuccessful = await this.refreshManager.attemptInternalRefresh();
|
|
@@ -10299,13 +10432,15 @@ class PersApiClient {
|
|
|
10299
10432
|
domain: 'authentication',
|
|
10300
10433
|
userMessage: 'Authentication token refreshed',
|
|
10301
10434
|
});
|
|
10435
|
+
// Retry with new token
|
|
10302
10436
|
return await this.request(method, endpoint, body, { ...options, retryCount: 1 });
|
|
10303
10437
|
}
|
|
10304
10438
|
}
|
|
10305
10439
|
catch (refreshError) {
|
|
10306
|
-
//
|
|
10440
|
+
// Refresh failed - fall through to handleAuthFailure
|
|
10307
10441
|
}
|
|
10308
10442
|
}
|
|
10443
|
+
// All recovery attempts failed
|
|
10309
10444
|
await this.authService.handleAuthFailure();
|
|
10310
10445
|
this.emitErrorEvent(backendError, errorMessage, endpoint, method, status, error);
|
|
10311
10446
|
throw new AuthenticationError(errorMessage, endpoint, method, backendError);
|
|
@@ -12266,6 +12401,69 @@ class BusinessManager {
|
|
|
12266
12401
|
async getBusinessTypes(options) {
|
|
12267
12402
|
return this.businessService.getBusinessTypes();
|
|
12268
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
|
+
}
|
|
12269
12467
|
/**
|
|
12270
12468
|
* Get businesses by type
|
|
12271
12469
|
*
|
|
@@ -14274,6 +14472,77 @@ class RedemptionManager {
|
|
|
14274
14472
|
async deleteRedemptionTokenUnit(redemptionId, tokenUnitId) {
|
|
14275
14473
|
return this.redemptionService.deleteRedemptionTokenUnit(redemptionId, tokenUnitId);
|
|
14276
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
|
+
}
|
|
14277
14546
|
/**
|
|
14278
14547
|
* Get the full redemption service for advanced operations
|
|
14279
14548
|
*
|
|
@@ -19429,15 +19698,6 @@ function createReactNativeAuthProvider(projectKey, config = {}) {
|
|
|
19429
19698
|
enabled: dpop.enabled ?? true,
|
|
19430
19699
|
cryptoProvider: dpop.cryptoProvider
|
|
19431
19700
|
} : undefined;
|
|
19432
|
-
// Always log DPoP config for debugging (critical for mobile auth)
|
|
19433
|
-
console.log('[ReactNativeAuthProvider] Config:', {
|
|
19434
|
-
platform: reactNative.Platform.OS,
|
|
19435
|
-
isWebPlatform,
|
|
19436
|
-
dpopEnabled: dpopConfig?.enabled ?? false,
|
|
19437
|
-
hasCryptoProvider: !!dpopConfig?.cryptoProvider,
|
|
19438
|
-
cryptoProviderType: dpopConfig?.cryptoProvider?.constructor?.name || 'none',
|
|
19439
|
-
storageType: tokenStorage.constructor.name
|
|
19440
|
-
});
|
|
19441
19701
|
// Return DefaultAuthProvider configured with platform-appropriate storage
|
|
19442
19702
|
return new DefaultAuthProvider({
|
|
19443
19703
|
authType,
|
|
@@ -19764,13 +20024,6 @@ const PersSDKProvider = ({ children, config }) => {
|
|
|
19764
20024
|
if (reactNative.Platform.OS !== 'web' && isDpopEnabled && !dpopSettings.cryptoProvider) {
|
|
19765
20025
|
dpopSettings.cryptoProvider = new ReactNativeDPoPProvider();
|
|
19766
20026
|
}
|
|
19767
|
-
// Log DPoP settings before creating auth provider
|
|
19768
|
-
console.log('[PersSDKProvider] DPoP settings:', {
|
|
19769
|
-
platform: reactNative.Platform.OS,
|
|
19770
|
-
isDpopEnabled,
|
|
19771
|
-
hasCryptoProvider: !!dpopSettings.cryptoProvider,
|
|
19772
|
-
cryptoProviderType: dpopSettings.cryptoProvider?.constructor?.name || 'none'
|
|
19773
|
-
});
|
|
19774
20027
|
// Create platform-aware auth provider if not provided
|
|
19775
20028
|
let authProvider;
|
|
19776
20029
|
if (config.authProvider) {
|
|
@@ -40279,6 +40532,13 @@ class MetadataDomainService {
|
|
|
40279
40532
|
const cacheKey = `resolve:${url}`;
|
|
40280
40533
|
return this.cache.getOrSet(cacheKey, () => this.ipfsApi.resolveIPFSUrl(url), CacheTTL.GATEWAY);
|
|
40281
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
|
+
}
|
|
40282
40542
|
/**
|
|
40283
40543
|
* Clear all cached metadata and URLs for this service
|
|
40284
40544
|
*/
|
|
@@ -40384,6 +40644,15 @@ class Web3ApplicationService {
|
|
|
40384
40644
|
async resolveIPFSUrl(url) {
|
|
40385
40645
|
return this.metadataDomainService.resolveIPFSUrl(url);
|
|
40386
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
|
+
}
|
|
40387
40656
|
/**
|
|
40388
40657
|
* Fetch and process metadata from any URI with IPFS conversion.
|
|
40389
40658
|
*
|
|
@@ -40504,25 +40773,26 @@ class IPFSInfrastructureApi {
|
|
|
40504
40773
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
40505
40774
|
}
|
|
40506
40775
|
const rawMetadata = await response.json();
|
|
40507
|
-
// Resolve IPFS URLs
|
|
40508
|
-
const
|
|
40509
|
-
|
|
40510
|
-
|
|
40511
|
-
|
|
40512
|
-
|
|
40513
|
-
|
|
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
|
+
}
|
|
40514
40783
|
// Extract custom properties (anything not in ERC standard)
|
|
40515
40784
|
const customProperties = Object.fromEntries(Object.entries(rawMetadata).filter(([key]) => !['name', 'description', 'image', 'animation_url', 'external_url', 'attributes'].includes(key)));
|
|
40516
|
-
// Return normalized SDK format
|
|
40517
|
-
|
|
40518
|
-
name: rawMetadata.name
|
|
40519
|
-
description: rawMetadata.description
|
|
40520
|
-
imageUrl:
|
|
40521
|
-
animationUrl:
|
|
40522
|
-
externalUrl: rawMetadata.external_url
|
|
40523
|
-
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 : [],
|
|
40524
40793
|
...customProperties
|
|
40525
40794
|
};
|
|
40795
|
+
return result;
|
|
40526
40796
|
}
|
|
40527
40797
|
catch (error) {
|
|
40528
40798
|
console.error('Error fetching metadata:', error);
|
|
@@ -40645,8 +40915,20 @@ async function getExplorerUrlByChainId(getChainData, chainId, address, type) {
|
|
|
40645
40915
|
*
|
|
40646
40916
|
* ## IPFS Resolution
|
|
40647
40917
|
*
|
|
40648
|
-
*
|
|
40649
|
-
*
|
|
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
|
+
* ```
|
|
40650
40932
|
*/
|
|
40651
40933
|
class Web3Manager {
|
|
40652
40934
|
// TODO: Add PersEventEmitter support for blockchain events
|
|
@@ -40704,6 +40986,45 @@ class Web3Manager {
|
|
|
40704
40986
|
async fetchAndProcessMetadata(tokenUri) {
|
|
40705
40987
|
return this.web3ApplicationService.fetchAndProcessMetadata(tokenUri);
|
|
40706
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
|
+
}
|
|
40707
41028
|
/**
|
|
40708
41029
|
* Get blockchain chain data by chain ID
|
|
40709
41030
|
*
|
|
@@ -41010,23 +41331,32 @@ const useWeb3 = () => {
|
|
|
41010
41331
|
/**
|
|
41011
41332
|
* Resolve IPFS URL to HTTP gateway URL
|
|
41012
41333
|
*
|
|
41013
|
-
*
|
|
41334
|
+
* Converts an ipfs:// URL to an HTTPS URL using the tenant's configured IPFS gateway.
|
|
41335
|
+
* Non-IPFS URLs are returned unchanged.
|
|
41336
|
+
*
|
|
41014
41337
|
* @param url - IPFS URL to resolve (ipfs://...)
|
|
41015
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
|
+
* ```
|
|
41016
41346
|
*/
|
|
41017
41347
|
const resolveIPFSUrl = react.useCallback(async (url) => {
|
|
41018
|
-
if (!isInitialized || !
|
|
41348
|
+
if (!isInitialized || !web3) {
|
|
41019
41349
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
41020
41350
|
}
|
|
41021
41351
|
try {
|
|
41022
|
-
const result = await
|
|
41352
|
+
const result = await web3.resolveIPFSUrl(url);
|
|
41023
41353
|
return result;
|
|
41024
41354
|
}
|
|
41025
41355
|
catch (error) {
|
|
41026
41356
|
console.error('Failed to resolve IPFS URL:', error);
|
|
41027
41357
|
throw error;
|
|
41028
41358
|
}
|
|
41029
|
-
}, [
|
|
41359
|
+
}, [web3, isInitialized]);
|
|
41030
41360
|
/**
|
|
41031
41361
|
* Fetch and process token metadata from a URI
|
|
41032
41362
|
*
|
|
@@ -42680,8 +43010,7 @@ const useTransactions = () => {
|
|
|
42680
43010
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
42681
43011
|
}
|
|
42682
43012
|
try {
|
|
42683
|
-
|
|
42684
|
-
return result;
|
|
43013
|
+
return await sdk.transactions.getTransactionById(transactionId, include);
|
|
42685
43014
|
}
|
|
42686
43015
|
catch (error) {
|
|
42687
43016
|
console.error('Failed to fetch transaction:', error);
|
|
@@ -42730,8 +43059,7 @@ const useTransactions = () => {
|
|
|
42730
43059
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
42731
43060
|
}
|
|
42732
43061
|
try {
|
|
42733
|
-
|
|
42734
|
-
return result;
|
|
43062
|
+
return await sdk.transactions.getUserTransactionHistory(options);
|
|
42735
43063
|
}
|
|
42736
43064
|
catch (error) {
|
|
42737
43065
|
console.error('Failed to fetch transaction history:', error);
|
|
@@ -45201,6 +45529,7 @@ exports.CampaignManager = CampaignManager;
|
|
|
45201
45529
|
exports.CampaignService = CampaignService;
|
|
45202
45530
|
exports.ChainTypes = ChainTypes;
|
|
45203
45531
|
exports.ClientTransactionType = ClientTransactionType;
|
|
45532
|
+
exports.CommonErrorCodes = CommonErrorCodes;
|
|
45204
45533
|
exports.DEFAULT_PERS_CONFIG = DEFAULT_PERS_CONFIG;
|
|
45205
45534
|
exports.DPOP_STORAGE_KEYS = DPOP_STORAGE_KEYS;
|
|
45206
45535
|
exports.DPoPManager = DPoPManager;
|