@explorins/pers-sdk 2.1.15 → 2.1.16

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/README.md CHANGED
@@ -453,12 +453,12 @@ unsubscribe();
453
453
 
454
454
  | Domain | Manager | Events |
455
455
  |--------|---------|--------|
456
- | `authentication` | `sdk.auth` | `LOGIN_SUCCESS` |
457
- | `user` | `sdk.users` | `PROFILE_UPDATED` |
458
- | `business` | `sdk.businesses` | `BUSINESS_CREATED`, `BUSINESS_UPDATED`, `MEMBERSHIP_UPDATED` |
459
- | `campaign` | `sdk.campaigns` | `CAMPAIGN_CLAIMED` |
460
- | `redemption` | `sdk.redemptions` | `REDEMPTION_COMPLETED` |
461
- | `transaction` | `sdk.transactions` | `TRANSACTION_CREATED`, `TRANSACTION_SUBMITTED` |
456
+ | `authentication` | `sdk.auth` | `login_success` |
457
+ | `user` | `sdk.users` | `profile_updated` |
458
+ | `business` | `sdk.businesses` | `business_created`, `business_updated`, `membership_updated` |
459
+ | `campaign` | `sdk.campaigns` | `claim_success` |
460
+ | `redemption` | `sdk.redemptions` | `redeem_success` |
461
+ | `transaction` | `sdk.transactions` | `transaction_created`, `transaction_submitted` |
462
462
 
463
463
  #### Event Types
464
464
 
@@ -1109,6 +1109,12 @@ class PersApiClient {
1109
1109
  try {
1110
1110
  const refreshSuccessful = await this.refreshManager.attemptInternalRefresh();
1111
1111
  if (refreshSuccessful) {
1112
+ // Emit TOKEN_REFRESHED event so WS clients can retry if they gave up
1113
+ this._events?.emitSuccess({
1114
+ type: 'token_refreshed',
1115
+ domain: 'authentication',
1116
+ userMessage: 'Authentication token refreshed',
1117
+ });
1112
1118
  return await this.request(method, endpoint, body, { ...options, retryCount: 1 });
1113
1119
  }
1114
1120
  }
@@ -1495,7 +1501,7 @@ class PersEventEmitter {
1495
1501
  * ```typescript
1496
1502
  * sdk.events.emitSuccess({
1497
1503
  * domain: 'transaction', // Only business domains allowed
1498
- * type: 'CONFIRMED',
1504
+ * type: 'transaction_confirmed',
1499
1505
  * userMessage: 'Transaction confirmed!'
1500
1506
  * });
1501
1507
  * ```
@@ -1522,7 +1528,7 @@ class PersEventEmitter {
1522
1528
  * ```typescript
1523
1529
  * sdk.events.emitError({
1524
1530
  * domain: 'validation', // Technical domains allowed
1525
- * type: 'INVALID_INPUT',
1531
+ * type: 'validation_failed',
1526
1532
  * userMessage: 'Please check your input'
1527
1533
  * });
1528
1534
  * ```
@@ -1656,7 +1662,7 @@ class AuthManager {
1656
1662
  : await authService.loginUser(jwtToken);
1657
1663
  this.events?.emitSuccess({
1658
1664
  domain: 'authentication',
1659
- type: 'LOGIN_SUCCESS',
1665
+ type: 'login_success',
1660
1666
  userMessage: 'Successfully logged in'
1661
1667
  });
1662
1668
  return result;
@@ -2029,7 +2035,7 @@ class UserManager {
2029
2035
  const result = await this.userService.updateRemoteUser(userData);
2030
2036
  this.events?.emitSuccess({
2031
2037
  domain: 'user',
2032
- type: 'PROFILE_UPDATED',
2038
+ type: 'profile_updated',
2033
2039
  userMessage: 'Profile updated successfully',
2034
2040
  details: { userId: result.id }
2035
2041
  });
@@ -2309,7 +2315,7 @@ class UserManager {
2309
2315
  const result = await this.userService.deleteUser(identifier);
2310
2316
  this.events?.emitSuccess({
2311
2317
  domain: 'user',
2312
- type: 'USER_DELETED',
2318
+ type: 'user_deleted',
2313
2319
  userMessage: 'User deleted successfully',
2314
2320
  details: { identifier }
2315
2321
  });
@@ -2342,7 +2348,7 @@ class UserManager {
2342
2348
  const result = await this.userService.restoreUser(identifier);
2343
2349
  this.events?.emitSuccess({
2344
2350
  domain: 'user',
2345
- type: 'USER_RESTORED',
2351
+ type: 'user_restored',
2346
2352
  userMessage: 'User restored successfully',
2347
2353
  details: { identifier, userId: result.id }
2348
2354
  });
@@ -3032,7 +3038,7 @@ class BusinessManager {
3032
3038
  const result = await this.businessService.createBusinessByDisplayName(displayName);
3033
3039
  this.events?.emitSuccess({
3034
3040
  domain: 'business',
3035
- type: 'BUSINESS_CREATED',
3041
+ type: 'business_created',
3036
3042
  userMessage: 'Business created successfully',
3037
3043
  details: { businessId: result.id, displayName: result.displayName }
3038
3044
  });
@@ -3067,7 +3073,7 @@ class BusinessManager {
3067
3073
  const result = await this.businessService.updateBusiness(businessId, businessData);
3068
3074
  this.events?.emitSuccess({
3069
3075
  domain: 'business',
3070
- type: 'BUSINESS_UPDATED',
3076
+ type: 'business_updated',
3071
3077
  userMessage: 'Business updated successfully',
3072
3078
  details: { businessId: result.id, displayName: result.displayName }
3073
3079
  });
@@ -3239,7 +3245,7 @@ class BusinessManager {
3239
3245
  const result = await this.membershipService.updateMemberRole(businessId, userId, newRole);
3240
3246
  this.events?.emitSuccess({
3241
3247
  domain: 'business',
3242
- type: 'MEMBERSHIP_UPDATED',
3248
+ type: 'membership_updated',
3243
3249
  userMessage: 'Membership role updated',
3244
3250
  details: { businessId, userId, role: newRole }
3245
3251
  });
@@ -3517,7 +3523,7 @@ class CampaignManager {
3517
3523
  const result = await this.campaignService.claimCampaign(claimRequest);
3518
3524
  this.events?.emitSuccess({
3519
3525
  domain: 'campaign',
3520
- type: 'CLAIM_SUCCESS',
3526
+ type: 'claim_success',
3521
3527
  userMessage: 'Campaign reward claimed successfully',
3522
3528
  details: { campaignId: claimRequest.campaignId }
3523
3529
  });
@@ -3785,7 +3791,7 @@ class CampaignManager {
3785
3791
  const result = await this.campaignService.createCampaignTrigger(data);
3786
3792
  this.events?.emitSuccess({
3787
3793
  domain: 'campaign',
3788
- type: 'CAMPAIGN_TRIGGER_CREATED',
3794
+ type: 'campaign_trigger_created',
3789
3795
  userMessage: `Trigger "${data.name}" created successfully`,
3790
3796
  details: { triggerId: result.id, name: data.name }
3791
3797
  });
@@ -3810,7 +3816,7 @@ class CampaignManager {
3810
3816
  const result = await this.campaignService.updateCampaignTrigger(triggerId, data);
3811
3817
  this.events?.emitSuccess({
3812
3818
  domain: 'campaign',
3813
- type: 'CAMPAIGN_TRIGGER_UPDATED',
3819
+ type: 'campaign_trigger_updated',
3814
3820
  userMessage: 'Trigger updated successfully',
3815
3821
  details: { triggerId, updates: Object.keys(data) }
3816
3822
  });
@@ -3831,7 +3837,7 @@ class CampaignManager {
3831
3837
  const result = await this.campaignService.deleteCampaignTrigger(triggerId);
3832
3838
  this.events?.emitSuccess({
3833
3839
  domain: 'campaign',
3834
- type: 'CAMPAIGN_TRIGGER_DELETED',
3840
+ type: 'campaign_trigger_deleted',
3835
3841
  userMessage: 'Trigger deleted successfully',
3836
3842
  details: { triggerId }
3837
3843
  });
@@ -3860,7 +3866,7 @@ class CampaignManager {
3860
3866
  const result = await this.campaignService.setCampaignTrigger(campaignId, triggerId);
3861
3867
  this.events?.emitSuccess({
3862
3868
  domain: 'campaign',
3863
- type: 'CAMPAIGN_TRIGGER_ASSIGNED',
3869
+ type: 'campaign_trigger_assigned',
3864
3870
  userMessage: 'Trigger assigned to campaign',
3865
3871
  details: { campaignId, triggerId }
3866
3872
  });
@@ -3889,7 +3895,7 @@ class CampaignManager {
3889
3895
  const result = await this.campaignService.removeCampaignTrigger(campaignId, triggerId);
3890
3896
  this.events?.emitSuccess({
3891
3897
  domain: 'campaign',
3892
- type: 'CAMPAIGN_TRIGGER_REMOVED',
3898
+ type: 'campaign_trigger_removed',
3893
3899
  userMessage: 'Trigger removed from campaign',
3894
3900
  details: { campaignId, triggerId }
3895
3901
  });
@@ -4225,7 +4231,7 @@ class CampaignManager {
4225
4231
  const result = await this.campaignService.assignTriggerSourceToCampaign(campaignId, triggerSourceId);
4226
4232
  this.events?.emitSuccess({
4227
4233
  domain: 'campaign',
4228
- type: 'TRIGGER_SOURCE_ASSIGNED',
4234
+ type: 'trigger_source_assigned',
4229
4235
  userMessage: 'Trigger source assigned to campaign',
4230
4236
  details: { campaignId, triggerSourceId }
4231
4237
  });
@@ -4573,7 +4579,7 @@ class RedemptionManager {
4573
4579
  const result = await this.redemptionService.redeemRedemption(redemptionId);
4574
4580
  this.events?.emitSuccess({
4575
4581
  domain: 'redemption',
4576
- type: 'REDEEM_SUCCESS',
4582
+ type: 'redeem_success',
4577
4583
  userMessage: 'Reward redeemed successfully',
4578
4584
  details: { redemptionId }
4579
4585
  });
@@ -5091,7 +5097,7 @@ class TransactionManager {
5091
5097
  const result = await this.transactionService.createTransaction(transactionData);
5092
5098
  this.events?.emitSuccess({
5093
5099
  domain: 'transaction',
5094
- type: 'TRANSACTION_CREATED',
5100
+ type: 'transaction_created',
5095
5101
  userMessage: 'Transaction created successfully',
5096
5102
  details: { transactionId: result.transaction?.id }
5097
5103
  });
@@ -5330,7 +5336,7 @@ class TransactionManager {
5330
5336
  const result = await this.transactionService.submitSignedTransaction(signedTxData);
5331
5337
  this.events?.emitSuccess({
5332
5338
  domain: 'transaction',
5333
- type: 'TRANSACTION_SUBMITTED',
5339
+ type: 'transaction_submitted',
5334
5340
  userMessage: 'Transaction submitted successfully',
5335
5341
  details: { transactionId: result.transaction?.id }
5336
5342
  });
@@ -7254,7 +7260,7 @@ class TriggerSourceManager {
7254
7260
  const result = await this.triggerSourceService.createTriggerSource(triggerSource);
7255
7261
  this.events?.emitSuccess({
7256
7262
  domain: 'trigger-source',
7257
- type: 'TRIGGER_SOURCE_CREATED',
7263
+ type: 'trigger_source_created',
7258
7264
  userMessage: 'Trigger source created successfully',
7259
7265
  details: { triggerSourceId: result.id, type: result.type }
7260
7266
  });
@@ -7286,7 +7292,7 @@ class TriggerSourceManager {
7286
7292
  const result = await this.triggerSourceService.updateTriggerSource(triggerSourceId, triggerSource);
7287
7293
  this.events?.emitSuccess({
7288
7294
  domain: 'trigger-source',
7289
- type: 'TRIGGER_SOURCE_UPDATED',
7295
+ type: 'trigger_source_updated',
7290
7296
  userMessage: 'Trigger source updated successfully',
7291
7297
  details: { triggerSourceId }
7292
7298
  });
@@ -7313,7 +7319,7 @@ class TriggerSourceManager {
7313
7319
  const result = await this.triggerSourceService.deleteTriggerSource(triggerSourceId);
7314
7320
  this.events?.emitSuccess({
7315
7321
  domain: 'trigger-source',
7316
- type: 'TRIGGER_SOURCE_DELETED',
7322
+ type: 'trigger_source_deleted',
7317
7323
  userMessage: 'Trigger source deleted successfully',
7318
7324
  details: { triggerSourceId }
7319
7325
  });
@@ -7787,7 +7793,7 @@ class WebhookManager {
7787
7793
  const result = await this.webhookService.createWebhook(webhook);
7788
7794
  this.events?.emitSuccess({
7789
7795
  domain: 'webhook',
7790
- type: 'WEBHOOK_CREATED',
7796
+ type: 'webhook_created',
7791
7797
  userMessage: 'Webhook created successfully',
7792
7798
  details: { webhookId: result.id, name: result.name }
7793
7799
  });
@@ -7804,7 +7810,7 @@ class WebhookManager {
7804
7810
  const result = await this.webhookService.updateWebhook(webhookId, webhook);
7805
7811
  this.events?.emitSuccess({
7806
7812
  domain: 'webhook',
7807
- type: 'WEBHOOK_UPDATED',
7813
+ type: 'webhook_updated',
7808
7814
  userMessage: 'Webhook updated successfully',
7809
7815
  details: { webhookId }
7810
7816
  });
@@ -7832,7 +7838,7 @@ class WebhookManager {
7832
7838
  const result = await this.webhookService.deleteWebhook(webhookId);
7833
7839
  this.events?.emitSuccess({
7834
7840
  domain: 'webhook',
7835
- type: 'WEBHOOK_DELETED',
7841
+ type: 'webhook_deleted',
7836
7842
  userMessage: 'Webhook deleted successfully',
7837
7843
  details: { webhookId }
7838
7844
  });
@@ -7889,7 +7895,7 @@ class WebhookManager {
7889
7895
  const result = await this.webhookService.post(hookId, body);
7890
7896
  this.events?.emitSuccess({
7891
7897
  domain: 'webhook',
7892
- type: 'WEBHOOK_TRIGGERED',
7898
+ type: 'webhook_triggered',
7893
7899
  userMessage: 'Webhook triggered',
7894
7900
  details: { hookId, executionId: result.executionId }
7895
7901
  });
@@ -8459,12 +8465,22 @@ class WalletEventsManager {
8459
8465
  this.client = null;
8460
8466
  this.pendingHandlers = [];
8461
8467
  this.unsubscribes = [];
8468
+ // Track if WS gave up reconnecting (so we can retry on token refresh)
8469
+ this.reconnectGaveUp = false;
8470
+ this.lastSubscriptions = { wallets: [], chains: [] };
8462
8471
  this.config = {
8463
8472
  autoReconnect: true,
8464
8473
  connectionTimeout: 30000,
8465
8474
  debug: false,
8466
8475
  ...config,
8467
8476
  };
8477
+ // Subscribe to auth events to retry WS connection when tokens are refreshed
8478
+ this.authEventUnsubscribe = this.eventEmitter.subscribe((event) => {
8479
+ if (event.type === 'token_refreshed' && this.reconnectGaveUp) {
8480
+ // Tokens were refreshed and WS had given up - retry connection
8481
+ this.retryAfterTokenRefresh();
8482
+ }
8483
+ }, { domains: ['authentication'], levels: ['success'] });
8468
8484
  }
8469
8485
  /**
8470
8486
  * Connect to real-time wallet events
@@ -8493,8 +8509,11 @@ class WalletEventsManager {
8493
8509
  const wsUrl = this.config.wsUrl
8494
8510
  || sdkConfig.walletEventsWsUrl
8495
8511
  || buildWalletEventsWsUrl(sdkConfig.environment);
8496
- // Create token refresher that fetches fresh token from auth provider
8512
+ // Create token refresher that ensures valid token before reconnecting
8513
+ // This triggers actual token refresh if expired, not just retrieval
8497
8514
  const tokenRefresher = async () => {
8515
+ // Ensure token is refreshed if expired (calls refresh API if needed)
8516
+ await this.apiClient.ensureValidToken();
8498
8517
  const freshToken = await authProvider.getToken();
8499
8518
  if (!freshToken) {
8500
8519
  throw new Error('Failed to refresh token');
@@ -8509,6 +8528,32 @@ class WalletEventsManager {
8509
8528
  tokenRefresher,
8510
8529
  });
8511
8530
  await this.client.connect(token);
8531
+ // Reset gave-up flag on successful connection
8532
+ this.reconnectGaveUp = false;
8533
+ // Track previous state to detect reconnections and give-ups
8534
+ let previousState = 'connected';
8535
+ // Clean up previous state change listener (prevent duplicate listeners)
8536
+ this.stateChangeUnsubscribe?.();
8537
+ // Listen for state changes
8538
+ this.stateChangeUnsubscribe = this.client.onStateChange((state) => {
8539
+ if (state === 'disconnected' && previousState === 'reconnecting') {
8540
+ // Transitioned from reconnecting to disconnected = exhausted all attempts
8541
+ this.reconnectGaveUp = true;
8542
+ }
8543
+ else if (state === 'connected') {
8544
+ this.reconnectGaveUp = false;
8545
+ // Emit reconnected event so apps can refresh state (catch missed events)
8546
+ if (previousState === 'reconnecting') {
8547
+ this.eventEmitter.emitSuccess({
8548
+ type: 'wallet_reconnected',
8549
+ domain: 'wallet',
8550
+ userMessage: 'Wallet events reconnected',
8551
+ details: { previousState }
8552
+ });
8553
+ }
8554
+ }
8555
+ previousState = state;
8556
+ });
8512
8557
  // Clear previous unsubscribes on new connection (prevent memory leak)
8513
8558
  this.unsubscribes.forEach(unsub => unsub());
8514
8559
  this.unsubscribes = [];
@@ -8525,11 +8570,26 @@ class WalletEventsManager {
8525
8570
  * Disconnect from real-time events
8526
8571
  */
8527
8572
  disconnect() {
8573
+ // Clear gave-up flag to prevent auto-reconnect after intentional disconnect
8574
+ this.reconnectGaveUp = false;
8575
+ this.stateChangeUnsubscribe?.();
8576
+ this.stateChangeUnsubscribe = undefined;
8528
8577
  this.unsubscribes.forEach(unsub => unsub());
8529
8578
  this.unsubscribes = [];
8530
8579
  this.client?.disconnect();
8531
8580
  this.client = null;
8532
8581
  }
8582
+ /**
8583
+ * Full cleanup - disconnect and remove all subscriptions including auth listener
8584
+ * Call this when completely done with the manager (e.g., SDK disposal)
8585
+ */
8586
+ destroy() {
8587
+ this.disconnect();
8588
+ this.authEventUnsubscribe?.();
8589
+ this.authEventUnsubscribe = undefined;
8590
+ this.reconnectGaveUp = false;
8591
+ this.lastSubscriptions = { wallets: [], chains: [] };
8592
+ }
8533
8593
  // ─────────────────────────────────────────────────────────────────────────────
8534
8594
  // Subscription Methods (v1.2.0)
8535
8595
  // ─────────────────────────────────────────────────────────────────────────────
@@ -8554,6 +8614,8 @@ class WalletEventsManager {
8554
8614
  if (!this.client) {
8555
8615
  throw new Error('Not connected. Call connect() first.');
8556
8616
  }
8617
+ // Save subscriptions for auto-resubscribe on reconnect
8618
+ this.lastSubscriptions.wallets = wallets;
8557
8619
  return this.client.subscribeWallets(wallets);
8558
8620
  }
8559
8621
  /**
@@ -8575,6 +8637,8 @@ class WalletEventsManager {
8575
8637
  if (!this.client) {
8576
8638
  throw new Error('Not connected. Call connect() first.');
8577
8639
  }
8640
+ // Save subscriptions for auto-resubscribe on reconnect
8641
+ this.lastSubscriptions.chains = chains;
8578
8642
  return this.client.subscribeChains(chains);
8579
8643
  }
8580
8644
  /**
@@ -8664,6 +8728,36 @@ class WalletEventsManager {
8664
8728
  isConnected() {
8665
8729
  return this.getState() === 'connected';
8666
8730
  }
8731
+ /**
8732
+ * Check if WS reconnection gave up (exhausted all attempts)
8733
+ * Used to determine if we should retry on token refresh
8734
+ */
8735
+ hasReconnectGivenUp() {
8736
+ return this.reconnectGaveUp;
8737
+ }
8738
+ /**
8739
+ * Retry connection after token refresh
8740
+ * Called when auth tokens are refreshed and WS had previously given up
8741
+ * Automatically resubscribes to previous subscriptions
8742
+ */
8743
+ async retryAfterTokenRefresh() {
8744
+ if (!this.reconnectGaveUp) {
8745
+ return; // Not in gave-up state, nothing to retry
8746
+ }
8747
+ try {
8748
+ await this.connect();
8749
+ // Restore previous subscriptions
8750
+ if (this.lastSubscriptions.wallets.length > 0) {
8751
+ await this.subscribeWallets(this.lastSubscriptions.wallets);
8752
+ }
8753
+ if (this.lastSubscriptions.chains.length > 0) {
8754
+ await this.subscribeChains(this.lastSubscriptions.chains);
8755
+ }
8756
+ }
8757
+ catch (error) {
8758
+ console.warn('[WalletEventsManager] Retry after token refresh failed:', error);
8759
+ }
8760
+ }
8667
8761
  /**
8668
8762
  * Get connection info (wallets, active chains)
8669
8763
  */
@@ -8868,7 +8962,7 @@ class PersSDK {
8868
8962
  }
8869
8963
  // Listen for login success events (both fresh login and session restoration)
8870
8964
  this._events.subscribe((event) => {
8871
- if (event.level === 'success' && (event.type === 'LOGIN_SUCCESS' || event.type === 'session_restored')) {
8965
+ if (event.level === 'success' && (event.type === 'login_success' || event.type === 'session_restored')) {
8872
8966
  // Auto-connect and subscribe to wallet events (fire and forget, log errors)
8873
8967
  this.connectWalletEvents().catch((err) => {
8874
8968
  console.warn('[PersSDK] Failed to auto-connect wallet events:', err.message);
@@ -9482,4 +9576,4 @@ function createPersSDK(httpClient, config) {
9482
9576
  }
9483
9577
 
9484
9578
  export { AuthStatus as A, BusinessManager as B, CampaignManager as C, DefaultAuthProvider as D, FileApi as E, FileManager as F, FileService as G, ApiKeyApi as H, WebhookApi as I, WebhookService as J, PersEventsClient as K, LocalStorageTokenStorage as L, MemoryTokenStorage as M, createPersEventsClient as N, PersSDK as P, RedemptionManager as R, SDK_NAME as S, TokenManager as T, UserManager as U, WebDPoPCryptoProvider as W, AuthTokenManager as a, AUTH_STORAGE_KEYS as b, createPersSDK as c, DPOP_STORAGE_KEYS as d, SDK_VERSION as e, SDK_USER_AGENT as f, PersApiClient as g, DEFAULT_PERS_CONFIG as h, buildApiRoot as i, buildWalletEventsWsUrl as j, StaticJwtAuthProvider as k, AuthApi as l, mergeWithDefaults as m, AuthService as n, DPoPManager as o, PersEventEmitter as p, AuthManager as q, UserStatusManager as r, TransactionManager as s, PurchaseManager as t, ApiKeyManager as u, AnalyticsManager as v, DonationManager as w, TriggerSourceManager as x, WebhookManager as y, WalletEventsManager as z };
9485
- //# sourceMappingURL=pers-sdk-BiP7UMJ3.js.map
9579
+ //# sourceMappingURL=pers-sdk-BkZkDQIe.js.map