@explorins/pers-sdk 2.1.23 → 2.1.24

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.
Files changed (107) hide show
  1. package/dist/business/api/business-api.d.ts +6 -9
  2. package/dist/business/api/business-api.d.ts.map +1 -1
  3. package/dist/business/index.d.ts +1 -0
  4. package/dist/business/index.d.ts.map +1 -1
  5. package/dist/business/services/business-service.d.ts +8 -5
  6. package/dist/business/services/business-service.d.ts.map +1 -1
  7. package/dist/business.cjs +1 -1
  8. package/dist/business.js +1 -1
  9. package/dist/campaign/api/campaign-api.d.ts +4 -12
  10. package/dist/campaign/api/campaign-api.d.ts.map +1 -1
  11. package/dist/campaign/index.d.ts +2 -1
  12. package/dist/campaign/index.d.ts.map +1 -1
  13. package/dist/campaign/models/index.d.ts +16 -6
  14. package/dist/campaign/models/index.d.ts.map +1 -1
  15. package/dist/campaign/services/campaign-service.d.ts +9 -26
  16. package/dist/campaign/services/campaign-service.d.ts.map +1 -1
  17. package/dist/campaign.cjs +10 -3
  18. package/dist/campaign.cjs.map +1 -1
  19. package/dist/campaign.js +10 -3
  20. package/dist/campaign.js.map +1 -1
  21. package/dist/chunks/{business-membership-service-BfHzIQlc.cjs → business-membership-service-DXLG5fP9.cjs} +17 -2
  22. package/dist/chunks/business-membership-service-DXLG5fP9.cjs.map +1 -0
  23. package/dist/chunks/{business-membership-service-CFa-TI39.js → business-membership-service-IyY5CkL0.js} +17 -2
  24. package/dist/chunks/business-membership-service-IyY5CkL0.js.map +1 -0
  25. package/dist/chunks/{pers-sdk-rmjhPvHo.cjs → pers-sdk-DXCcAgUS.cjs} +370 -85
  26. package/dist/chunks/pers-sdk-DXCcAgUS.cjs.map +1 -0
  27. package/dist/chunks/{pers-sdk-DgSbePI0.js → pers-sdk-DkCRHY5i.js} +370 -85
  28. package/dist/chunks/pers-sdk-DkCRHY5i.js.map +1 -0
  29. package/dist/chunks/{redemption-service-B6ZlAV6_.cjs → redemption-service-5Mu78Sne.cjs} +21 -5
  30. package/dist/chunks/redemption-service-5Mu78Sne.cjs.map +1 -0
  31. package/dist/chunks/{redemption-service-C0vys0OQ.js → redemption-service-CoODony4.js} +21 -5
  32. package/dist/chunks/redemption-service-CoODony4.js.map +1 -0
  33. package/dist/chunks/{tenant-manager-BIQONvmF.cjs → tenant-manager-D3toTiB9.cjs} +20 -2
  34. package/dist/chunks/{tenant-manager-BIQONvmF.cjs.map → tenant-manager-D3toTiB9.cjs.map} +1 -1
  35. package/dist/chunks/{tenant-manager-C5txKrZA.js → tenant-manager-D8-eD2CZ.js} +20 -2
  36. package/dist/chunks/{tenant-manager-C5txKrZA.js.map → tenant-manager-D8-eD2CZ.js.map} +1 -1
  37. package/dist/chunks/{tenant-service-Ch-V3mj-.cjs → tenant-service-8vZWmTLV.cjs} +16 -1
  38. package/dist/chunks/tenant-service-8vZWmTLV.cjs.map +1 -0
  39. package/dist/chunks/{tenant-service-BnTAZCxS.js → tenant-service-DlhdZAs9.js} +16 -1
  40. package/dist/chunks/tenant-service-DlhdZAs9.js.map +1 -0
  41. package/dist/chunks/{web3-manager-D3VYTPBZ.js → web3-manager-DZXBaBh0.js} +2 -2
  42. package/dist/chunks/{web3-manager-D3VYTPBZ.js.map → web3-manager-DZXBaBh0.js.map} +1 -1
  43. package/dist/chunks/{web3-manager-C891F2cd.cjs → web3-manager-ojRB6_ty.cjs} +2 -2
  44. package/dist/chunks/{web3-manager-C891F2cd.cjs.map → web3-manager-ojRB6_ty.cjs.map} +1 -1
  45. package/dist/core/auth/api/auth-api.d.ts +37 -2
  46. package/dist/core/auth/api/auth-api.d.ts.map +1 -1
  47. package/dist/core/auth/services/auth-service.d.ts +24 -3
  48. package/dist/core/auth/services/auth-service.d.ts.map +1 -1
  49. package/dist/core/events/event-emitter.d.ts +13 -1
  50. package/dist/core/events/event-emitter.d.ts.map +1 -1
  51. package/dist/core/events/event-types.d.ts +11 -0
  52. package/dist/core/events/event-types.d.ts.map +1 -1
  53. package/dist/core/pers-config.d.ts +13 -0
  54. package/dist/core/pers-config.d.ts.map +1 -1
  55. package/dist/core.cjs +5 -5
  56. package/dist/core.js +5 -5
  57. package/dist/index.cjs +5 -5
  58. package/dist/index.d.ts +2 -2
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +5 -5
  61. package/dist/managers/auth-manager.d.ts +61 -3
  62. package/dist/managers/auth-manager.d.ts.map +1 -1
  63. package/dist/managers/business-manager.d.ts +4 -4
  64. package/dist/managers/business-manager.d.ts.map +1 -1
  65. package/dist/managers/campaign-manager.d.ts +33 -39
  66. package/dist/managers/campaign-manager.d.ts.map +1 -1
  67. package/dist/managers/events-manager.d.ts.map +1 -1
  68. package/dist/managers/index.d.ts +1 -0
  69. package/dist/managers/index.d.ts.map +1 -1
  70. package/dist/managers/redemption-manager.d.ts +25 -3
  71. package/dist/managers/redemption-manager.d.ts.map +1 -1
  72. package/dist/managers/tenant-manager.d.ts +16 -0
  73. package/dist/managers/tenant-manager.d.ts.map +1 -1
  74. package/dist/node.cjs +5 -5
  75. package/dist/node.js +5 -5
  76. package/dist/package.json +2 -2
  77. package/dist/pers-sdk.d.ts +12 -6
  78. package/dist/pers-sdk.d.ts.map +1 -1
  79. package/dist/redemption/api/redemption-api.d.ts +5 -11
  80. package/dist/redemption/api/redemption-api.d.ts.map +1 -1
  81. package/dist/redemption/index.d.ts +2 -1
  82. package/dist/redemption/index.d.ts.map +1 -1
  83. package/dist/redemption/models/index.d.ts +17 -3
  84. package/dist/redemption/models/index.d.ts.map +1 -1
  85. package/dist/redemption/services/redemption-service.d.ts +13 -18
  86. package/dist/redemption/services/redemption-service.d.ts.map +1 -1
  87. package/dist/redemption.cjs +1 -1
  88. package/dist/redemption.js +1 -1
  89. package/dist/tenant/api/tenant-api.d.ts +7 -0
  90. package/dist/tenant/api/tenant-api.d.ts.map +1 -1
  91. package/dist/tenant/services/tenant-service.d.ts +4 -0
  92. package/dist/tenant/services/tenant-service.d.ts.map +1 -1
  93. package/dist/tenant.cjs +1 -1
  94. package/dist/tenant.js +1 -1
  95. package/dist/web3-manager.cjs +3 -3
  96. package/dist/web3-manager.js +3 -3
  97. package/dist/web3.cjs +3 -3
  98. package/dist/web3.js +3 -3
  99. package/package.json +2 -2
  100. package/dist/chunks/business-membership-service-BfHzIQlc.cjs.map +0 -1
  101. package/dist/chunks/business-membership-service-CFa-TI39.js.map +0 -1
  102. package/dist/chunks/pers-sdk-DgSbePI0.js.map +0 -1
  103. package/dist/chunks/pers-sdk-rmjhPvHo.cjs.map +0 -1
  104. package/dist/chunks/redemption-service-B6ZlAV6_.cjs.map +0 -1
  105. package/dist/chunks/redemption-service-C0vys0OQ.js.map +0 -1
  106. package/dist/chunks/tenant-service-BnTAZCxS.js.map +0 -1
  107. package/dist/chunks/tenant-service-Ch-V3mj-.cjs.map +0 -1
@@ -5,12 +5,12 @@ var index = require('./index-CVuttuU8.cjs');
5
5
  var user = require('../user.cjs');
6
6
  var userStatus = require('../user-status.cjs');
7
7
  var tokenService = require('./token-service-C1xe11OX.cjs');
8
- var businessMembershipService = require('./business-membership-service-BfHzIQlc.cjs');
8
+ var businessMembershipService = require('./business-membership-service-DXLG5fP9.cjs');
9
9
  var campaign = require('../campaign.cjs');
10
- var redemptionService = require('./redemption-service-B6ZlAV6_.cjs');
10
+ var redemptionService = require('./redemption-service-5Mu78Sne.cjs');
11
11
  var transactionRequest_builder = require('./transaction-request.builder-D8pIzjYD.cjs');
12
12
  var paymentService = require('./payment-service-Bkw7ZXev.cjs');
13
- var tenantManager = require('./tenant-manager-BIQONvmF.cjs');
13
+ var tenantManager = require('./tenant-manager-D3toTiB9.cjs');
14
14
  var paginationUtils = require('./pagination-utils-B2jRHMSO.cjs');
15
15
  var analyticsService = require('./analytics-service-CF9AsMQH.cjs');
16
16
  var donation = require('../donation.cjs');
@@ -32,7 +32,8 @@ const DEFAULT_PERS_CONFIG = {
32
32
  retries: 3,
33
33
  tokenRefreshMargin: 60, // Refresh tokens 60 seconds before expiry
34
34
  backgroundRefreshThreshold: 30, // Use background refresh if >30s remaining
35
- captureWalletEvents: true // Auto-connect to wallet events after auth
35
+ captureWalletEvents: true, // Auto-connect to wallet events after auth
36
+ autoRestoreSession: true // Auto-restore session from stored tokens on init
36
37
  };
37
38
  /**
38
39
  * Build the API root URL based on config
@@ -99,11 +100,28 @@ class AuthApi {
99
100
  }
100
101
  /**
101
102
  * Login tenant admin with JWT
103
+ *
104
+ * Authenticates an admin in a tenant context.
105
+ *
106
+ * @param jwt - Authentication token (Firebase JWT)
107
+ * @param options - Tenant authentication options (tenantId for multi-tenant admins)
108
+ * @returns Session response with tenant context
109
+ * @throws MultipleContextSelectionError when tenantId is required but not provided
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * // Single tenant - auto-selects
114
+ * const response = await authApi.loginTenantAdmin(jwt);
115
+ *
116
+ * // Multiple tenants - explicit selection
117
+ * const response = await authApi.loginTenantAdmin(jwt, { tenantId: 'tenant-123' });
118
+ * ```
102
119
  */
103
- async loginTenantAdmin(jwt) {
120
+ async loginTenantAdmin(jwt, options) {
104
121
  const body = {
105
122
  authToken: jwt,
106
- authType: persShared.AccountOwnerType.TENANT
123
+ authType: persShared.AccountOwnerType.TENANT,
124
+ context: options?.tenantId ? { tenantId: options.tenantId } : undefined
107
125
  };
108
126
  return this.apiClient.post(`${this.basePath}/token`, body, { bypassAuth: true });
109
127
  }
@@ -161,6 +179,30 @@ class AuthApi {
161
179
  async refreshAccessToken(refreshToken) {
162
180
  return this.apiClient.post(`${this.basePath}/refresh`, { refreshToken }, { bypassAuth: true, isRefreshRequest: true });
163
181
  }
182
+ // ==========================================
183
+ // IDENTITY VERIFICATION (for session restore)
184
+ // Note: These duplicate calls in domain APIs (user-api, business-api)
185
+ // but are kept here to avoid circular dependencies during initialization.
186
+ // If endpoints change, update both locations.
187
+ // ==========================================
188
+ /**
189
+ * Get current authenticated user
190
+ */
191
+ async getCurrentUser() {
192
+ return this.apiClient.get('/users/me');
193
+ }
194
+ /**
195
+ * Get current business context
196
+ */
197
+ async getCurrentBusiness() {
198
+ return this.apiClient.get('/businesses/me');
199
+ }
200
+ /**
201
+ * Get current admin context
202
+ */
203
+ async getCurrentAdmin() {
204
+ return this.apiClient.get('/admins/me');
205
+ }
164
206
  }
165
207
 
166
208
  /**
@@ -185,6 +227,12 @@ exports.AuthStatus = void 0;
185
227
  AuthStatus["SESSION_RESTORATION_FAILED"] = "session_restoration_failed";
186
228
  })(exports.AuthStatus || (exports.AuthStatus = {}));
187
229
 
230
+ /**
231
+ * Type guard to check if provider implements extended storage methods
232
+ */
233
+ function isExtendedProvider(provider) {
234
+ return 'setAuthType' in provider && typeof provider.setAuthType === 'function';
235
+ }
188
236
  /**
189
237
  * Platform-agnostic authentication service
190
238
  * Handles login, token refresh, and storage operations
@@ -196,6 +244,12 @@ class AuthService {
196
244
  this.activeRefreshPromise = null;
197
245
  this.currentAuthStatus = exports.AuthStatus.UNAUTHENTICATED;
198
246
  }
247
+ /**
248
+ * Get extended provider if available, null otherwise
249
+ */
250
+ get extendedProvider() {
251
+ return this.authProvider && isExtendedProvider(this.authProvider) ? this.authProvider : null;
252
+ }
199
253
  /**
200
254
  * Emit auth status change to the app
201
255
  */
@@ -203,9 +257,10 @@ class AuthService {
203
257
  if (this.currentAuthStatus === status)
204
258
  return; // No change
205
259
  this.currentAuthStatus = status;
206
- if (this.authProvider && typeof this.authProvider.onAuthStatusChange === 'function') {
260
+ const extended = this.extendedProvider;
261
+ if (extended?.onAuthStatusChange) {
207
262
  try {
208
- await this.authProvider.onAuthStatusChange(status);
263
+ await extended.onAuthStatusChange(status);
209
264
  }
210
265
  catch (error) {
211
266
  console.warn('[AuthService] Auth status change callback failed:', error);
@@ -217,9 +272,14 @@ class AuthService {
217
272
  // ==========================================
218
273
  /**
219
274
  * Login tenant admin with JWT
275
+ *
276
+ * @param jwt - Authentication token (Firebase JWT)
277
+ * @param options - Tenant authentication options (tenantId for multi-tenant admins)
278
+ * @returns Session response with tenant context
279
+ * @throws Error with code MULTIPLE_CONTEXT_SELECTION_REQUIRED when tenantId is required but not provided
220
280
  */
221
- async loginTenantAdmin(jwt) {
222
- const response = await this.authApi.loginTenantAdmin(jwt);
281
+ async loginTenantAdmin(jwt, options) {
282
+ const response = await this.authApi.loginTenantAdmin(jwt, options);
223
283
  if (this.authProvider && response.accessToken) {
224
284
  await this.storeTokens(response.accessToken, response.refreshToken, persShared.AccountOwnerType.TENANT, jwt);
225
285
  }
@@ -300,9 +360,13 @@ class AuthService {
300
360
  if (!tokenToUse) {
301
361
  throw new Error('No refresh token available for token refresh');
302
362
  }
363
+ // Get the current authType to preserve it after refresh
364
+ const extended = this.extendedProvider;
365
+ const currentAuthType = extended?.getAuthType ? await extended.getAuthType() ?? undefined : undefined;
303
366
  const response = await this.authApi.refreshAccessToken(tokenToUse);
304
367
  if (this.authProvider && response.accessToken) {
305
- await this.storeTokens(response.accessToken, response.refreshToken);
368
+ // Preserve the authType during refresh
369
+ await this.storeTokens(response.accessToken, response.refreshToken, currentAuthType);
306
370
  }
307
371
  return response;
308
372
  }
@@ -340,6 +404,27 @@ class AuthService {
340
404
  return !!token;
341
405
  }
342
406
  // ==========================================
407
+ // CONTEXT RETRIEVAL
408
+ // ==========================================
409
+ /**
410
+ * Get current authenticated user
411
+ */
412
+ async getCurrentUser() {
413
+ return this.authApi.getCurrentUser();
414
+ }
415
+ /**
416
+ * Get current business context
417
+ */
418
+ async getCurrentBusiness() {
419
+ return this.authApi.getCurrentBusiness();
420
+ }
421
+ /**
422
+ * Get current admin context
423
+ */
424
+ async getCurrentAdmin() {
425
+ return this.authApi.getCurrentAdmin();
426
+ }
427
+ // ==========================================
343
428
  // PRIVATE HELPERS
344
429
  // ==========================================
345
430
  /**
@@ -353,17 +438,18 @@ class AuthService {
353
438
  if (refreshToken) {
354
439
  await this.authProvider.setRefreshToken(refreshToken);
355
440
  }
356
- // Type-safe handling of extended token storage features
357
- const extendedProvider = this.authProvider;
358
- if (providerToken && extendedProvider.setProviderToken) {
359
- await extendedProvider.setProviderToken(providerToken);
360
- }
361
- if (authType && extendedProvider.setAuthType) {
362
- console.log('[AuthService] Storing auth type:', authType);
363
- await extendedProvider.setAuthType(authType);
441
+ // Handle optional extended storage methods
442
+ const extended = this.extendedProvider;
443
+ if (extended) {
444
+ if (providerToken && extended.setProviderToken) {
445
+ await extended.setProviderToken(providerToken);
446
+ }
447
+ if (authType && extended.setAuthType) {
448
+ await extended.setAuthType(authType);
449
+ }
364
450
  }
365
- else {
366
- console.warn('[AuthService] Auth type not stored - authType:', authType, 'has setAuthType:', !!extendedProvider.setAuthType);
451
+ else if (authType) {
452
+ console.warn('[AuthService] Auth type not stored - provider does not implement setAuthType');
367
453
  }
368
454
  // Emit authenticated status on successful token storage
369
455
  await this.emitAuthStatus(exports.AuthStatus.AUTHENTICATED);
@@ -1403,6 +1489,7 @@ function generateEventId() {
1403
1489
  *
1404
1490
  * All events flow through one subscription point.
1405
1491
  * Optional filtering at subscription level.
1492
+ * Supports replay of last auth event for late subscribers.
1406
1493
  *
1407
1494
  * @example Basic Usage
1408
1495
  * ```typescript
@@ -1426,6 +1513,13 @@ function generateEventId() {
1426
1513
  * showNotification(event.userMessage);
1427
1514
  * }, { excludeDomains: ['validation'] });
1428
1515
  *
1516
+ * // Subscribe with replay - get last auth event if missed
1517
+ * sdk.events.subscribe((event) => {
1518
+ * if (event.type === 'session_restored') {
1519
+ * setUser(event.details.user);
1520
+ * }
1521
+ * }, { domains: ['authentication'], replay: true });
1522
+ *
1429
1523
  * // Cleanup
1430
1524
  * unsubscribe();
1431
1525
  * ```
@@ -1433,6 +1527,8 @@ function generateEventId() {
1433
1527
  let emitterInstanceCounter = 0;
1434
1528
  class PersEventEmitter {
1435
1529
  constructor() {
1530
+ // Store last auth event for replay to late subscribers
1531
+ this.lastAuthEvent = null;
1436
1532
  this.handlers = new Set();
1437
1533
  this._instanceId = ++emitterInstanceCounter;
1438
1534
  }
@@ -1443,7 +1539,7 @@ class PersEventEmitter {
1443
1539
  * Subscribe to events
1444
1540
  *
1445
1541
  * @param handler - Callback for matching events
1446
- * @param filter - Optional filter by domain and/or level
1542
+ * @param filter - Optional filter by domain and/or level. Set `replay: true` to receive last auth event if missed.
1447
1543
  * @returns Unsubscribe function
1448
1544
  *
1449
1545
  * @example All events
@@ -1467,10 +1563,35 @@ class PersEventEmitter {
1467
1563
  * confetti();
1468
1564
  * }, { domains: ['transaction'], levels: ['success'] });
1469
1565
  * ```
1566
+ *
1567
+ * @example Auth events with replay (catches session_restored even if emitted before subscription)
1568
+ * ```typescript
1569
+ * sdk.events.subscribe((event) => {
1570
+ * if (event.type === 'session_restored') {
1571
+ * const { user } = event.details;
1572
+ * setUser(user);
1573
+ * }
1574
+ * }, { domains: ['authentication'], replay: true });
1575
+ * ```
1470
1576
  */
1471
1577
  subscribe(handler, filter) {
1472
1578
  const filteredHandler = { handler, filter };
1473
1579
  this.handlers.add(filteredHandler);
1580
+ // If replay is requested and we have a cached auth event, replay it immediately
1581
+ if (filter?.replay && this.lastAuthEvent) {
1582
+ // Check if event matches the filter
1583
+ if (!filter || this.matchesFilter(this.lastAuthEvent, filter)) {
1584
+ // Use queueMicrotask to ensure handler runs after subscribe returns
1585
+ queueMicrotask(() => {
1586
+ try {
1587
+ handler(this.lastAuthEvent);
1588
+ }
1589
+ catch (error) {
1590
+ console.error('[PersEventEmitter] Replay handler error:', error);
1591
+ }
1592
+ });
1593
+ }
1594
+ }
1474
1595
  return () => this.handlers.delete(filteredHandler);
1475
1596
  }
1476
1597
  /**
@@ -1495,6 +1616,7 @@ class PersEventEmitter {
1495
1616
  * Emit a success event
1496
1617
  *
1497
1618
  * Domain is restricted to business domains only (Domain type).
1619
+ * Auth events (login_success, session_restored) are cached for replay to late subscribers.
1498
1620
  *
1499
1621
  * @param event - Success event data (id and timestamp auto-generated)
1500
1622
  * @returns The complete event object
@@ -1515,6 +1637,15 @@ class PersEventEmitter {
1515
1637
  id: generateEventId(),
1516
1638
  timestamp: Date.now()
1517
1639
  };
1640
+ // Cache auth events for replay to late subscribers
1641
+ if (event.domain === 'authentication' &&
1642
+ (event.type === 'login_success' || event.type === 'session_restored')) {
1643
+ this.lastAuthEvent = fullEvent;
1644
+ }
1645
+ // Clear cached auth on logout
1646
+ if (event.domain === 'authentication' && event.type === 'logout_success') {
1647
+ this.lastAuthEvent = null;
1648
+ }
1518
1649
  this.notifyHandlers(fullEvent);
1519
1650
  return fullEvent;
1520
1651
  }
@@ -1542,6 +1673,10 @@ class PersEventEmitter {
1542
1673
  id: generateEventId(),
1543
1674
  timestamp: Date.now()
1544
1675
  };
1676
+ // Clear cached auth on auth failure (session invalid)
1677
+ if (event.domain === 'authentication' && event.type === 'session_restoration_failed') {
1678
+ this.lastAuthEvent = null;
1679
+ }
1545
1680
  this.notifyHandlers(fullEvent);
1546
1681
  return fullEvent;
1547
1682
  }
@@ -1665,7 +1800,8 @@ class AuthManager {
1665
1800
  this.events?.emitSuccess({
1666
1801
  domain: 'authentication',
1667
1802
  type: 'login_success',
1668
- userMessage: 'Successfully logged in'
1803
+ userMessage: 'Successfully logged in',
1804
+ details: { user: result.user }
1669
1805
  });
1670
1806
  return result;
1671
1807
  }
@@ -1713,7 +1849,66 @@ class AuthManager {
1713
1849
  */
1714
1850
  async loginAsBusiness(jwtToken, options) {
1715
1851
  const authService = this.apiClient.getAuthService();
1716
- return authService.loginBusiness(jwtToken, options);
1852
+ const result = await authService.loginBusiness(jwtToken, options);
1853
+ this.events?.emitSuccess({
1854
+ domain: 'authentication',
1855
+ type: 'login_success',
1856
+ userMessage: 'Successfully logged in as business',
1857
+ details: { user: result.user, business: result.business }
1858
+ });
1859
+ return result;
1860
+ }
1861
+ /**
1862
+ * Login as tenant admin with JWT token
1863
+ *
1864
+ * Authenticates an admin in a tenant context.
1865
+ *
1866
+ * **Auto-Selection Behavior:**
1867
+ * - If admin has access to a single tenant, it's auto-selected
1868
+ * - If admin has access to multiple tenants and no tenantId is provided,
1869
+ * throws `MULTIPLE_CONTEXT_SELECTION_REQUIRED` error with available options
1870
+ *
1871
+ * @param jwtToken - JWT token from auth provider (Firebase, etc.)
1872
+ * @param options - Tenant authentication options (tenantId for multi-tenant admins)
1873
+ * @returns Promise resolving to authentication response with tenant context
1874
+ * @throws Error with code `MULTIPLE_CONTEXT_SELECTION_REQUIRED` when tenantId is needed
1875
+ *
1876
+ * @example Single Tenant Access
1877
+ * ```typescript
1878
+ * // Auto-selects the admin's only tenant
1879
+ * const result = await sdk.auth.loginAsTenant(jwt);
1880
+ * console.log('Tenant:', result.admin?.tenantId);
1881
+ * ```
1882
+ *
1883
+ * @example Multiple Tenant Access
1884
+ * ```typescript
1885
+ * try {
1886
+ * const result = await sdk.auth.loginAsTenant(jwt);
1887
+ * } catch (error) {
1888
+ * if (error.code === 'MULTIPLE_CONTEXT_SELECTION_REQUIRED') {
1889
+ * // Show tenant selector UI
1890
+ * const selectedId = await showTenantSelector(error.details.availableOptions);
1891
+ * const result = await sdk.auth.loginAsTenant(jwt, { tenantId: selectedId });
1892
+ * }
1893
+ * }
1894
+ * ```
1895
+ *
1896
+ * @example Direct Tenant Selection
1897
+ * ```typescript
1898
+ * const result = await sdk.auth.loginAsTenant(jwt, { tenantId: 'tenant-123' });
1899
+ * console.log('Authenticated as admin for tenant:', result.admin?.tenantId);
1900
+ * ```
1901
+ */
1902
+ async loginAsTenant(jwtToken, options) {
1903
+ const authService = this.apiClient.getAuthService();
1904
+ const result = await authService.loginTenantAdmin(jwtToken, options);
1905
+ this.events?.emitSuccess({
1906
+ domain: 'authentication',
1907
+ type: 'login_success',
1908
+ userMessage: 'Successfully logged in as tenant admin',
1909
+ details: { admin: result.admin }
1910
+ });
1911
+ return result;
1717
1912
  }
1718
1913
  /**
1719
1914
  * Get current business context
@@ -1731,7 +1926,27 @@ class AuthManager {
1731
1926
  * ```
1732
1927
  */
1733
1928
  async getCurrentBusiness() {
1734
- return this.apiClient.get('/businesses/me');
1929
+ const authService = this.apiClient.getAuthService();
1930
+ return authService.getCurrentBusiness();
1931
+ }
1932
+ /**
1933
+ * Get current admin context
1934
+ *
1935
+ * Retrieves the current admin data if authenticated as tenant admin.
1936
+ * Requires prior tenant authentication via {@link loginAsTenant}.
1937
+ *
1938
+ * @returns Promise resolving to current admin data
1939
+ * @throws {PersApiError} When not authenticated as tenant admin
1940
+ *
1941
+ * @example
1942
+ * ```typescript
1943
+ * const admin = await sdk.auth.getCurrentAdmin();
1944
+ * console.log('Current admin:', admin.email);
1945
+ * ```
1946
+ */
1947
+ async getCurrentAdmin() {
1948
+ const authService = this.apiClient.getAuthService();
1949
+ return authService.getCurrentAdmin();
1735
1950
  }
1736
1951
  /**
1737
1952
  * Login with raw user data
@@ -1775,7 +1990,8 @@ class AuthManager {
1775
1990
  * ```
1776
1991
  */
1777
1992
  async getCurrentUser() {
1778
- return this.apiClient.get('/users/me');
1993
+ const authService = this.apiClient.getAuthService();
1994
+ return authService.getCurrentUser();
1779
1995
  }
1780
1996
  /**
1781
1997
  * Check if user is authenticated
@@ -4073,58 +4289,52 @@ class CampaignManager {
4073
4289
  async deleteCampaignBusinessEngagement(campaignId, engagementId) {
4074
4290
  return this.campaignService.deleteCampaignBusinessEngagement(campaignId, engagementId);
4075
4291
  }
4076
- /**
4077
- * Admin: Get all campaign claims
4078
- *
4079
- * Retrieves all campaign claims across the system for comprehensive reporting
4080
- * and analytics. This operation requires administrator privileges and provides
4081
- * system-wide visibility into campaign performance and user engagement.
4082
- *
4083
- * @returns Promise resolving to array of all campaign claims
4084
- * @throws {PersApiError} When not authenticated as administrator
4085
- *
4086
- * @example
4087
- * ```typescript
4088
- * // Admin operation - get campaign performance data
4089
- * const allClaims = await sdk.campaigns.getCampaignClaims();
4090
- *
4091
- * console.log(`Campaign Performance Report:`);
4092
- * console.log(`Total claims: ${allClaims.length}`);
4093
- *
4094
- * // Analyze claims by campaign
4095
- * const claimsByCampaign = allClaims.reduce((acc, claim) => {
4096
- * const campaignId = claim.campaignId;
4097
- * acc[campaignId] = (acc[campaignId] || 0) + 1;
4098
- * return acc;
4099
- * }, {});
4100
- *
4101
- * console.log('\nClaims by Campaign:');
4102
- * Object.entries(claimsByCampaign).forEach(([campaignId, count]) => {
4103
- * console.log(`${campaignId}: ${count} claims`);
4104
- * });
4105
- * ```
4106
- */
4107
4292
  /**
4108
4293
  * Admin: Get campaign claims with optional filters
4109
4294
  *
4110
- * Retrieves campaign claims with optional filtering by campaign, user, or business.
4295
+ * Retrieves campaign claims with optional filtering by campaign, user, business, or date range.
4111
4296
  * This operation requires administrator privileges and provides system-wide
4112
4297
  * visibility into campaign performance and user engagement.
4113
4298
  *
4114
4299
  * @param filters - Optional filters and pagination options
4300
+ * @param filters.campaignId - Filter by specific campaign ID
4301
+ * @param filters.userId - Filter by specific user ID
4302
+ * @param filters.businessId - Filter by specific business ID
4303
+ * @param filters.dateFrom - Filter claims from this date (inclusive)
4304
+ * @param filters.dateTo - Filter claims until this date (inclusive)
4305
+ * @param filters.page - Page number for pagination
4306
+ * @param filters.limit - Items per page
4307
+ * @param filters.sortBy - Field to sort by
4308
+ * @param filters.sortOrder - Sort direction ('asc' or 'desc')
4309
+ * @param include - Optional relations to include for enrichment
4115
4310
  * @returns Promise resolving to paginated campaign claims
4116
4311
  * @throws {PersApiError} When not authenticated as administrator
4117
4312
  *
4118
- * @example
4313
+ * @example Get All Claims
4119
4314
  * ```typescript
4120
- * // Get all claims
4121
- * const allClaims = await sdk.campaigns.getCampaignClaims();
4315
+ * const { data: allClaims, pagination } = await sdk.campaigns.getCampaignClaims();
4316
+ * console.log(`Total: ${pagination.total}`);
4317
+ * ```
4122
4318
  *
4123
- * // Get claims for specific user
4124
- * const userClaims = await sdk.campaigns.getCampaignClaims({ userId: 'user-123' });
4319
+ * @example Filter by User
4320
+ * ```typescript
4321
+ * const { data: userClaims } = await sdk.campaigns.getCampaignClaims({ userId: 'user-123' });
4322
+ * ```
4125
4323
  *
4126
- * // Get claims for specific campaign with pagination
4127
- * const page1 = await sdk.campaigns.getCampaignClaims({
4324
+ * @example Filter by Date Range
4325
+ * ```typescript
4326
+ * // Get claims within a specific date range
4327
+ * const { data: monthClaims } = await sdk.campaigns.getCampaignClaims({
4328
+ * dateFrom: new Date('2024-01-01'),
4329
+ * dateTo: new Date('2024-01-31'),
4330
+ * limit: 100
4331
+ * });
4332
+ * console.log(`${monthClaims.length} claims in January 2024`);
4333
+ * ```
4334
+ *
4335
+ * @example With Pagination and Campaign Filter
4336
+ * ```typescript
4337
+ * const { data: page1 } = await sdk.campaigns.getCampaignClaims({
4128
4338
  * campaignId: 'campaign-456',
4129
4339
  * page: 1,
4130
4340
  * limit: 50
@@ -4729,9 +4939,19 @@ class RedemptionManager {
4729
4939
  *
4730
4940
  * Retrieves all redemption redeems across the platform with filtering capabilities.
4731
4941
  * This is an admin-level operation that allows monitoring and analytics of redemption
4732
- * activity. Supports filtering by user, redemption offer, and enrichment of related entities.
4733
- *
4734
- * @param filters - Filter options (userId, redemptionId, pagination)
4942
+ * activity. Supports filtering by user, redemption offer, date range, and enrichment of related entities.
4943
+ *
4944
+ * @param filters - Filter options (userId, redemptionId, businessId, status, dateFrom, dateTo, pagination)
4945
+ * @param filters.userId - Filter by specific user ID
4946
+ * @param filters.redemptionId - Filter by specific redemption offer ID
4947
+ * @param filters.businessId - Filter by specific business ID
4948
+ * @param filters.status - Filter by redeem status
4949
+ * @param filters.dateFrom - Filter redeems from this date (inclusive)
4950
+ * @param filters.dateTo - Filter redeems until this date (inclusive)
4951
+ * @param filters.page - Page number for pagination
4952
+ * @param filters.limit - Items per page
4953
+ * @param filters.sortBy - Field to sort by
4954
+ * @param filters.sortOrder - Sort direction ('asc' or 'desc')
4735
4955
  * @param include - Optional relations to include for enrichment
4736
4956
  * @returns Promise resolving to paginated list of redemption redeems
4737
4957
  * @throws {PersApiError} When not authenticated as admin
@@ -4756,6 +4976,18 @@ class RedemptionManager {
4756
4976
  * console.log(`User has ${userRedeems.length} redemptions`);
4757
4977
  * ```
4758
4978
  *
4979
+ * @example Filter by Date Range
4980
+ * ```typescript
4981
+ * // Get redeems within a specific date range
4982
+ * const { data: recentRedeems } = await sdk.redemptions.getRedemptionRedeems({
4983
+ * dateFrom: new Date('2024-01-01'),
4984
+ * dateTo: new Date('2024-01-31'),
4985
+ * limit: 100
4986
+ * });
4987
+ *
4988
+ * console.log(`${recentRedeems.length} redeems in January 2024`);
4989
+ * ```
4990
+ *
4759
4991
  * @example With Enriched Data
4760
4992
  * ```typescript
4761
4993
  * const { data: redeems } = await sdk.redemptions.getRedemptionRedeems(
@@ -8692,7 +8924,8 @@ class WalletEventsManager {
8692
8924
  }
8693
8925
  // Save subscriptions for auto-resubscribe on reconnect
8694
8926
  this.lastSubscriptions.wallets = wallets;
8695
- return this.client.subscribeWallets(wallets);
8927
+ const result = await this.client.subscribeWallets(wallets);
8928
+ return result;
8696
8929
  }
8697
8930
  /**
8698
8931
  * Subscribe to chain events (Admin Dashboard)
@@ -8715,7 +8948,8 @@ class WalletEventsManager {
8715
8948
  }
8716
8949
  // Save subscriptions for auto-resubscribe on reconnect
8717
8950
  this.lastSubscriptions.chains = chains;
8718
- return this.client.subscribeChains(chains);
8951
+ const result = await this.client.subscribeChains(chains);
8952
+ return result;
8719
8953
  }
8720
8954
  /**
8721
8955
  * Unsubscribe from wallet events
@@ -9025,6 +9259,24 @@ class PersSDK {
9025
9259
  this.apiClient.setEvents(this._events);
9026
9260
  // Auto-connect to wallet events on successful login (if enabled)
9027
9261
  this.setupWalletEventsAutoConnect();
9262
+ // Auto-restore session from stored tokens (if enabled, default: true)
9263
+ this.setupAutoRestoreSession();
9264
+ }
9265
+ /**
9266
+ * Setup automatic session restoration from stored tokens
9267
+ * @internal
9268
+ */
9269
+ setupAutoRestoreSession() {
9270
+ const config = this.apiClient.getConfig();
9271
+ // Check if autoRestoreSession is enabled (default: true)
9272
+ if (config.autoRestoreSession === false) {
9273
+ return;
9274
+ }
9275
+ // Fire-and-forget: restore session asynchronously
9276
+ // Events will be emitted on success/failure
9277
+ this.restoreSession().catch(() => {
9278
+ // Error already emitted via session_restoration_failed event
9279
+ });
9028
9280
  }
9029
9281
  /**
9030
9282
  * Setup auto-connect for wallet events on authentication
@@ -9102,22 +9354,23 @@ class PersSDK {
9102
9354
  /**
9103
9355
  * Restore user session from stored tokens
9104
9356
  *
9105
- * Call this method after SDK initialization to restore the user's session
9106
- * if valid tokens exist. This is useful for maintaining login state across
9107
- * app restarts.
9357
+ * **Note:** This method is called automatically on SDK initialization when
9358
+ * `autoRestoreSession` is enabled (default: true). You only need to call this
9359
+ * manually if you disabled auto-restore or need to force a session refresh.
9360
+ *
9361
+ * Validates stored tokens and fetches user data to restore the session.
9362
+ * Emits `session_restored` event on success, `session_restoration_failed` on error.
9108
9363
  *
9109
9364
  * **Important:** Only works for USER and BUSINESS accounts. Admin/tenant
9110
9365
  * accounts don't support user data fetching, so this will return null for them
9111
9366
  * (though their tokens remain valid for API calls).
9112
9367
  *
9113
- * Emits auth domain success event when session is restored.
9114
- *
9115
9368
  * @returns Promise resolving to User data if session restored, null if no session or admin account
9116
9369
  * @throws {PersError} If token validation or user fetch fails
9117
9370
  *
9118
9371
  * @example
9119
9372
  * ```typescript
9120
- * // Call after initial render for better perceived performance
9373
+ * // Manual restore (only needed if autoRestoreSession: false)
9121
9374
  * const user = await sdk.restoreSession();
9122
9375
  * if (user) {
9123
9376
  * console.log('Welcome back,', user.name);
@@ -9131,25 +9384,57 @@ class PersSDK {
9131
9384
  }
9132
9385
  // Check auth type - only restore session for user and business accounts
9133
9386
  const authProvider = this.apiClient.getConfig().authProvider;
9134
- if (authProvider?.getAuthType) {
9135
- const authType = await authProvider.getAuthType();
9136
- if (authType === persShared.AccountOwnerType.TENANT) {
9137
- // Admin sessions don't support getCurrentUser(), skip restoration
9138
- // Tokens are valid and will be used for API calls
9387
+ const authType = authProvider?.getAuthType ? await authProvider.getAuthType() : persShared.AccountOwnerType.USER;
9388
+ if (authType === persShared.AccountOwnerType.TENANT) {
9389
+ // Ensure token is valid (refresh if expired) before fetching admin
9390
+ try {
9391
+ await this.auth.ensureValidToken();
9392
+ // Fetch current admin data
9393
+ const adminData = await this.auth.getCurrentAdmin();
9394
+ // Emit session restored for tenant admin
9395
+ this._events.emitSuccess({
9396
+ type: 'session_restored',
9397
+ domain: 'authentication',
9398
+ userMessage: 'Admin session restored successfully',
9399
+ details: { admin: adminData }
9400
+ });
9139
9401
  return null;
9140
9402
  }
9403
+ catch (error) {
9404
+ await this.auth.clearAuth();
9405
+ this._events.emitError({
9406
+ type: 'session_restoration_failed',
9407
+ domain: 'authentication',
9408
+ userMessage: 'Admin session restoration failed',
9409
+ code: 'SESSION_INVALID',
9410
+ details: { error }
9411
+ });
9412
+ throw error;
9413
+ }
9141
9414
  }
9142
9415
  try {
9143
9416
  // Ensure token is valid (refresh if expired) before fetching user
9144
9417
  await this.auth.ensureValidToken();
9145
- // Fetch user data to restore session
9418
+ // For BUSINESS auth, only fetch business context (no access to /users/me)
9419
+ if (authType === persShared.AccountOwnerType.BUSINESS) {
9420
+ const businessData = await this.auth.getCurrentBusiness();
9421
+ // Emit event with business data (no user data for business auth)
9422
+ this._events.emitSuccess({
9423
+ type: 'session_restored',
9424
+ domain: 'authentication',
9425
+ userMessage: 'Business session restored successfully',
9426
+ details: { business: businessData }
9427
+ });
9428
+ return null; // No user data for business auth
9429
+ }
9430
+ // For USER auth, fetch user data
9146
9431
  const userData = await this.auth.getCurrentUser();
9147
- // Emit event through proper event emitter
9432
+ // Emit event with user data
9148
9433
  this._events.emitSuccess({
9149
9434
  type: 'session_restored',
9150
9435
  domain: 'authentication',
9151
9436
  userMessage: 'Session restored successfully',
9152
- details: { userId: userData.id }
9437
+ details: { user: userData }
9153
9438
  });
9154
9439
  return userData;
9155
9440
  }
@@ -9698,4 +9983,4 @@ exports.buildWalletEventsWsUrl = buildWalletEventsWsUrl;
9698
9983
  exports.createPersEventsClient = createPersEventsClient;
9699
9984
  exports.createPersSDK = createPersSDK;
9700
9985
  exports.mergeWithDefaults = mergeWithDefaults;
9701
- //# sourceMappingURL=pers-sdk-rmjhPvHo.cjs.map
9986
+ //# sourceMappingURL=pers-sdk-DXCcAgUS.cjs.map