@explorins/pers-sdk 1.2.5 → 1.3.1

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 (131) hide show
  1. package/README.md +416 -0
  2. package/dist/analytics.cjs +6 -0
  3. package/dist/analytics.cjs.map +1 -1
  4. package/dist/analytics.js +2 -0
  5. package/dist/analytics.js.map +1 -1
  6. package/dist/business.cjs +6 -0
  7. package/dist/business.cjs.map +1 -1
  8. package/dist/business.js +2 -0
  9. package/dist/business.js.map +1 -1
  10. package/dist/campaign/api/campaign-api.d.ts +19 -65
  11. package/dist/campaign/api/campaign-api.d.ts.map +1 -1
  12. package/dist/campaign.cjs +55 -103
  13. package/dist/campaign.cjs.map +1 -1
  14. package/dist/campaign.js +51 -103
  15. package/dist/campaign.js.map +1 -1
  16. package/dist/chunks/base-token-service-BA81_Ouq.js +532 -0
  17. package/dist/chunks/base-token-service-BA81_Ouq.js.map +1 -0
  18. package/dist/chunks/base-token-service-BQ6uFoki.cjs +537 -0
  19. package/dist/chunks/base-token-service-BQ6uFoki.cjs.map +1 -0
  20. package/dist/chunks/jwt.function-BYiyl-z_.cjs +25 -0
  21. package/dist/chunks/jwt.function-BYiyl-z_.cjs.map +1 -0
  22. package/dist/chunks/jwt.function-d6jPtBqI.js +23 -0
  23. package/dist/chunks/jwt.function-d6jPtBqI.js.map +1 -0
  24. package/dist/chunks/pers-sdk-JC-hSYUd.js +1377 -0
  25. package/dist/chunks/pers-sdk-JC-hSYUd.js.map +1 -0
  26. package/dist/chunks/pers-sdk-_1sTi9x9.cjs +1384 -0
  27. package/dist/chunks/pers-sdk-_1sTi9x9.cjs.map +1 -0
  28. package/dist/core/auth/api/auth-api.d.ts +30 -0
  29. package/dist/core/auth/api/auth-api.d.ts.map +1 -0
  30. package/dist/core/auth/auth-constants.d.ts +33 -0
  31. package/dist/core/auth/auth-constants.d.ts.map +1 -0
  32. package/dist/core/auth/auth-errors.d.ts +8 -0
  33. package/dist/core/auth/auth-errors.d.ts.map +1 -0
  34. package/dist/core/auth/auth-provider.interface.d.ts +72 -2
  35. package/dist/core/auth/auth-provider.interface.d.ts.map +1 -1
  36. package/dist/core/auth/create-auth-provider.d.ts +3 -3
  37. package/dist/core/auth/create-auth-provider.d.ts.map +1 -1
  38. package/dist/core/auth/default-auth-provider.d.ts +71 -0
  39. package/dist/core/auth/default-auth-provider.d.ts.map +1 -0
  40. package/dist/core/auth/index.d.ts +17 -0
  41. package/dist/core/auth/index.d.ts.map +1 -0
  42. package/dist/core/auth/services/auth-service.d.ts +49 -0
  43. package/dist/core/auth/services/auth-service.d.ts.map +1 -0
  44. package/dist/core/auth/token-refresh.d.ts +91 -0
  45. package/dist/core/auth/token-refresh.d.ts.map +1 -0
  46. package/dist/core/auth/token-storage.d.ts +74 -0
  47. package/dist/core/auth/token-storage.d.ts.map +1 -0
  48. package/dist/core/errors/index.d.ts +80 -0
  49. package/dist/core/errors/index.d.ts.map +1 -0
  50. package/dist/core/index.d.ts +1 -2
  51. package/dist/core/index.d.ts.map +1 -1
  52. package/dist/core/pers-api-client.d.ts +172 -12
  53. package/dist/core/pers-api-client.d.ts.map +1 -1
  54. package/dist/core/pers-config.d.ts +36 -1
  55. package/dist/core/pers-config.d.ts.map +1 -1
  56. package/dist/core/utils/jwt.function.d.ts.map +1 -1
  57. package/dist/core.cjs +8 -500
  58. package/dist/core.cjs.map +1 -1
  59. package/dist/core.js +2 -496
  60. package/dist/core.js.map +1 -1
  61. package/dist/donation.cjs +6 -0
  62. package/dist/donation.cjs.map +1 -1
  63. package/dist/donation.js +2 -0
  64. package/dist/donation.js.map +1 -1
  65. package/dist/index.cjs +79 -4751
  66. package/dist/index.cjs.map +1 -1
  67. package/dist/index.d.ts +0 -1
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +20 -4699
  70. package/dist/index.js.map +1 -1
  71. package/dist/package.json +129 -129
  72. package/dist/payment.cjs +6 -0
  73. package/dist/payment.cjs.map +1 -1
  74. package/dist/payment.js +2 -0
  75. package/dist/payment.js.map +1 -1
  76. package/dist/pers-sdk.d.ts +49 -7
  77. package/dist/pers-sdk.d.ts.map +1 -1
  78. package/dist/redemption/api/redemption-api.d.ts +38 -77
  79. package/dist/redemption/api/redemption-api.d.ts.map +1 -1
  80. package/dist/redemption/services/redemption-service.d.ts +21 -3
  81. package/dist/redemption/services/redemption-service.d.ts.map +1 -1
  82. package/dist/redemption.cjs +84 -117
  83. package/dist/redemption.cjs.map +1 -1
  84. package/dist/redemption.js +80 -117
  85. package/dist/redemption.js.map +1 -1
  86. package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts +2 -1
  87. package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts.map +1 -1
  88. package/dist/tenant/api/tenant-api.d.ts +28 -10
  89. package/dist/tenant/api/tenant-api.d.ts.map +1 -1
  90. package/dist/tenant/index.d.ts +4 -4
  91. package/dist/tenant.cjs +46 -11
  92. package/dist/tenant.cjs.map +1 -1
  93. package/dist/tenant.js +42 -11
  94. package/dist/tenant.js.map +1 -1
  95. package/dist/token.cjs +10 -531
  96. package/dist/token.cjs.map +1 -1
  97. package/dist/token.js +2 -531
  98. package/dist/token.js.map +1 -1
  99. package/dist/transaction.cjs +4 -0
  100. package/dist/transaction.cjs.map +1 -1
  101. package/dist/transaction.js +1 -0
  102. package/dist/transaction.js.map +1 -1
  103. package/dist/user-status.cjs +6 -0
  104. package/dist/user-status.cjs.map +1 -1
  105. package/dist/user-status.js +2 -0
  106. package/dist/user-status.js.map +1 -1
  107. package/dist/user.cjs +6 -0
  108. package/dist/user.cjs.map +1 -1
  109. package/dist/user.js +2 -0
  110. package/dist/user.js.map +1 -1
  111. package/dist/web3-chain.cjs +12 -148
  112. package/dist/web3-chain.cjs.map +1 -1
  113. package/dist/web3-chain.js +7 -147
  114. package/dist/web3-chain.js.map +1 -1
  115. package/dist/web3.cjs +8 -537
  116. package/dist/web3.cjs.map +1 -1
  117. package/dist/web3.js +6 -535
  118. package/dist/web3.js.map +1 -1
  119. package/package.json +129 -129
  120. package/dist/auth-admin/api/auth-admin-api.d.ts +0 -29
  121. package/dist/auth-admin/api/auth-admin-api.d.ts.map +0 -1
  122. package/dist/auth-admin/index.d.ts +0 -27
  123. package/dist/auth-admin/index.d.ts.map +0 -1
  124. package/dist/auth-admin/services/auth-admin-service.d.ts +0 -27
  125. package/dist/auth-admin/services/auth-admin-service.d.ts.map +0 -1
  126. package/dist/auth-admin.cjs +0 -115
  127. package/dist/auth-admin.cjs.map +0 -1
  128. package/dist/auth-admin.js +0 -111
  129. package/dist/auth-admin.js.map +0 -1
  130. package/dist/core/auth/simple-auth-config.interface.d.ts +0 -15
  131. package/dist/core/auth/simple-auth-config.interface.d.ts.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,4755 +1,83 @@
1
1
  'use strict';
2
2
 
3
+ var persSdk = require('./chunks/pers-sdk-_1sTi9x9.cjs');
4
+ var business = require('./business.cjs');
5
+ var transaction = require('./transaction.cjs');
6
+ var analytics = require('./analytics.cjs');
7
+ var campaign = require('./campaign.cjs');
8
+ var donation = require('./donation.cjs');
9
+ var payment = require('./payment.cjs');
10
+ var redemption = require('./redemption.cjs');
11
+ var tenant = require('./tenant.cjs');
12
+ var baseTokenService = require('./chunks/base-token-service-BQ6uFoki.cjs');
3
13
  var persShared = require('@explorins/pers-shared');
4
- var jwtDecode = require('jwt-decode');
5
- var Web3 = require('web3');
6
- var ethers = require('ethers');
7
- var web3Ts = require('@explorins/web3-ts');
8
-
9
- /**
10
- * PERS SDK Configuration interfaces
11
- */
12
- /**
13
- * Default configuration values
14
- */
15
- const DEFAULT_PERS_CONFIG = {
16
- environment: 'production',
17
- apiVersion: 'v2',
18
- timeout: 30000,
19
- retries: 3
20
- };
21
- /**
22
- * Internal function to construct API root from environment
23
- * Now defaults to production and v2
24
- */
25
- function buildApiRoot(environment = 'production', version = 'v2') {
26
- const baseUrls = {
27
- development: 'https://explorins-loyalty.ngrok.io',
28
- staging: `https://dev.api.pers.ninja/${version}`,
29
- production: `https://api.pers.ninja/${version}`
30
- };
31
- return `${baseUrls[environment]}`;
32
- }
33
- /**
34
- * Merge user config with defaults
35
- */
36
- function mergeWithDefaults(config) {
37
- return {
38
- ...DEFAULT_PERS_CONFIG,
39
- ...config,
40
- environment: config.environment ?? DEFAULT_PERS_CONFIG.environment,
41
- apiVersion: config.apiVersion ?? DEFAULT_PERS_CONFIG.apiVersion,
42
- timeout: config.timeout ?? DEFAULT_PERS_CONFIG.timeout,
43
- retries: config.retries ?? DEFAULT_PERS_CONFIG.retries
44
- };
45
- }
46
-
47
- // packages/pers-sdk/src/core/pers-api-client.ts
48
- /**
49
- * PERS API Client - Core platform-agnostic client for PERS backend
50
- */
51
- class PersApiClient {
52
- constructor(httpClient, config) {
53
- this.httpClient = httpClient;
54
- this.config = config;
55
- // Merge user config with defaults (production + v2)
56
- this.mergedConfig = mergeWithDefaults(config);
57
- // Build API root from merged environment and version
58
- this.apiRoot = buildApiRoot(this.mergedConfig.environment, this.mergedConfig.apiVersion);
59
- }
60
- /**
61
- * Get request headers including auth token and project key
62
- */
63
- async getHeaders() {
64
- const headers = {
65
- 'Content-Type': 'application/json',
66
- };
67
- // Add authentication token
68
- if (this.mergedConfig.authProvider) {
69
- const token = await this.mergedConfig.authProvider.getToken();
70
- if (token) {
71
- headers['Authorization'] = `Bearer ${token}`;
72
- }
73
- }
74
- // Add project key
75
- if (this.mergedConfig.authProvider) {
76
- const projectKey = await this.mergedConfig.authProvider.getProjectKey();
77
- if (projectKey) {
78
- headers['x-project-key'] = projectKey;
79
- }
80
- }
81
- else if (this.mergedConfig.apiProjectKey) {
82
- // Fallback to config project key if no auth provider
83
- headers['x-project-key'] = this.mergedConfig.apiProjectKey;
84
- }
85
- return headers;
86
- }
87
- /**
88
- * Make a request with proper headers, auth, and error handling
89
- */
90
- async request(method, endpoint, body, options) {
91
- const { retryCount = 0, responseType = 'json' } = options || {};
92
- const url = `${this.apiRoot}${endpoint}`;
93
- // ✅ DEBUGGING: Add extensive logging for CSV endpoint
94
- const isCSVEndpoint = endpoint.includes('/export/csv');
95
- const requestOptions = {
96
- headers: await this.getHeaders(),
97
- timeout: this.mergedConfig.timeout,
98
- responseType
99
- };
100
- try {
101
- let result;
102
- switch (method) {
103
- case 'GET':
104
- result = await this.httpClient.get(url, requestOptions);
105
- break;
106
- case 'POST':
107
- result = await this.httpClient.post(url, body, requestOptions);
108
- break;
109
- case 'PUT':
110
- result = await this.httpClient.put(url, body, requestOptions);
111
- break;
112
- case 'DELETE':
113
- result = await this.httpClient.delete(url, requestOptions);
114
- break;
115
- default:
116
- throw new Error(`Unsupported HTTP method: ${method}`);
117
- }
118
- return result;
119
- }
120
- catch (error) {
121
- if (isCSVEndpoint) {
122
- console.error('❌ [PERS API CLIENT] CSV Request failed:', error);
123
- }
124
- // Handle 401 errors with automatic token refresh
125
- const apiError = error;
126
- if (apiError.status === 401 && retryCount === 0 && this.mergedConfig.authProvider?.onTokenExpired) {
127
- try {
128
- await this.mergedConfig.authProvider.onTokenExpired();
129
- // Retry once with refreshed token
130
- return this.request(method, endpoint, body, { ...options, retryCount: 1 });
131
- }
132
- catch (refreshError) {
133
- throw new PersApiError(`Authentication refresh failed: ${refreshError}`, endpoint, method, 401);
134
- }
135
- }
136
- throw new PersApiError(`PERS API request failed: ${apiError.message || error}`, endpoint, method, apiError.status);
137
- }
138
- }
139
- /**
140
- * Generic GET request
141
- */
142
- async get(endpoint, responseType) {
143
- return this.request('GET', endpoint, undefined, { responseType });
144
- }
145
- /**
146
- * Generic POST request
147
- */
148
- async post(endpoint, body) {
149
- return this.request('POST', endpoint, body);
150
- }
151
- /**
152
- * Generic PUT request
153
- */
154
- async put(endpoint, body) {
155
- return this.request('PUT', endpoint, body);
156
- }
157
- /**
158
- * Generic DELETE request
159
- */
160
- async delete(endpoint) {
161
- return this.request('DELETE', endpoint);
162
- }
163
- /**
164
- * Get current configuration (returns merged config)
165
- */
166
- getConfig() {
167
- return this.mergedConfig;
168
- }
169
- /**
170
- * Get original user configuration
171
- */
172
- getOriginalConfig() {
173
- return this.config;
174
- }
175
- }
176
- class PersApiError extends Error {
177
- constructor(message, endpoint, method, statusCode) {
178
- super(message);
179
- this.endpoint = endpoint;
180
- this.method = method;
181
- this.statusCode = statusCode;
182
- this.name = 'PersApiError';
183
- }
184
- }
185
- /**
186
- * PERS API Client - Core platform-agnostic client for PERS backend
187
- */
188
- /*import { HttpClient, RequestOptions } from './abstractions/http-client';
189
- import { PersConfig, buildApiRoot, mergeWithDefaults } from './pers-config';
190
-
191
- export class PersApiClient {
192
- private readonly apiRoot: string;
193
- private readonly mergedConfig: ReturnType<typeof mergeWithDefaults>;
194
-
195
- constructor(
196
- private httpClient: HttpClient,
197
- private config: PersConfig
198
- ) {
199
- // Merge user config with defaults (production + v2)
200
- this.mergedConfig = mergeWithDefaults(config);
201
-
202
- // Build API root from merged environment and version
203
- this.apiRoot = buildApiRoot(this.mergedConfig.environment, this.mergedConfig.apiVersion);
204
- }
205
-
206
- /**
207
- * Get request headers including auth token and project key
208
- */
209
- /*private async getHeaders(): Promise<Record<string, string>> {
210
- const headers: Record<string, string> = {
211
- 'Content-Type': 'application/json',
212
- };
213
-
214
- // Add authentication token
215
- if (this.mergedConfig.authProvider) {
216
- const token = await this.mergedConfig.authProvider.getToken();
217
- if (token) {
218
- headers['Authorization'] = `Bearer ${token}`;
219
- }
220
- }
221
-
222
- // Add project key
223
- if (this.mergedConfig.authProvider) {
224
- const projectKey = await this.mergedConfig.authProvider.getProjectKey();
225
- if (projectKey) {
226
- headers['x-project-key'] = projectKey;
227
- }
228
- } else if(this.mergedConfig.apiProjectKey) {
229
- // Fallback to config project key if no auth provider
230
- headers['x-project-key'] = this.mergedConfig.apiProjectKey;
231
- }
232
-
233
- return headers;
234
- }
235
-
236
- /**
237
- * Make a request with proper headers, auth, and error handling
238
- */
239
- /*private async request<T>(
240
- method: 'GET' | 'POST' | 'PUT' | 'DELETE',
241
- endpoint: string,
242
- body?: any,
243
- options?: { retryCount?: number }
244
- ): Promise<T> {
245
- const { retryCount = 0 } = options || {};
246
- const url = `${this.apiRoot}${endpoint}`;
247
-
248
- const requestOptions: RequestOptions = {
249
- headers: await this.getHeaders(),
250
- timeout: this.mergedConfig.timeout,
251
- };
252
-
253
- try {
254
- switch (method) {
255
- case 'GET':
256
- return await this.httpClient.get<T>(url, requestOptions);
257
- case 'POST':
258
- return await this.httpClient.post<T>(url, body, requestOptions);
259
- case 'PUT':
260
- return await this.httpClient.put<T>(url, body, requestOptions);
261
- case 'DELETE':
262
- return await this.httpClient.delete<T>(url, requestOptions);
263
- default:
264
- throw new Error(`Unsupported HTTP method: ${method}`);
265
- }
266
- } catch (error: any) {
267
- // Handle 401 errors with automatic token refresh
268
- if (error.status === 401 && retryCount === 0 && this.mergedConfig.authProvider?.onTokenExpired) {
269
- try {
270
- await this.mergedConfig.authProvider.onTokenExpired();
271
- // Retry once with refreshed token
272
- return this.request<T>(method, endpoint, body, { ...options, retryCount: 1 });
273
- } catch (refreshError) {
274
- throw new PersApiError(
275
- `Authentication refresh failed: ${refreshError}`,
276
- endpoint,
277
- method,
278
- 401
279
- );
280
- }
281
- }
282
-
283
- throw new PersApiError(
284
- `PERS API request failed: ${error.message || error}`,
285
- endpoint,
286
- method,
287
- error.status
288
- );
289
- }
290
- }
291
-
292
- /**
293
- * Generic GET request
294
- */
295
- /*async get<T>(endpoint: string): Promise<T> {
296
- return this.request<T>('GET', endpoint);
297
- }
298
-
299
- /**
300
- * Generic POST request
301
- */
302
- /*async post<T>(endpoint: string, body?: any): Promise<T> {
303
- return this.request<T>('POST', endpoint, body);
304
- }
305
-
306
- /**
307
- * Generic PUT request
308
- */
309
- /*async put<T>(endpoint: string, body?: any): Promise<T> {
310
- return this.request<T>('PUT', endpoint, body);
311
- }
312
-
313
- /**
314
- * Generic DELETE request
315
- */
316
- /*async delete<T>(endpoint: string): Promise<T> {
317
- return this.request<T>('DELETE', endpoint);
318
- }
319
-
320
- /**
321
- * Get current configuration (returns merged config)
322
- */
323
- /*getConfig(): ReturnType<typeof mergeWithDefaults> {
324
- return this.mergedConfig;
325
- }
326
-
327
- /**
328
- * Get original user configuration
329
- */
330
- /*getOriginalConfig(): PersConfig {
331
- return this.config;
332
- }
333
- }
334
-
335
- export class PersApiError extends Error {
336
- constructor(
337
- message: string,
338
- public endpoint: string,
339
- public method: string,
340
- public statusCode?: number
341
- ) {
342
- super(message);
343
- this.name = 'PersApiError';
344
- }
345
- }*/
346
-
347
- /**
348
- * Creates a platform-agnostic AuthProvider from simple configuration
349
- *
350
- * This factory function is completely platform-agnostic and can be used
351
- * across Angular, React, Vue, Node.js, or any other JavaScript environment.
352
- *
353
- * Features:
354
- * - Token caching with refresh support
355
- * - Automatic token refresh on expiration
356
- * - Configurable token providers
357
- * - Platform-independent (no localStorage assumptions)
358
- *
359
- * @param config - Simple auth configuration
360
- * @returns AuthProvider implementation
361
- */
362
- function createAuthProvider(config) {
363
- // Store current token for refresh scenarios and caching
364
- let currentToken = config.token || null;
365
- let isRefreshing = false; // Prevent concurrent refresh attempts
366
- let refreshPromise = null;
367
- return {
368
- authType: config.authType || 'user',
369
- async getToken() {
370
- // If currently refreshing, wait for it to complete
371
- if (isRefreshing && refreshPromise) {
372
- await refreshPromise;
373
- return currentToken;
374
- }
375
- // Use cached current token (updated after refresh)
376
- if (currentToken) {
377
- return currentToken;
378
- }
379
- // Custom token provider function (always fresh)
380
- if (config.tokenProvider) {
381
- const token = await config.tokenProvider();
382
- currentToken = token; // Cache for future calls
383
- return token;
384
- }
385
- // No token available
386
- return null;
387
- },
388
- async getProjectKey() {
389
- return config.projectKey || null;
390
- },
391
- async onTokenExpired() {
392
- // Prevent concurrent refresh attempts
393
- if (isRefreshing) {
394
- if (refreshPromise) {
395
- await refreshPromise;
396
- }
397
- return;
398
- }
399
- // No refresh logic provided
400
- if (!config.onTokenExpired) {
401
- console.warn('Token expired but no refresh logic provided');
402
- currentToken = null; // Clear expired token
403
- return;
404
- }
405
- // Start refresh process
406
- isRefreshing = true;
407
- refreshPromise = (async () => {
408
- try {
409
- // Execute refresh logic (should update token source)
410
- await config.onTokenExpired();
411
- // After refresh, get the new token
412
- if (config.tokenProvider) {
413
- const newToken = await config.tokenProvider();
414
- if (newToken && newToken !== currentToken) {
415
- currentToken = newToken;
416
- // Notify about successful token refresh
417
- if (config.onTokenRefreshed) {
418
- config.onTokenRefreshed(newToken);
419
- }
420
- }
421
- else {
422
- console.warn('Token refresh completed but no new token received');
423
- currentToken = null;
424
- }
425
- }
426
- else {
427
- // For static token configs, clear the token since we can't refresh
428
- console.warn('Token expired for static token config - clearing token');
429
- currentToken = null;
430
- }
431
- }
432
- catch (error) {
433
- console.error('Token refresh failed:', error);
434
- currentToken = null; // Clear token on refresh failure
435
- throw error; // Re-throw to let SDK handle the error
436
- }
437
- finally {
438
- isRefreshing = false;
439
- refreshPromise = null;
440
- }
441
- })();
442
- await refreshPromise;
443
- }
444
- };
445
- }
446
- /**
447
- * Platform-specific localStorage token provider for browsers
448
- * This is a convenience function for browser environments
449
- */
450
- /* export function createBrowserTokenProvider(tokenKey: string = 'userJwt'): () => Promise<string | null> {
451
- return async () => {
452
- if (typeof localStorage !== 'undefined') {
453
- return localStorage.getItem(tokenKey);
454
- }
455
- return null;
456
- };
457
- } */
458
- /**
459
- * Platform-specific environment variable token provider for Node.js
460
- * This is a convenience function for Node.js environments
461
- */
462
- /* export function createNodeTokenProvider(envVar: string = 'JWT_TOKEN'): () => Promise<string | null> {
463
- return async () => {
464
- if (typeof process !== 'undefined' && process.env) {
465
- return process.env[envVar] || null;
466
- }
467
- return null;
468
- };
469
- } */
470
-
471
- /**
472
- * PERS SDK - Minimal platform-agnostic client with built-in authentication
473
- * Authentication is now handled at the SDK core level for better scalability
474
- */
475
- /**
476
- * Minimal PERS SDK - API client with authentication built-in
477
- * Platform adapters provide auth providers and HTTP clients
478
- */
479
- class PersSDK {
480
- constructor(httpClient, config) {
481
- this.apiClient = new PersApiClient(httpClient, config);
482
- }
483
- /**
484
- * Get the API client for direct PERS API calls
485
- * This is the main interface - keep it simple!
486
- */
487
- api() {
488
- return this.apiClient;
489
- }
490
- /**
491
- * Quick config check
492
- */
493
- isProduction() {
494
- return this.apiClient.getConfig().environment === 'production';
495
- }
496
- }
497
- /**
498
- * Simple factory function
499
- */
500
- function createPersSDK(httpClient, config) {
501
- return new PersSDK(httpClient, config);
502
- }
503
-
504
- /**
505
- * Platform-Agnostic Business API Client
506
- *
507
- * Updated to match the actual RESTful endpoints:
508
- * - /businesses for business operations
509
- * - /business-types for business type operations (separate controller)
510
- */
511
- class BusinessApi {
512
- constructor(apiClient) {
513
- this.apiClient = apiClient;
514
- this.basePath = '/businesses';
515
- this.businessTypesPath = '/business-types'; // ✅ FIX: Separate controller
516
- }
517
- // ==========================================
518
- // 🌐 BUSINESS TYPES MANAGEMENT
519
- // ==========================================
520
- /**
521
- * Get all business types (project key required)
522
- *
523
- * Endpoint: GET /business-types
524
- * Auth: @ApiSecurity('projectKey')
525
- */
526
- async getAllBusinessTypes() {
527
- return this.apiClient.get(this.businessTypesPath); // ✅ FIX: Correct path
528
- }
529
- /**
530
- * ADMIN: Create business type
531
- *
532
- * Endpoint: POST /business-types
533
- * Auth: @TenantAdmin()
534
- */
535
- async createBusinessType(dto) {
536
- return this.apiClient.post(this.businessTypesPath, dto); // ✅ FIX: Correct path
537
- }
538
- /**
539
- * ADMIN: Update business type
540
- *
541
- * Endpoint: PUT /business-types
542
- * Auth: @TenantAdmin()
543
- */
544
- async updateBusinessType(dto) {
545
- return this.apiClient.put(this.businessTypesPath, dto); // ✅ FIX: Correct path
546
- }
547
- /**
548
- * ADMIN: Delete business type
549
- *
550
- * Endpoint: DELETE /business-types/{id}
551
- * Auth: @TenantAdmin()
552
- */
553
- async deleteBusinessType(id) {
554
- return this.apiClient.delete(`${this.businessTypesPath}/${id}`); // ✅ FIX: Correct path
555
- }
556
- // ==========================================
557
- // 🏢 BUSINESS MANAGEMENT
558
- // ==========================================
559
- /**
560
- * Get current business info (business authentication required)
561
- *
562
- * Endpoint: GET /businesses/me
563
- * Auth: @Business()
564
- */
565
- async getCurrentBusiness() {
566
- return this.apiClient.get(`${this.basePath}/me`);
567
- }
568
- /**
569
- * Get all businesses with role-based filtering
570
- *
571
- * Endpoint: GET /businesses?active={boolean}&sanitize={mode}
572
- * Auth: @ApiSecurity('projectKey') (enhanced with role-based filtering)
573
- * Note:
574
- * - Project API Key users: Active businesses only (automatically filtered)
575
- * - Admin JWT users: Full access with all query parameters
576
- */
577
- async getAllBusinesses(options) {
578
- const params = new URLSearchParams();
579
- if (options?.active !== undefined) {
580
- params.append('active', String(options.active));
581
- }
582
- if (options?.sanitize) {
583
- params.append('sanitize', options.sanitize);
584
- }
585
- const queryString = params.toString();
586
- const url = queryString ? `${this.basePath}?${queryString}` : this.basePath;
587
- return this.apiClient.get(url);
588
- }
589
- /**
590
- * Get all active businesses (convenience method)
591
- *
592
- * Endpoint: GET /businesses
593
- * Auth: @ApiSecurity('projectKey')
594
- */
595
- async getActiveBusinesses() {
596
- return this.apiClient.get(this.basePath);
597
- }
598
- // ✅ REMOVED: getAllBusinessesAdmin() - No separate /admin endpoint exists
599
- // The unified endpoint handles role-based access automatically
600
- /**
601
- * Get business by ID
602
- *
603
- * Endpoint: GET /businesses/{id}
604
- * Auth: @ApiSecurity('projectKey')
605
- */
606
- async getBusinessById(businessId) {
607
- return this.apiClient.get(`${this.basePath}/${businessId}`);
608
- }
609
- /**
610
- * Get business by account address
611
- *
612
- * Endpoint: GET /businesses/account/{accountAddress}
613
- * Auth: @ApiSecurity('projectKey')
614
- */
615
- async getBusinessByAccount(accountAddress) {
616
- return this.apiClient.get(`${this.basePath}/account/${accountAddress}`);
617
- }
618
- // ==========================================
619
- // 🔧 ADMIN OPERATIONS
620
- // ==========================================
621
- /**
622
- * ADMIN: Create business
623
- *
624
- * Endpoint: POST /businesses
625
- * Auth: @TenantAdmin()
626
- * Returns: BusinessApiKeyDTO | BusinessTokenBalancesDTO
627
- */
628
- async createBusiness(dto) {
629
- return this.apiClient.post(this.basePath, dto);
630
- }
631
- /**
632
- * ADMIN: Create business by display name (convenience method)
633
- */
634
- async createBusinessByDisplayName(displayName) {
635
- const dto = {
636
- displayName,
637
- // Add other required fields based on BusinessCreateRequestDTO structure
638
- };
639
- return this.createBusiness(dto);
640
- }
641
- /**
642
- * ADMIN: Create businesses from URL
643
- *
644
- * Endpoint: POST /businesses/bulk/url
645
- * Auth: @TenantAdmin()
646
- */
647
- async createBusinessesFromUrl(url) {
648
- return this.apiClient.post(`${this.basePath}/bulk/url`, { url });
649
- }
650
- /**
651
- * ADMIN: Update business
652
- *
653
- * Endpoint: PUT /businesses/{id}
654
- * Auth: @TenantAdmin()
655
- */
656
- async updateBusiness(id, businessData) {
657
- return this.apiClient.put(`${this.basePath}/${id}`, businessData);
658
- }
659
- /**
660
- * ADMIN: Toggle business active status
661
- *
662
- * Endpoint: PUT /businesses/{id}/status
663
- * Auth: @TenantAdmin()
664
- */
665
- async toggleBusinessActive(id, isActive) {
666
- const dto = { isActive };
667
- return this.apiClient.put(`${this.basePath}/${id}/status`, dto); // ✅ FIX: Correct endpoint
668
- }
669
- }
670
-
671
- /**
672
- * Platform-Agnostic Business Service
673
- *
674
- * Contains business logic and operations that work across platforms.
675
- * No framework dependencies - pure TypeScript business logic.
676
- *
677
- * Focuses only on actual backend capabilities.
678
- */
679
- class BusinessService {
680
- constructor(businessApi) {
681
- this.businessApi = businessApi;
682
- }
683
- /**
684
- * Get all active businesses
685
- */
686
- async getActiveBusinesses() {
687
- return this.businessApi.getActiveBusinesses();
688
- }
689
- /**
690
- * Get all business types
691
- */
692
- async getAllBusinessTypes() {
693
- return this.businessApi.getAllBusinessTypes();
694
- }
695
- /**
696
- * Get business by ID
697
- */
698
- async getBusinessById(businessId) {
699
- return this.businessApi.getBusinessById(businessId);
700
- }
701
- /**
702
- * Get business by account address
703
- */
704
- async getBusinessByAccount(accountAddress) {
705
- return this.businessApi.getBusinessByAccount(accountAddress);
706
- }
707
- /**
708
- * Get businesses by type (client-side filtering)
709
- */
710
- async getBusinessesByType(typeId) {
711
- const businesses = await this.getActiveBusinesses();
712
- return businesses.filter(business => business.businessType && business.businessType.id === parseInt(typeId));
713
- }
714
- // ==========================================
715
- // ADMIN OPERATIONS
716
- // ==========================================
717
- /**
718
- * ADMIN: Get all businesses (active and inactive)
719
- */
720
- async getAllBusinesses() {
721
- return this.businessApi.getAllBusinesses();
722
- }
723
- /**
724
- * ADMIN: Create business by display name
725
- */
726
- async createBusinessByDisplayName(displayName) {
727
- return this.businessApi.createBusinessByDisplayName(displayName);
728
- }
729
- /**
730
- * ADMIN: Update business
731
- */
732
- async updateBusiness(id, businessData) {
733
- return this.businessApi.updateBusiness(id, businessData);
734
- }
735
- /**
736
- * ADMIN: Toggle business active status
737
- */
738
- async toggleBusinessActive(id, isActive) {
739
- return this.businessApi.toggleBusinessActive(id, isActive);
740
- }
741
- }
742
-
743
- /**
744
- * @explorins/pers-sdk-business
745
- *
746
- * Platform-agnostic Business Domain SDK for PERS ecosystem
747
- * Focuses on non-admin business operations
748
- */
749
- // API Layer
750
- /**
751
- * Create a complete Business SDK instance
752
- *
753
- * @param apiClient - Configured PERS API client
754
- * @returns Business SDK with flattened structure for better DX
755
- */
756
- function createBusinessSDK(apiClient) {
757
- const businessApi = new BusinessApi(apiClient);
758
- const businessService = new BusinessService(businessApi);
759
- return {
760
- // Direct access to service methods (primary interface)
761
- getActiveBusinesses: () => businessService.getActiveBusinesses(),
762
- getAllBusinessTypes: () => businessService.getAllBusinessTypes(),
763
- getBusinessById: (businessId) => businessService.getBusinessById(businessId),
764
- getBusinessByAccount: (accountAddress) => businessService.getBusinessByAccount(accountAddress),
765
- getBusinessesByType: (typeId) => businessService.getBusinessesByType(typeId),
766
- // Admin methods
767
- getAllBusinesses: () => businessService.getAllBusinesses(),
768
- createBusinessByDisplayName: (displayName) => businessService.createBusinessByDisplayName(displayName),
769
- updateBusiness: (id, businessData) => businessService.updateBusiness(id, businessData),
770
- toggleBusinessActive: (id, isActive) => businessService.toggleBusinessActive(id, isActive),
771
- // Advanced access for edge cases
772
- api: businessApi,
773
- service: businessService
774
- };
775
- }
776
-
777
- /**
778
- * Platform-Agnostic Transaction API Client (UPDATED FOR NEW RESTful ENDPOINTS)
779
- *
780
- * Handles transaction operations using the PERS backend.
781
- * Uses @explorins/pers-shared DTOs for consistency with backend.
782
- *
783
- * MIGRATION NOTES:
784
- * - All endpoints changed from /transaction to /transactions
785
- * - Role-based paths removed (no more /auth, /admin, /business in URLs)
786
- * - New RESTful resource-based structure
787
- * - Added new client-side transaction flow methods
788
- * - Enhanced admin query capabilities
789
- */
790
- class TransactionApi {
791
- constructor(apiClient) {
792
- this.apiClient = apiClient;
793
- this.basePath = '/transactions';
794
- }
795
- /**
796
- * Get transaction by ID (public endpoint)
797
- *
798
- * UPDATED: /transaction/{id} → /transactions/{id}
799
- */
800
- async getTransactionById(transactionId) {
801
- return this.apiClient.get(`${this.basePath}/${transactionId}`);
802
- }
803
- /**
804
- * Unique method to create a transaction
805
- * @param request
806
- * @returns
807
- */
808
- async createTransaction(request) {
809
- return this.apiClient.post(`${this.basePath}`, request);
810
- // return this.apiClient.post<TransactionDTO>(`${this.basePath}/system`, request);
811
- }
812
- // ==========================================
813
- // AUTHENTICATED USER OPERATIONS
814
- // ==========================================
815
- /**
816
- * AUTH: Create authenticated user transaction
817
- *
818
- * UPDATED: /transaction/auth/transaction → /transactions/user
819
- */
820
- /* async createAuthTransaction(request: TransactionRequestDTO): Promise<TransactionRequestResponseDTO> {
821
- return this.apiClient.post<TransactionRequestResponseDTO>(`${this.basePath}`, request);
822
- } */
823
- /**
824
- * AUTH: Get user's sent transactions
825
- *
826
- * UPDATED: /transaction/auth/sender → /transactions/me/sent
827
- */
828
- async getUserSentTransactions() {
829
- const params = new URLSearchParams({
830
- timestamp: Date.now().toString()
831
- });
832
- return this.apiClient.get(`${this.basePath}/me/sent?${params.toString()}`);
833
- }
834
- /**
835
- * AUTH: Get user's received transactions
836
- *
837
- * UPDATED: /transaction/auth/recipient → /transactions/me/received
838
- */
839
- async getUserReceivedTransactions() {
840
- const params = new URLSearchParams({
841
- timestamp: Date.now().toString()
842
- });
843
- return this.apiClient.get(`${this.basePath}/me/received?${params.toString()}`);
844
- }
845
- /**
846
- * AUTH: Get user transaction history by type (backwards compatibility)
847
- *
848
- * UPDATED: Maps to appropriate /transactions/me/* endpoints
849
- */
850
- async getUserTransactionHistory(type) {
851
- const params = new URLSearchParams({
852
- timestamp: Date.now().toString()
853
- });
854
- // Map legacy type parameter to new endpoints
855
- switch (type.toLowerCase()) {
856
- case 'sender':
857
- case 'sent':
858
- return this.apiClient.get(`${this.basePath}/me/sent?${params.toString()}`);
859
- case 'recipient':
860
- case 'received':
861
- return this.apiClient.get(`${this.basePath}/me/received?${params.toString()}`);
862
- default:
863
- // Default to sent transactions for backwards compatibility
864
- return this.apiClient.get(`${this.basePath}/me/sent?${params.toString()}`);
865
- }
866
- }
867
- /**
868
- * AUTH: Prepare existing transaction for client-side signing
869
- *
870
- * NEW ENDPOINT: GET /transactions/{id}/prepare
871
- */
872
- async prepareExistingTransaction(transactionId) {
873
- return this.apiClient.get(`${this.basePath}/${transactionId}/prepare`);
874
- }
875
- /**
876
- * AUTH: Submit client-side signed transaction
877
- *
878
- * NEW ENDPOINT: POST /transactions/{id}/submit
879
- */
880
- async submitSignedTransaction(signedTxData) {
881
- return this.apiClient.post(`${this.basePath}/submit`, signedTxData);
882
- }
883
- /**
884
- * AUTH: Burn user tokens
885
- *
886
- * UPDATED: Uses new user transaction endpoint with burn-specific parameters
887
- * Note: This might need backend confirmation on burn functionality implementation
888
- */
889
- /* async burnUserTokens(request: UserBurnTokenRequestDTO): Promise<TransactionRequestResponseDTO> {
890
- // Map burn request to TransactionRequestDTO format for new endpoint
891
- const transactionRequest: TransactionRequestDTO = {
892
- ...request,
893
- // Add any specific burn transaction parameters here
894
- } as any;
895
-
896
- return this.apiClient.post<TransactionRequestResponseDTO>(`${this.basePath}`, transactionRequest);
897
- } */
898
- // ==========================================
899
- // BUSINESS OPERATIONS
900
- // ==========================================
901
- /**
902
- * BUSINESS: Create business transaction
903
- *
904
- * UPDATED: /transaction/business/transaction → /transactions/business
905
- */
906
- /* async createBusinessTransaction(request: TransactionRequestDTO): Promise<TransactionRequestResponseDTO> {
907
- return this.apiClient.post<TransactionRequestResponseDTO>(`${this.basePath}`, request);
908
- } */
909
- // ==========================================
910
- // ADMIN OPERATIONS
911
- // ==========================================
912
- /**
913
- * ADMIN: Create admin transaction
914
- *
915
- * UPDATED: /transaction/admin/transaction → /transactions/admin
916
- */
917
- /* async createAdminTransaction(request: TransactionRequestDTO): Promise<TransactionRequestResponseDTO> {
918
- // return this.apiClient.post<TransactionRequestResponseDTO>(`${this.basePath}`, request);
919
- return this.apiClient.post<TransactionDTO>(`${this.basePath}/system`, request);
920
- } */
921
- /**
922
- * AUTH: Prepare client signed transaction
923
- *
924
- * UPDATED: /transaction/auth/prepare-signing → /transactions/prepare
925
- */
926
- async prepareClientSignedTransaction(request) {
927
- return this.apiClient.post(`${this.basePath}`, request);
928
- }
929
- /**
930
- * ADMIN: Get all tenant transactions
931
- *
932
- * UPDATED: /transaction/admin → /transactions
933
- */
934
- async getTenantTransactions() {
935
- const result = await this.apiClient.get(`${this.basePath}`);
936
- // If the new endpoint returns paginated response, extract the data array
937
- if ('data' in result) {
938
- return result.data;
939
- }
940
- // Fallback for direct array response
941
- return result;
942
- }
943
- /**
944
- * ADMIN: Get paginated transactions with filtering and sorting
945
- *
946
- * UPDATED: /transaction/admin → /transactions (same endpoint, better structure)
947
- */
948
- async getPaginatedTransactions(params) {
949
- // Build query parameters
950
- const queryParams = {
951
- page: params.page.toString(),
952
- limit: params.limit.toString()
953
- };
954
- // Add sorting parameters if provided
955
- if (params.sortBy) {
956
- queryParams['sortBy'] = params.sortBy;
957
- }
958
- if (params.sortOrder) {
959
- queryParams['sortOrder'] = params.sortOrder;
960
- }
961
- // Add user-specific filtering if provided
962
- if (params.participantId) {
963
- queryParams['participantId'] = params.participantId;
964
- }
965
- // Add status filtering if provided
966
- if (params.status) {
967
- queryParams['status'] = params.status;
968
- }
969
- // Add additional filters if provided
970
- if (params.filters) {
971
- if (params.filters.startDate) {
972
- queryParams['startDate'] = params.filters.startDate;
973
- }
974
- if (params.filters.endDate) {
975
- queryParams['endDate'] = params.filters.endDate;
976
- }
977
- if (params.filters.type && params.filters.type.length > 0) {
978
- queryParams['type'] = params.filters.type.join(',');
979
- }
980
- if (params.filters.tokenType && params.filters.tokenType.length > 0) {
981
- queryParams['tokenType'] = params.filters.tokenType.join(',');
982
- }
983
- }
984
- // Build query string
985
- const queryString = Object.entries(queryParams)
986
- .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
987
- .join('&');
988
- return this.apiClient.get(`${this.basePath}?${queryString}`);
989
- }
990
- /**
991
- * ADMIN: Export transactions to CSV
992
- *
993
- * UPDATED: /transaction/admin/export/csv → /transactions/export/csv
994
- */
995
- async exportTransactionsCSV() {
996
- return this.apiClient.get(`${this.basePath}/export/csv`, 'blob');
997
- }
998
- // ==========================================
999
- // NEW ADMIN QUERY METHODS
1000
- // ==========================================
1001
- /**
1002
- * ADMIN: Query transactions by sender
1003
- *
1004
- * NEW ENDPOINT: POST /transactions/query-sender
1005
- */
1006
- /**
1007
- * Query transactions by sender using unified endpoint
1008
- */
1009
- async queryTransactionsBySender(accountSelector) {
1010
- // Build query parameters safely
1011
- const queryParams = {};
1012
- if (accountSelector.accountId) {
1013
- queryParams['participantId'] = accountSelector.accountId;
1014
- }
1015
- queryParams['role'] = persShared.TransactionRole.SENDER.toString();
1016
- const params = new URLSearchParams(queryParams);
1017
- return this.apiClient.get(`${this.basePath}?${params.toString()}`).then(response => response); // Extract items from paginated response
1018
- }
1019
- /**
1020
- * Query transactions by recipient using unified endpoint
1021
- */
1022
- async queryTransactionsByRecipient(accountSelector) {
1023
- // Build query parameters safely
1024
- const queryParams = {};
1025
- if (accountSelector.accountId) {
1026
- queryParams['participantId'] = accountSelector.accountId;
1027
- }
1028
- queryParams['role'] = persShared.TransactionRole.RECIPIENT.toString();
1029
- const params = new URLSearchParams(queryParams);
1030
- return this.apiClient.get(`${this.basePath}?${params.toString()}`).then(response => response); // Extract items from paginated response
1031
- }
1032
- /**
1033
- * ADMIN: Get transaction analytics
1034
- *
1035
- * NEW ENDPOINT: POST /transactions/analytics
1036
- */
1037
- async getTransactionAnalytics(analyticsRequest) {
1038
- return this.apiClient.post(`${this.basePath}/analytics`, analyticsRequest);
1039
- }
1040
- // ==========================================
1041
- // CONVENIENCE METHODS (BACKWARDS COMPATIBILITY)
1042
- // ==========================================
1043
- /**
1044
- * Convenience method: Get user sent transactions (alias)
1045
- */
1046
- async getUserSenderTransactions() {
1047
- return this.getUserSentTransactions();
1048
- }
1049
- /**
1050
- * Convenience method: Get user received transactions (alias)
1051
- */
1052
- async getUserRecipientTransactions() {
1053
- return this.getUserReceivedTransactions();
1054
- }
1055
- }
1056
-
1057
- /**
1058
- * Platform-Agnostic Transaction Service
1059
- *
1060
- * Contains transaction business logic and operations that work across platforms.
1061
- * No framework dependencies - pure TypeScript business logic.
1062
- *
1063
- * Focuses only on actual backend capabilities.
1064
- */
1065
- class TransactionService {
1066
- constructor(transactionApi) {
1067
- this.transactionApi = transactionApi;
1068
- }
1069
- /**
1070
- * Get transaction by ID
1071
- */
1072
- async getTransactionById(transactionId) {
1073
- return this.transactionApi.getTransactionById(transactionId);
1074
- }
1075
- // ==========================================
1076
- // AUTHENTICATED OPERATIONS
1077
- // ==========================================
1078
- /**
1079
- * AUTH: Create authenticated transaction
1080
- */
1081
- /* async createAuthTransaction(request: TransactionRequestDTO): Promise<TransactionRequestResponseDTO> {
1082
- return this.transactionApi.createAuthTransaction(request);
1083
- } */
1084
- async createTransaction(request) {
1085
- return this.transactionApi.createTransaction(request);
1086
- }
1087
- async submitSignedTransaction(signedTxData) {
1088
- return this.transactionApi.submitSignedTransaction(signedTxData);
1089
- }
1090
- /**
1091
- * AUTH: Get user transaction history by type
1092
- */
1093
- async getUserTransactionHistory(type) {
1094
- return this.transactionApi.getUserTransactionHistory(type);
1095
- }
1096
- /**
1097
- * AUTH: Prepare client signed transaction
1098
- */
1099
- /* async prepareClientSignedTransaction(request: TransactionRequestDTO): Promise<TransactionRequestResponseDTO> {
1100
- return this.transactionApi.prepareClientSignedTransaction(request);
1101
- } */
1102
- /**
1103
- * AUTH: Burn user tokens
1104
- */
1105
- /* async burnUserTokens(request: UserBurnTokenRequestDTO): Promise<TransactionRequestResponseDTO> {
1106
- return this.transactionApi.burnUserTokens(request);
1107
- } */
1108
- // ==========================================
1109
- // BUSINESS OPERATIONS
1110
- // ==========================================
1111
- /**
1112
- * BUSINESS: Create business transaction
1113
- */
1114
- /* async createBusinessTransaction(request: TransactionRequestDTO): Promise<TransactionRequestResponseDTO> {
1115
- return this.transactionApi.createBusinessTransaction(request);
1116
- } */
1117
- // ==========================================
1118
- // ADMIN OPERATIONS
1119
- // ==========================================
1120
- /**
1121
- * ADMIN: Create admin transaction
1122
- */
1123
- /* async createAdminTransaction(request: TransactionRequestDTO): Promise<TransactionRequestResponseDTO> {
1124
- return this.transactionApi.createAdminTransaction(request);
1125
- } */
1126
- /**
1127
- * ADMIN: Get all tenant transactions
1128
- */
1129
- async getTenantTransactions() {
1130
- return this.transactionApi.getTenantTransactions();
1131
- }
1132
- /**
1133
- * ADMIN: Get paginated transactions with filtering and sorting
1134
- */
1135
- async getPaginatedTransactions(params) {
1136
- return this.transactionApi.getPaginatedTransactions(params);
1137
- }
1138
- /**
1139
- * ADMIN: Export transactions to CSV
1140
- */
1141
- async exportTransactionsCSV() {
1142
- return this.transactionApi.exportTransactionsCSV();
1143
- }
1144
- }
1145
-
1146
- /**
1147
- * Transaction Domain Models
1148
- *
1149
- * Re-exports from @explorins/pers-shared for consistency with backend
1150
- * and to provide a single import source for transaction-related types.
1151
- */
1152
- // Transaction account types (domain-specific enum)
1153
- exports.TransactionAccountType = void 0;
1154
- (function (TransactionAccountType) {
1155
- // Add specific transaction account types as needed
1156
- // This should match the enum used in the infrastructure layer
1157
- })(exports.TransactionAccountType || (exports.TransactionAccountType = {}));
1158
-
1159
- /**
1160
- * @explorins/pers-sdk-transaction
1161
- *
1162
- * Platform-agnostic Transaction Domain SDK for PERS ecosystem
1163
- * Handles transaction operations across different authorization levels
1164
- */
1165
- // API Layer
1166
- /**
1167
- * Create a complete Transaction SDK instance
1168
- *
1169
- * @param apiClient - Configured PERS API client
1170
- * @returns Transaction SDK with flattened structure for better DX
1171
- */
1172
- function createTransactionSDK(apiClient) {
1173
- const transactionApi = new TransactionApi(apiClient);
1174
- const transactionService = new TransactionService(transactionApi);
1175
- return {
1176
- // Direct access to service methods (primary interface)
1177
- // Public methods
1178
- getTransactionById: (transactionId) => transactionService.getTransactionById(transactionId),
1179
- createTransaction: (request) => transactionService.createTransaction(request),
1180
- // Auth methods
1181
- // createAuthTransaction: (request: TransactionRequestDTO) => transactionService.createAuthTransaction(request),
1182
- getUserTransactionHistory: (type) => transactionService.getUserTransactionHistory(type),
1183
- //prepareClientSignedTransaction: (request: TransactionRequestDTO) => transactionService.prepareClientSignedTransaction(request),
1184
- // burnUserTokens: (request: UserBurnTokenRequestDTO) => transactionService.burnUserTokens(request),
1185
- // Business methods
1186
- // createBusinessTransaction: (request: TransactionRequestDTO) => transactionService.createBusinessTransaction(request),
1187
- // Admin methods
1188
- // createAdminTransaction: (request: TransactionRequestDTO) => transactionService.createAdminTransaction(request),
1189
- getTenantTransactions: () => transactionService.getTenantTransactions(),
1190
- getPaginatedTransactions: (params) => transactionService.getPaginatedTransactions(params),
1191
- exportTransactionsCSV: () => transactionService.exportTransactionsCSV(),
1192
- // Advanced access for edge cases
1193
- api: transactionApi,
1194
- service: transactionService
1195
- };
1196
- }
1197
-
1198
- /**
1199
- * Platform-Agnostic Analytics API Client
1200
- *
1201
- * Handles analytics operations using the PERS backend.
1202
- * Uses @explorins/pers-shared DTOs for consistency with backend.
1203
- */
1204
- class AnalyticsApi {
1205
- constructor(apiClient) {
1206
- this.apiClient = apiClient;
1207
- }
1208
- // ==========================================
1209
- // ADMIN OPERATIONS
1210
- // ==========================================
1211
- /**
1212
- * ADMIN: Get transaction analytics with filtering and aggregation
1213
- */
1214
- async getTransactionAnalytics(request) {
1215
- return this.apiClient.post('/transactions/analytics', request);
1216
- }
1217
- }
1218
-
1219
- /**
1220
- * Platform-Agnostic Analytics Service
1221
- *
1222
- * Contains analytics business logic and operations that work across platforms.
1223
- * No framework dependencies - pure TypeScript business logic.
1224
- *
1225
- * Focuses only on actual backend capabilities.
1226
- */
1227
- class AnalyticsService {
1228
- constructor(analyticsApi) {
1229
- this.analyticsApi = analyticsApi;
1230
- }
1231
- // ==========================================
1232
- // ADMIN OPERATIONS
1233
- // ==========================================
1234
- /**
1235
- * ADMIN: Get transaction analytics with filtering and aggregation
1236
- */
1237
- async getTransactionAnalytics(request) {
1238
- return this.analyticsApi.getTransactionAnalytics(request);
1239
- }
1240
- }
1241
-
1242
- /**
1243
- * @explorins/pers-sdk-analytics
1244
- *
1245
- * Platform-agnostic Analytics Domain SDK for PERS ecosystem
1246
- * Handles analytics operations and data aggregation
1247
- */
1248
- // API Layer
1249
- /**
1250
- * Create a complete Analytics SDK instance
1251
- *
1252
- * @param apiClient - Configured PERS API client
1253
- * @returns Analytics SDK with flattened structure for better DX
1254
- */
1255
- function createAnalyticsSDK(apiClient) {
1256
- const analyticsApi = new AnalyticsApi(apiClient);
1257
- const analyticsService = new AnalyticsService(analyticsApi);
1258
- return {
1259
- // Direct access to service methods (primary interface)
1260
- // Admin methods
1261
- getTransactionAnalytics: (request) => analyticsService.getTransactionAnalytics(request),
1262
- // Advanced access for edge cases
1263
- api: analyticsApi,
1264
- service: analyticsService
1265
- };
1266
- }
1267
-
1268
- /**
1269
- * Platform-Agnostic Auth Admin API Client
1270
- *
1271
- * Handles authentication and authorization admin operations using the PERS backend.
1272
- * Uses @explorins/pers-shared DTOs for consistency with backend.
1273
- *
1274
- * Note: Special header handling (bypass-auth-interceptor) may need to be implemented
1275
- * at the PersApiClient level or through a specialized auth client.
1276
- */
1277
- class AuthAdminApi {
1278
- constructor(apiClient) {
1279
- this.apiClient = apiClient;
1280
- this.basePath = '/auth';
1281
- }
1282
- // ==========================================
1283
- // ADMIN AUTHENTICATION OPERATIONS
1284
- // ==========================================
1285
- /**
1286
- * ADMIN: Login tenant admin with JWT
1287
- * Note: JWT handling and auth bypass headers may need special implementation
1288
- */
1289
- async loginTenantAdmin(jwt) {
1290
- const body = {
1291
- authToken: jwt,
1292
- authType: persShared.AccountOwnerType.TENANT
1293
- };
1294
- return this.apiClient.post(`${this.basePath}/token`, body);
1295
- }
1296
- async loginUser(jwt) {
1297
- const body = {
1298
- authToken: jwt,
1299
- authType: persShared.AccountOwnerType.USER
1300
- };
1301
- return this.apiClient.post(`${this.basePath}/token`, body);
1302
- }
1303
- /**
1304
- * ADMIN: Refresh access token
1305
- * Note: Bypass header handling may need special implementation
1306
- */
1307
- async refreshAccessToken(refreshToken) {
1308
- return this.apiClient.post(`${this.basePath}/refresh`, { refreshToken });
1309
- }
1310
- }
1311
-
1312
- /**
1313
- * Platform-Agnostic Auth Admin Service
1314
- *
1315
- * Contains auth admin business logic and operations that work across platforms.
1316
- * No framework dependencies - pure TypeScript business logic.
1317
- *
1318
- * Focuses only on actual backend capabilities.
1319
- */
1320
- class AuthAdminService {
1321
- constructor(authAdminApi) {
1322
- this.authAdminApi = authAdminApi;
1323
- }
1324
- // ==========================================
1325
- // ADMIN AUTHENTICATION OPERATIONS
1326
- // ==========================================
1327
- /**
1328
- * ADMIN: Login tenant admin with JWT
1329
- */
1330
- async loginTenantAdmin(jwt) {
1331
- return this.authAdminApi.loginTenantAdmin(jwt);
1332
- }
1333
- /**
1334
- * ADMIN: Login user with JWT
1335
- */
1336
- async loginUser(jwt) {
1337
- return this.authAdminApi.loginUser(jwt);
1338
- }
1339
- /**
1340
- * ADMIN: Refresh access token
1341
- */
1342
- async refreshAccessToken(refreshToken) {
1343
- return this.authAdminApi.refreshAccessToken(refreshToken);
1344
- }
1345
- }
1346
-
1347
- /**
1348
- * @explorins/pers-sdk-auth-admin
1349
- *
1350
- * Platform-agnostic Auth Admin Domain SDK for PERS ecosystem
1351
- * Handles authentication and authorization admin operations
1352
- */
1353
- // API Layer
1354
- /**
1355
- * Create a complete Auth Admin SDK instance
1356
- *
1357
- * @param apiClient - Configured PERS API client
1358
- * @returns Auth Admin SDK with flattened structure for better DX
1359
- */
1360
- function createAuthAdminSDK(apiClient) {
1361
- const authAdminApi = new AuthAdminApi(apiClient);
1362
- const authAdminService = new AuthAdminService(authAdminApi);
1363
- return {
1364
- // Direct access to service methods (primary interface)
1365
- // Admin authentication methods
1366
- loginTenantAdmin: (jwt) => authAdminService.loginTenantAdmin(jwt),
1367
- loginUser: (jwt) => authAdminService.loginUser(jwt),
1368
- refreshAccessToken: (refreshToken) => authAdminService.refreshAccessToken(refreshToken),
1369
- // Advanced access for edge cases
1370
- api: authAdminApi,
1371
- service: authAdminService
1372
- };
1373
- }
1374
-
1375
- /**
1376
- * Platform-Agnostic Campaign API Client (NEW - RESTful Design)
1377
- *
1378
- * Updated to use the new microservice-ready campaign controllers:
1379
- * - CampaignsController: Core campaign operations
1380
- * - CampaignTagsController: Tag management
1381
- * - CampaignTokensController: Token unit operations
1382
- * - CampaignTriggersController: Trigger system
1383
- * - CampaignEngagementsController: Business relationships
1384
- * - CampaignClaimsController: Claims processing
1385
- *
1386
- * Uses @explorins/pers-shared DTOs for consistency with backend.
1387
- * All endpoints updated to new RESTful patterns without role revelation.
1388
- */
1389
- class CampaignApi {
1390
- constructor(apiClient) {
1391
- this.apiClient = apiClient;
1392
- }
1393
- // ==========================================
1394
- // CORE CAMPAIGN OPERATIONS (/campaigns)
1395
- // ==========================================
1396
- /**
1397
- * PUBLIC: Get all active campaigns
1398
- * NEW: /campaigns (intelligent access detection)
1399
- */
1400
- async getActiveCampaigns() {
1401
- return this.apiClient.get('/campaigns');
1402
- }
1403
- /**
1404
- * ADMIN: Get campaigns with filtering options
1405
- * NEW: /campaigns with query parameters (admin access detected automatically)
1406
- */
1407
- async getCampaigns(options) {
1408
- let url = '/campaigns';
1409
- const params = [];
1410
- if (options) {
1411
- if (options.active !== undefined)
1412
- params.push(`active=${options.active}`);
1413
- if (options.tag)
1414
- params.push(`tag=${encodeURIComponent(options.tag)}`);
1415
- if (options.limit)
1416
- params.push(`limit=${options.limit}`);
1417
- if (options.offset)
1418
- params.push(`offset=${options.offset}`);
1419
- if (options.sort)
1420
- params.push(`sort=${options.sort}`);
1421
- if (options.order)
1422
- params.push(`order=${options.order}`);
1423
- }
1424
- if (params.length > 0) {
1425
- url += `?${params.join('&')}`;
1426
- }
1427
- return this.apiClient.get(url);
1428
- }
1429
- /**
1430
- * PUBLIC: Get campaign by ID
1431
- * NEW: /campaigns/{id}
1432
- */
1433
- async getCampaignById(id) {
1434
- return this.apiClient.get(`/campaigns/${id}`);
1435
- }
1436
- /**
1437
- * ADMIN: Create campaign
1438
- * NEW: POST /campaigns
1439
- */
1440
- async createCampaign(campaign) {
1441
- return this.apiClient.post('/campaigns', campaign);
1442
- }
1443
- /**
1444
- * ADMIN: Update campaign
1445
- * NEW: PUT /campaigns/{id}
1446
- */
1447
- async updateCampaign(campaignId, campaign) {
1448
- return this.apiClient.put(`/campaigns/${campaignId}`, campaign);
1449
- }
1450
- /**
1451
- * ADMIN: Toggle campaign active status
1452
- * NEW: PUT /campaigns/{id}/status
1453
- */
1454
- async toggleCampaignActive(campaignId) {
1455
- return this.apiClient.put(`/campaigns/${campaignId}/status`, {});
1456
- }
1457
- /**
1458
- * ADMIN: Toggle campaign testnet environment
1459
- * NEW: PUT /campaigns/{id}/environment
1460
- */
1461
- async toggleCampaignTestnet(campaignId) {
1462
- return this.apiClient.put(`/campaigns/${campaignId}/environment`, {});
1463
- }
1464
- /**
1465
- * ADMIN: Delete campaign
1466
- * NEW: DELETE /campaigns/{id}
1467
- */
1468
- async deleteCampaign(campaignId) {
1469
- return this.apiClient.delete(`/campaigns/${campaignId}`);
1470
- }
1471
- // ==========================================
1472
- // TAG MANAGEMENT (/campaign-tags)
1473
- // ==========================================
1474
- /**
1475
- * ADMIN: Get all unique campaign tags
1476
- * NEW: GET /campaign-tags
1477
- */
1478
- async getAllUniqueTags() {
1479
- return this.apiClient.get('/campaign-tags');
1480
- }
1481
- /**
1482
- * ADMIN: Update campaign tags (replace all)
1483
- * NEW: PUT /campaign-tags/{id}
1484
- */
1485
- async updateCampaignTags(campaignId, tags) {
1486
- return this.apiClient.put(`/campaign-tags/${campaignId}`, { tags });
1487
- }
1488
- /**
1489
- * ADMIN: Add tags to campaign
1490
- * NEW: POST /campaign-tags/{id}
1491
- */
1492
- async addTagsToCampaign(campaignId, tags) {
1493
- return this.apiClient.post(`/campaign-tags/${campaignId}`, { tags });
1494
- }
1495
- /**
1496
- * ADMIN: Remove tag from campaign
1497
- * NEW: DELETE /campaign-tags/{id}/{tag}
1498
- */
1499
- async removeTagFromCampaign(campaignId, tag) {
1500
- return this.apiClient.delete(`/campaign-tags/${campaignId}/${encodeURIComponent(tag)}`);
1501
- }
1502
- // ==========================================
1503
- // TOKEN MANAGEMENT (/campaign-tokens)
1504
- // ==========================================
1505
- /**
1506
- * ADMIN: Create campaign token unit
1507
- * NEW: POST /campaign-tokens/{id}
1508
- */
1509
- async createCampaignTokenUnit(campaignId, campaignTokenUnit) {
1510
- return this.apiClient.post(`/campaign-tokens/${campaignId}`, campaignTokenUnit);
1511
- }
1512
- /**
1513
- * ADMIN: Update campaign token unit
1514
- * NEW: PUT /campaign-tokens/{id}/{tokenUnitId}
1515
- */
1516
- async updateCampaignTokenUnit(campaignId, tokenUnitId, campaignTokenUnit) {
1517
- return this.apiClient.put(`/campaign-tokens/${campaignId}/${tokenUnitId}`, campaignTokenUnit);
1518
- }
1519
- /**
1520
- * ADMIN: Delete campaign token unit
1521
- * NEW: DELETE /campaign-tokens/{id}/{tokenUnitId}
1522
- */
1523
- async deleteCampaignTokenUnit(campaignId, campaignTokenUnitId) {
1524
- return this.apiClient.delete(`/campaign-tokens/${campaignId}/${campaignTokenUnitId}`);
1525
- }
1526
- // ==========================================
1527
- // TRIGGER SYSTEM (/campaign-triggers)
1528
- // ==========================================
1529
- /**
1530
- * PUBLIC: Get campaign triggers catalog
1531
- * NEW: GET /campaign-triggers
1532
- */
1533
- async getCampaignTriggers() {
1534
- return this.apiClient.get('/campaign-triggers');
1535
- }
1536
- /**
1537
- * ADMIN: Create campaign trigger
1538
- * NEW: POST /campaign-triggers
1539
- */
1540
- async createCampaignTrigger(trigger) {
1541
- return this.apiClient.post('/campaign-triggers', trigger);
1542
- }
1543
- /**
1544
- * ADMIN: Update campaign trigger
1545
- * NEW: PUT /campaign-triggers/{id}
1546
- */
1547
- async updateCampaignTrigger(triggerId, trigger) {
1548
- return this.apiClient.put(`/campaign-triggers/${triggerId}`, trigger);
1549
- }
1550
- /**
1551
- * ADMIN: Delete campaign trigger
1552
- * NEW: DELETE /campaign-triggers/{id}
1553
- */
1554
- async deleteCampaignTrigger(triggerId) {
1555
- return this.apiClient.delete(`/campaign-triggers/${triggerId}`);
1556
- }
1557
- /**
1558
- * ADMIN: Set campaign trigger
1559
- * NEW: PUT /campaign-triggers/campaigns/{id}/trigger/{triggerId}
1560
- */
1561
- async setCampaignTrigger(campaignId, triggerId) {
1562
- return this.apiClient.put(`/campaign-triggers/campaigns/${campaignId}/trigger/${triggerId}`, {});
1563
- }
1564
- /**
1565
- * ADMIN: Create trigger condition
1566
- * NEW: POST /campaign-triggers/conditions
1567
- */
1568
- async createTriggerCondition(condition) {
1569
- return this.apiClient.post('/campaign-triggers/conditions', condition);
1570
- }
1571
- /**
1572
- * ADMIN: Update trigger condition
1573
- * NEW: PUT /campaign-triggers/conditions/{id}
1574
- */
1575
- async updateTriggerCondition(conditionId, condition) {
1576
- return this.apiClient.put(`/campaign-triggers/conditions/${conditionId}`, condition);
1577
- }
1578
- /**
1579
- * ADMIN: Add/Remove condition to trigger
1580
- * NEW: PUT /campaign-triggers/{triggerId}/condition/{conditionId}
1581
- */
1582
- async addOrRemoveConditionToTrigger(triggerId, conditionId) {
1583
- return this.apiClient.put(`/campaign-triggers/${triggerId}/condition/${conditionId}`, {});
1584
- }
1585
- // ==========================================
1586
- // BUSINESS ENGAGEMENTS (/campaign-engagements)
1587
- // ==========================================
1588
- /**
1589
- * ADMIN: Add business engagement to campaign
1590
- * NEW: POST /campaign-engagements/{id}
1591
- */
1592
- async addBusinessEngagementToCampaign(campaignId, campaignBusinessEngagement) {
1593
- return this.apiClient.post(`/campaign-engagements/${campaignId}`, campaignBusinessEngagement);
1594
- }
1595
- /**
1596
- * ADMIN: Update campaign business engagement
1597
- * NEW: PUT /campaign-engagements/{id}/{businessEngagementId}
1598
- */
1599
- async updateCampaignBusinessEngagement(campaignId, businessEngagementId, campaignBusinessEngagement) {
1600
- return this.apiClient.put(`/campaign-engagements/${campaignId}/${businessEngagementId}`, campaignBusinessEngagement);
1601
- }
1602
- /**
1603
- * ADMIN: Delete campaign business engagement
1604
- * NEW: DELETE /campaign-engagements/{id}/{businessEngagementId}
1605
- */
1606
- async deleteCampaignBusinessEngagement(campaignId, businessEngagementId) {
1607
- return this.apiClient.delete(`/campaign-engagements/${campaignId}/${businessEngagementId}`);
1608
- }
1609
- // ==========================================
1610
- // CLAIMS PROCESSING (/campaign-claims)
1611
- // ==========================================
1612
- /**
1613
- * USER: Claim campaign reward
1614
- * NEW: POST /campaign-claims/user
1615
- */
1616
- async claimCampaign(request) {
1617
- return this.apiClient.post('/campaign-claims', request);
1618
- }
1619
- /**
1620
- * USER: Get claims for logged user
1621
- * NEW: GET /campaign-claims/users/me
1622
- */
1623
- async getClaimsForLoggedUser() {
1624
- return this.apiClient.get('/campaign-claims/me');
1625
- }
1626
- /**
1627
- * ADMIN: Get all campaign claims
1628
- * Updated to use unified endpoint
1629
- */
1630
- async getCampaignClaims() {
1631
- // Admin context - no parameters needed for all claims
1632
- return this.apiClient.get('/campaign-claims');
1633
- }
1634
- /**
1635
- * ADMIN: Get campaign claims by campaign ID
1636
- * Updated to use query parameters
1637
- */
1638
- async getCampaignClaimsByCampaignId(campaignId) {
1639
- return this.apiClient.get(`/campaign-claims?campaignId=${campaignId}`);
1640
- }
1641
- /**
1642
- * ADMIN: Get campaign claims by user ID
1643
- * Updated to use query parameters
1644
- */
1645
- async getCampaignClaimsByUserId(userId) {
1646
- return this.apiClient.get(`/campaign-claims?userId=${userId}`);
1647
- }
1648
- /**
1649
- * ADMIN: Get campaign claims by business ID
1650
- * Updated to use query parameters
1651
- */
1652
- async getCampaignClaimsByBusinessId(businessId) {
1653
- return this.apiClient.get(`/campaign-claims?businessId=${businessId}`);
1654
- }
1655
- /**
1656
- * ADMIN: Get campaign claims by user ID for specific campaign
1657
- * Combined filtering using query parameters
1658
- */
1659
- async getCampaignClaimsByUserAndCampaign(userId, campaignId) {
1660
- return this.apiClient.get(`/campaign-claims?userId=${userId}&campaignId=${campaignId}`);
1661
- }
1662
- /**
1663
- * ADMIN: Get campaign claims by business ID for specific campaign
1664
- * Combined filtering using query parameters
1665
- */
1666
- async getCampaignClaimsByBusinessAndCampaign(businessId, campaignId) {
1667
- return this.apiClient.get(`/campaign-claims?businessId=${businessId}&campaignId=${campaignId}`);
1668
- }
1669
- /**
1670
- * USER: Get user's own claims (all campaigns)
1671
- * Use convenience endpoint
1672
- */
1673
- async getUserClaims() {
1674
- return this.apiClient.get('/campaign-claims/me');
1675
- }
1676
- /**
1677
- * USER: Get user's claims for specific campaign
1678
- * Use convenience endpoint with query parameter
1679
- */
1680
- async getUserClaimsForCampaign(campaignId) {
1681
- return this.apiClient.get(`/campaign-claims/me?campaignId=${campaignId}`);
1682
- }
1683
- /**
1684
- * BUSINESS: Get business claims (all campaigns)
1685
- * Uses unified endpoint with business context
1686
- */
1687
- async getBusinessClaims() {
1688
- return this.apiClient.get('/campaign-claims');
1689
- }
1690
- /**
1691
- * BUSINESS: Get business claims for specific campaign
1692
- * Uses unified endpoint with business context and campaign filter
1693
- */
1694
- async getBusinessClaimsForCampaign(campaignId) {
1695
- return this.apiClient.get(`/campaign-claims?campaignId=${campaignId}`);
1696
- }
1697
- /**
1698
- * Helper: Build query string from parameters
1699
- */
1700
- buildQueryString(params) {
1701
- const validParams = Object.entries(params)
1702
- .filter(([_, value]) => value !== undefined)
1703
- .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
1704
- .join('&');
1705
- return validParams ? `?${validParams}` : '';
1706
- }
1707
- /**
1708
- * Flexible admin claims query with multiple filters
1709
- */
1710
- async getAdminClaims(filters) {
1711
- const queryString = this.buildQueryString(filters || {});
1712
- return this.apiClient.get(`/campaign-claims${queryString}`);
1713
- }
1714
- }
1715
-
1716
- /**
1717
- * Platform-Agnostic Campaign Service
1718
- *
1719
- * Contains campaign business logic and operations that work across platforms.
1720
- * No framework dependencies - pure TypeScript business logic.
1721
- *
1722
- * Focuses only on actual backend capabilities.
1723
- */
1724
- class CampaignService {
1725
- constructor(campaignApi) {
1726
- this.campaignApi = campaignApi;
1727
- }
1728
- // ==========================================
1729
- // PUBLIC OPERATIONS
1730
- // ==========================================
1731
- /**
1732
- * PUBLIC: Get all active campaigns
1733
- */
1734
- async getActiveCampaigns() {
1735
- return this.campaignApi.getActiveCampaigns();
1736
- }
1737
- /**
1738
- * PUBLIC: Get campaign by ID
1739
- */
1740
- async getCampaignById(id) {
1741
- return this.campaignApi.getCampaignById(id);
1742
- }
1743
- // ==========================================
1744
- // AUTHENTICATED OPERATIONS
1745
- // ==========================================
1746
- /**
1747
- * AUTH: Claim campaign
1748
- */
1749
- async claimCampaign(request) {
1750
- return this.campaignApi.claimCampaign(request);
1751
- }
1752
- /**
1753
- * AUTH: Get claims for logged user
1754
- */
1755
- async getClaimsForLoggedUser() {
1756
- return this.campaignApi.getClaimsForLoggedUser();
1757
- }
1758
- // ==========================================
1759
- // ADMIN OPERATIONS
1760
- // ==========================================
1761
- /**
1762
- * ADMIN: Get campaigns with optional active filter
1763
- */
1764
- async getCampaigns(active) {
1765
- return this.campaignApi.getCampaigns(active !== undefined ? { active } : undefined);
1766
- }
1767
- /**
1768
- * ADMIN: Get campaign triggers
1769
- */
1770
- async getCampaignTriggers() {
1771
- return this.campaignApi.getCampaignTriggers();
1772
- }
1773
- /**
1774
- * ADMIN: Toggle campaign active status
1775
- */
1776
- async toggleCampaignActive(campaignId) {
1777
- return this.campaignApi.toggleCampaignActive(campaignId);
1778
- }
1779
- /**
1780
- * ADMIN: Toggle campaign testnet environment
1781
- */
1782
- async toggleCampaignTestnet(campaignId) {
1783
- return this.campaignApi.toggleCampaignTestnet(campaignId);
1784
- }
1785
- /**
1786
- * ADMIN: Create campaign
1787
- */
1788
- async createCampaign(campaign) {
1789
- return this.campaignApi.createCampaign(campaign);
1790
- }
1791
- /**
1792
- * ADMIN: Set campaign trigger
1793
- */
1794
- async setCampaignTrigger(campaignId, triggerId) {
1795
- return this.campaignApi.setCampaignTrigger(campaignId, triggerId);
1796
- }
1797
- /**
1798
- * ADMIN: Update campaign
1799
- */
1800
- async updateCampaign(campaignId, campaign) {
1801
- return this.campaignApi.updateCampaign(campaignId, campaign);
1802
- }
1803
- /**
1804
- * ADMIN: Create campaign token unit
1805
- */
1806
- async createCampaignTokenUnit(campaignId, campaignTokenUnit) {
1807
- return this.campaignApi.createCampaignTokenUnit(campaignId, campaignTokenUnit);
1808
- }
1809
- /**
1810
- * ADMIN: Delete campaign token unit
1811
- */
1812
- async deleteCampaignTokenUnit(campaignId, campaignTokenUnitId) {
1813
- return this.campaignApi.deleteCampaignTokenUnit(campaignId, campaignTokenUnitId);
1814
- }
1815
- /**
1816
- * ADMIN: Add business engagement to campaign
1817
- */
1818
- async addBusinessEngagementToCampaign(campaignId, campaignBusinessEngagement) {
1819
- return this.campaignApi.addBusinessEngagementToCampaign(campaignId, campaignBusinessEngagement);
1820
- }
1821
- /**
1822
- * ADMIN: Update campaign business engagement
1823
- */
1824
- async updateCampaignBusinessEngagement(campaignId, businessEngagementId, campaignBusinessEngagement) {
1825
- return this.campaignApi.updateCampaignBusinessEngagement(campaignId, businessEngagementId, campaignBusinessEngagement);
1826
- }
1827
- async deleteCampaignBusinessEngagement(campaignId, businessEngagementId) {
1828
- return this.campaignApi.deleteCampaignBusinessEngagement(campaignId, businessEngagementId);
1829
- }
1830
- /**
1831
- * ADMIN: Get all campaign claims
1832
- */
1833
- async getCampaignClaims() {
1834
- return this.campaignApi.getCampaignClaims();
1835
- }
1836
- /**
1837
- * ADMIN: Get campaign claims by user ID
1838
- */
1839
- async getCampaignClaimsByUserId(userId) {
1840
- return this.campaignApi.getCampaignClaimsByUserId(userId);
1841
- }
1842
- /**
1843
- * ADMIN: Get campaign claims by business ID
1844
- */
1845
- async getCampaignClaimsByBusinessId(businessId) {
1846
- return this.campaignApi.getCampaignClaimsByBusinessId(businessId);
1847
- }
1848
- }
1849
-
1850
- /**
1851
- * @explorins/pers-sdk-campaign
1852
- *
1853
- * Platform-agnostic Campaign Domain SDK for PERS ecosystem
1854
- * Handles campaign operations across different authorization levels
1855
- */
1856
- // API Layer
1857
- /**
1858
- * Create a complete Campaign SDK instance
1859
- *
1860
- * @param apiClient - Configured PERS API client
1861
- * @returns Campaign SDK with flattened structure for better DX
1862
- */
1863
- function createCampaignSDK(apiClient) {
1864
- const campaignApi = new CampaignApi(apiClient);
1865
- const campaignService = new CampaignService(campaignApi);
1866
- return {
1867
- // Direct access to service methods (primary interface)
1868
- // Public methods
1869
- getActiveCampaigns: () => campaignService.getActiveCampaigns(),
1870
- getCampaignById: (id) => campaignService.getCampaignById(id),
1871
- // Auth methods
1872
- claimCampaign: (request) => campaignService.claimCampaign(request),
1873
- getClaimsForLoggedUser: () => campaignService.getClaimsForLoggedUser(),
1874
- // Admin methods
1875
- getCampaigns: (active) => campaignService.getCampaigns(active),
1876
- getCampaignTriggers: () => campaignService.getCampaignTriggers(),
1877
- toggleCampaignActive: (campaignId) => campaignService.toggleCampaignActive(campaignId),
1878
- toggleCampaignTestnet: (campaignId) => campaignService.toggleCampaignTestnet(campaignId),
1879
- createCampaign: (campaign) => campaignService.createCampaign(campaign),
1880
- setCampaignTrigger: (campaignId, triggerId) => campaignService.setCampaignTrigger(campaignId, triggerId),
1881
- updateCampaign: (campaignId, campaign) => campaignService.updateCampaign(campaignId, campaign),
1882
- createCampaignTokenUnit: (campaignId, campaignTokenUnit) => campaignService.createCampaignTokenUnit(campaignId, campaignTokenUnit),
1883
- deleteCampaignTokenUnit: (campaignId, campaignTokenUnitId) => campaignService.deleteCampaignTokenUnit(campaignId, campaignTokenUnitId),
1884
- addBusinessEngagementToCampaign: (campaignId, campaignBusinessEngagement) => campaignService.addBusinessEngagementToCampaign(campaignId, campaignBusinessEngagement),
1885
- updateCampaignBusinessEngagement: (campaignId, businessEngagementId, campaignBusinessEngagement) => campaignService.updateCampaignBusinessEngagement(campaignId, businessEngagementId, campaignBusinessEngagement),
1886
- deleteCampaignBusinessEngagement: (campaignId, businessEngagementId) => campaignService.deleteCampaignBusinessEngagement(campaignId, businessEngagementId),
1887
- getCampaignClaims: () => campaignService.getCampaignClaims(),
1888
- getCampaignClaimsByUserId: (userId) => campaignService.getCampaignClaimsByUserId(userId),
1889
- getCampaignClaimsByBusinessId: (businessId) => campaignService.getCampaignClaimsByBusinessId(businessId),
1890
- // Advanced access for edge cases
1891
- api: campaignApi,
1892
- service: campaignService
1893
- };
1894
- }
1895
-
1896
- /**
1897
- * Platform-Agnostic Donation API Client
1898
- *
1899
- * Handles donation operations using the PERS backend.
1900
- * Matches framework DonationApiService methods exactly.
1901
- */
1902
- class DonationApi {
1903
- constructor(apiClient) {
1904
- this.apiClient = apiClient;
1905
- }
1906
- // ==========================================
1907
- // PUBLIC OPERATIONS
1908
- // ==========================================
1909
- /**
1910
- * PUBLIC: Get all donation types
1911
- * ✅ ONLY method actually used by framework
1912
- */
1913
- async getAllDonationTypes() {
1914
- return this.apiClient.get('/purchases/donation-types');
1915
- }
1916
- }
1917
-
1918
- /**
1919
- * Platform-Agnostic Donation Service
1920
- *
1921
- * Contains donation business logic and operations that work across platforms.
1922
- * No framework dependencies - pure TypeScript business logic.
1923
- * Matches framework DonationApiService capabilities exactly.
1924
- */
1925
- class DonationService {
1926
- constructor(donationApi) {
1927
- this.donationApi = donationApi;
1928
- }
1929
- // ==========================================
1930
- // PUBLIC OPERATIONS
1931
- // ==========================================
1932
- /**
1933
- * PUBLIC: Get all donation types
1934
- * ✅ ONLY method actually used by framework
1935
- */
1936
- async getAllDonationTypes() {
1937
- return this.donationApi.getAllDonationTypes();
1938
- }
1939
- }
1940
-
1941
- /**
1942
- * @explorins/pers-sdk-donation
1943
- *
1944
- * Platform-agnostic Donation Domain SDK for PERS ecosystem
1945
- * Handles donation type retrieval for purchase flow integration
1946
- */
1947
- // API Layer
1948
- /**
1949
- * Create a complete Donation SDK instance
1950
- *
1951
- * @param apiClient - Configured PERS API client
1952
- * @returns Donation SDK with flattened structure for better DX
1953
- */
1954
- function createDonationSDK(apiClient) {
1955
- const donationApi = new DonationApi(apiClient);
1956
- const donationService = new DonationService(donationApi);
1957
- return {
1958
- // Direct access to service methods (primary interface)
1959
- // ✅ FRAMEWORK ALIGNED: Only method actually used by framework
1960
- // Public methods
1961
- getAllDonationTypes: () => donationService.getAllDonationTypes(),
1962
- // Advanced access for edge cases
1963
- api: donationApi,
1964
- service: donationService
1965
- };
1966
- }
1967
-
1968
- /**
1969
- * Platform-Agnostic Purchase API Client (RESTful Architecture)
1970
- *
1971
- * Handles purchase and payment operations using the PERS backend's new RESTful endpoints.
1972
- * Uses @explorins/pers-shared DTOs for consistency with backend.
1973
- *
1974
- * Migration Status: Updated to match /purchases controller (replaces /purchase endpoints)
1975
- *
1976
- * Available Access Levels:
1977
- * - PUBLIC: Project key authentication for catalog browsing and payment operations
1978
- * - USER: Requires user authentication JWT (purchase creation, history access)
1979
- * - ADMIN: Requires tenant admin privileges (not implemented in this client)
1980
- *
1981
- * Note: This SDK focuses on backend purchase operations only.
1982
- * Payment provider integrations (Stripe, etc.) should remain in infrastructure layer.
1983
- */
1984
- class PurchaseApi {
1985
- constructor(apiClient) {
1986
- this.apiClient = apiClient;
1987
- this.basePath = '/purchases';
1988
- }
1989
- // ==========================================
1990
- // PUBLIC OPERATIONS (Project Key)
1991
- // ==========================================
1992
- /**
1993
- * PUBLIC: Get purchase tokens (Intelligent Access)
1994
- *
1995
- * RESTful endpoint: GET /purchases/tokens
1996
- * Replaces: GET /purchase/token
1997
- *
1998
- * INTELLIGENT ACCESS:
1999
- * - PUBLIC (Project Key): Returns active tokens only (active parameter ignored)
2000
- * - ADMIN (Tenant Admin JWT): Returns filtered results based on active parameter
2001
- */
2002
- async getPurchaseTokens(active) {
2003
- let url = `${this.basePath}/tokens`;
2004
- if (active !== undefined) {
2005
- url += `?active=${active}`;
2006
- }
2007
- return this.apiClient.get(url);
2008
- }
2009
- /**
2010
- * PUBLIC: Get donation types
2011
- *
2012
- * RESTful endpoint: GET /purchases/donation-types
2013
- * Replaces: GET /purchase/donation/type
2014
- */
2015
- async getDonationTypes() {
2016
- return this.apiClient.get(`${this.basePath}/donation-types`);
2017
- }
2018
- // ==========================================
2019
- // PAYMENT OPERATIONS (FINANCIAL - CRITICAL)
2020
- // ==========================================
2021
- /**
2022
- * PUBLIC: Create payment intent (FINANCIAL OPERATION)
2023
- *
2024
- * RESTful endpoint: POST /purchases/payment-intents
2025
- * Replaces: POST /purchase/payment-intent
2026
- *
2027
- * CRITICAL: Handles real money operations - tenant context required
2028
- */
2029
- async createPaymentIntent(amount, currency, receiptEmail, description) {
2030
- const body = {
2031
- amount,
2032
- currency,
2033
- receiptEmail,
2034
- description
2035
- };
2036
- return this.apiClient.post(`${this.basePath}/payment-intents`, body);
2037
- }
2038
- /**
2039
- * PUBLIC: Update payment intent (FINANCIAL OPERATION)
2040
- *
2041
- * RESTful endpoint: PUT /purchases/payment-intents/{paymentIntentId}
2042
- * Replaces: PUT /purchase/payment-intent/{paymentIntentId}
2043
- *
2044
- * CRITICAL: Handles real money operations - tenant context required
2045
- */
2046
- async updatePaymentIntent(paymentIntentId, amount, currency, receiptEmail, description) {
2047
- const body = {
2048
- amount,
2049
- currency,
2050
- receiptEmail,
2051
- description
2052
- };
2053
- return this.apiClient.put(`${this.basePath}/payment-intents/${paymentIntentId}`, body);
2054
- }
2055
- /**
2056
- * PUBLIC: Cancel payment intent (FINANCIAL OPERATION)
2057
- *
2058
- * RESTful endpoint: DELETE /purchases/payment-intents/{paymentIntentId}
2059
- * Replaces: DELETE /purchase/payment-intent/{paymentIntentId}
2060
- *
2061
- * CRITICAL: Handles real money operations - tenant context required
2062
- */
2063
- async cancelPaymentIntent(paymentIntentId) {
2064
- return this.apiClient.delete(`${this.basePath}/payment-intents/${paymentIntentId}`);
2065
- }
2066
- // ==========================================
2067
- // USER OPERATIONS (JWT + Project Key)
2068
- // ==========================================
2069
- /**
2070
- * USER: Create purchase (BUSINESS CRITICAL - FINANCIAL TRANSACTION)
2071
- *
2072
- * RESTful endpoint: POST /purchases
2073
- * Replaces: POST /purchase/auth
2074
- *
2075
- * USER-ONLY: Requires user authentication JWT for purchase creation
2076
- * CRITICAL: Real financial transaction with Stripe integration
2077
- */
2078
- async createUserPurchase(paymentIntentId, amount, purchaseTokenId, donationTypeId, donationAccountAddress) {
2079
- const body = {
2080
- quantity: amount,
2081
- purchaseTokenId: purchaseTokenId || '',
2082
- donationTypeId,
2083
- donationAccountAddress,
2084
- paymentIntentId
2085
- };
2086
- return this.apiClient.post(`${this.basePath}`, body);
2087
- }
2088
- /**
2089
- * USER: Get user purchase history
2090
- *
2091
- * RESTful endpoint: GET /purchases/me/history
2092
- * Replaces: GET /purchase/auth
2093
- *
2094
- * USER-ONLY: Get authenticated user's purchase history
2095
- * FINANCIAL RECORDS: User attribution critical for compliance
2096
- */
2097
- async getUserPurchaseHistory() {
2098
- return this.apiClient.get(`${this.basePath}/me/history`);
2099
- }
2100
- // ==========================================
2101
- // CONVENIENCE METHODS (Backward Compatibility)
2102
- // ==========================================
2103
- /**
2104
- * @deprecated Use getPurchaseTokens() instead
2105
- * Backward compatibility alias for getActivePurchaseTokens
2106
- */
2107
- async getActivePurchaseTokens(active = true) {
2108
- return this.getPurchaseTokens(active);
2109
- }
2110
- /**
2111
- * @deprecated Use createUserPurchase() instead
2112
- * Backward compatibility alias for createPurchase
2113
- */
2114
- async createPurchase(paymentIntentId, amount, purchaseTokenId, donationTypeId, donationAccountAddress) {
2115
- return this.createUserPurchase(paymentIntentId, amount, purchaseTokenId, donationTypeId, donationAccountAddress);
2116
- }
2117
- /**
2118
- * @deprecated Use getUserPurchaseHistory() instead
2119
- * Backward compatibility alias for getAllUserPurchases
2120
- */
2121
- async getAllUserPurchases() {
2122
- return this.getUserPurchaseHistory();
2123
- }
2124
- }
2125
-
2126
- /**
2127
- * Platform-Agnostic Payment Service
2128
- *
2129
- * Contains payment business logic and operations that work across platforms.
2130
- * No framework dependencies - pure TypeScript business logic.
2131
- *
2132
- * Focuses only on actual backend capabilities.
2133
- * Payment provider logic (Stripe, etc.) should remain in infrastructure layer.
2134
- */
2135
- class PaymentService {
2136
- constructor(paymentApi) {
2137
- this.paymentApi = paymentApi;
2138
- }
2139
- // ==========================================
2140
- // PUBLIC OPERATIONS
2141
- // ==========================================
2142
- /**
2143
- * PUBLIC: Get active purchase tokens
2144
- */
2145
- async getActivePurchaseTokens(active = true) {
2146
- return this.paymentApi.getActivePurchaseTokens(active);
2147
- }
2148
- /**
2149
- * PUBLIC: Create payment intent
2150
- */
2151
- async createPaymentIntent(amount, currency, receiptEmail, description) {
2152
- return this.paymentApi.createPaymentIntent(amount, currency, receiptEmail, description);
2153
- }
2154
- /**
2155
- * PUBLIC: Update payment intent
2156
- */
2157
- async updatePaymentIntent(paymentIntentId, amount, currency, receiptEmail, description) {
2158
- return this.paymentApi.updatePaymentIntent(paymentIntentId, amount, currency, receiptEmail, description);
2159
- }
2160
- /**
2161
- * PUBLIC: Cancel payment intent
2162
- */
2163
- async cancelPaymentIntent(paymentIntentId) {
2164
- return this.paymentApi.cancelPaymentIntent(paymentIntentId);
2165
- }
2166
- // ==========================================
2167
- // AUTHENTICATED OPERATIONS
2168
- // ==========================================
2169
- /**
2170
- * AUTH: Create purchase
2171
- */
2172
- async createPurchase(paymentIntentId, amount, purchaseTokenId, donationTypeId, donationAccountAddress) {
2173
- return this.paymentApi.createPurchase(paymentIntentId, amount, purchaseTokenId, donationTypeId, donationAccountAddress);
2174
- }
2175
- /**
2176
- * AUTH: Get all user purchases
2177
- */
2178
- async getAllUserPurchases() {
2179
- return this.paymentApi.getAllUserPurchases();
2180
- }
2181
- }
2182
-
2183
- /**
2184
- * @explorins/pers-sdk-payment
2185
- *
2186
- * Platform-agnostic Payment Domain SDK for PERS ecosystem
2187
- * Handles payment intents, purchases, and purchase tokens
2188
- *
2189
- * Note: Payment provider integrations (Stripe, etc.) are kept separate
2190
- * in the infrastructure layer to maintain platform-agnostic principles.
2191
- */
2192
- // API Layer
2193
- /**
2194
- * Create a complete Payment SDK instance
2195
- *
2196
- * @param apiClient - Configured PERS API client
2197
- * @returns Payment SDK with flattened structure for better DX
2198
- */
2199
- function createPaymentSDK(apiClient) {
2200
- const paymentApi = new PurchaseApi(apiClient);
2201
- const paymentService = new PaymentService(paymentApi);
2202
- return {
2203
- // Direct access to service methods (primary interface)
2204
- // Public methods
2205
- getActivePurchaseTokens: (active) => paymentService.getActivePurchaseTokens(active),
2206
- // ✅ FIXED: Proper type instead of any
2207
- createPaymentIntent: (amount, currency, receiptEmail, description) => paymentService.createPaymentIntent(amount, currency, receiptEmail, description),
2208
- // ✅ FIXED: Proper type instead of any
2209
- updatePaymentIntent: (paymentIntentId, amount, currency, receiptEmail, description) => paymentService.updatePaymentIntent(paymentIntentId, amount, currency, receiptEmail, description),
2210
- cancelPaymentIntent: (paymentIntentId) => paymentService.cancelPaymentIntent(paymentIntentId),
2211
- // Auth methods
2212
- createPurchase: (paymentIntentId, amount, purchaseTokenId, donationTypeId, donationAccountAddress) => paymentService.createPurchase(paymentIntentId, amount, purchaseTokenId, donationTypeId, donationAccountAddress),
2213
- getAllUserPurchases: () => paymentService.getAllUserPurchases(),
2214
- // Advanced access for edge cases
2215
- api: paymentApi,
2216
- service: paymentService
2217
- };
2218
- }
2219
-
2220
- /**
2221
- * Platform-Agnostic Redemption API Client (UPDATED - RESTful Design)
2222
- *
2223
- * Updated to work with the new RESTful /redemptions and /redemption-redeems endpoints.
2224
- * Handles redemption operations using the PERS backend with intelligent access detection.
2225
- * Uses @explorins/pers-shared DTOs for consistency with backend.
2226
- *
2227
- * Migration Update: Updated all endpoints for unified controller pattern
2228
- * - Removed role revelation from URLs (no more /admin, /auth paths)
2229
- * - Added intelligent access detection for unified endpoints
2230
- * - Added new /redemption-redeems endpoints for redeem processing
2231
- * - Enhanced redemption process with role-based access control
2232
- */
2233
- class RedemptionApi {
2234
- constructor(apiClient) {
2235
- this.apiClient = apiClient;
2236
- this.basePath = '/redemptions';
2237
- this.redeemsPath = '/redemption-redeems';
2238
- }
2239
- // ==========================================
2240
- // PUBLIC OPERATIONS (Project Key)
2241
- // ==========================================
2242
- /**
2243
- * PUBLIC: Get redemptions (intelligent access)
2244
- *
2245
- * NEW: Intelligent endpoint that adapts based on authentication
2246
- * - Public users: Get active redemptions only
2247
- * - Admin users: Get all redemptions with optional filtering
2248
- *
2249
- * Replaces: getActiveRedemptions() + getRedemptionsAsAdmin()
2250
- */
2251
- async getRedemptions(active) {
2252
- let url = `${this.basePath}`;
2253
- if (active !== undefined) {
2254
- url += `?active=${active}`;
2255
- }
2256
- return this.apiClient.get(url);
2257
- }
2258
- /**
2259
- * PUBLIC: Get active redemptions
2260
- *
2261
- * Updated: Now uses unified endpoint (backward compatibility)
2262
- */
2263
- async getActiveRedemptions() {
2264
- return this.getRedemptions(); // Will return active only for public access
2265
- }
2266
- /**
2267
- * PUBLIC: Get redemption types
2268
- *
2269
- * Updated: /redemption/type → /redemptions/types
2270
- */
2271
- async getRedemptionTypes() {
2272
- return this.apiClient.get(`/redemption-types`);
2273
- }
2274
- /**
2275
- * PUBLIC: Get redemption by ID
2276
- *
2277
- * Updated: /redemption/:id → /redemptions/:id
2278
- */
2279
- async getRedemptionById(id) {
2280
- return this.apiClient.get(`${this.basePath}/${id}`);
2281
- }
2282
- /**
2283
- * PUBLIC: Get available supply for redemption
2284
- *
2285
- * Updated: /redemption/:id/available-supply → /redemptions/:id/supply
2286
- */
2287
- async getRedemptionAvailableSupply(id) {
2288
- return this.apiClient.get(`${this.basePath}/${id}/supply`);
2289
- }
2290
- // ==========================================
2291
- // REDEMPTION EXECUTION (NEW UNIFIED ENDPOINT)
2292
- // ==========================================
2293
- /**
2294
- * Execute redemption (unified endpoint)
2295
- *
2296
- * NEW: POST /redemption-redeems - Role-based processing
2297
- * - USER: Direct user redemption processing
2298
- * - ADMIN: Can process redemptions for any account type
2299
- * - BUSINESS: Process redemptions for customers
2300
- */
2301
- async redeemRedemption(redemptionId) {
2302
- const body = {
2303
- redemptionId: redemptionId,
2304
- };
2305
- return this.apiClient.post(this.redeemsPath, body);
2306
- }
2307
- // ==========================================
2308
- // REDEMPTION REDEEMS QUERIES (NEW ENDPOINTS)
2309
- // ==========================================
2310
- /**
2311
- * Get redemption redeems with filtering (unified endpoint)
2312
- *
2313
- * NEW: GET /redemption-redeems with query parameters
2314
- * Role-based access: Users see only their own, admins can filter by userId/businessId
2315
- */
2316
- async getRedemptionRedeems(filters) {
2317
- let url = this.redeemsPath;
2318
- const params = new URLSearchParams();
2319
- if (filters?.redemptionId)
2320
- params.append('redemptionId', filters.redemptionId);
2321
- if (filters?.userId)
2322
- params.append('userId', filters.userId);
2323
- if (filters?.businessId)
2324
- params.append('businessId', filters.businessId);
2325
- const queryString = params.toString();
2326
- if (queryString) {
2327
- url += `?${queryString}`;
2328
- }
2329
- return this.apiClient.get(url);
2330
- }
2331
- /**
2332
- * Get specific redemption redeem by ID
2333
- *
2334
- * NEW: GET /redemption-redeems/:id
2335
- */
2336
- async getRedemptionRedeemById(id) {
2337
- return this.apiClient.get(`${this.redeemsPath}/${id}`);
2338
- }
2339
- /**
2340
- * USER: Get my redemption redeems (convenience endpoint)
2341
- *
2342
- * NEW: GET /redemption-redeems/me with optional filtering
2343
- */
2344
- async getMyRedemptionRedeems(redemptionId) {
2345
- let url = `${this.redeemsPath}/me`;
2346
- if (redemptionId) {
2347
- url += `?redemptionId=${redemptionId}`;
2348
- }
2349
- return this.apiClient.get(url);
2350
- }
2351
- /**
2352
- * ADMIN: Get redemption redeems by user ID
2353
- *
2354
- * NEW: GET /redemption-redeems?userId=X
2355
- */
2356
- async getRedemptionRedeemsByUserId(userId, redemptionId) {
2357
- return this.getRedemptionRedeems({ userId, redemptionId });
2358
- }
2359
- /**
2360
- * ADMIN: Get redemption redeems by business ID
2361
- *
2362
- * NEW: GET /redemption-redeems?businessId=X
2363
- */
2364
- async getRedemptionRedeemsByBusinessId(businessId, redemptionId) {
2365
- return this.getRedemptionRedeems({ businessId, redemptionId });
2366
- }
2367
- /**
2368
- * ADMIN: Get redemption redeems by redemption ID
2369
- *
2370
- * NEW: GET /redemption-redeems?redemptionId=X
2371
- */
2372
- async getRedemptionRedeemsByRedemptionId(redemptionId) {
2373
- return this.getRedemptionRedeems({ redemptionId });
2374
- }
2375
- // ==========================================
2376
- // USER OPERATIONS (JWT + Project Key)
2377
- // ==========================================
2378
- /**
2379
- * USER: Get user redemption history
2380
- *
2381
- * Updated: Uses new convenience endpoint /redemption-redeems/me
2382
- */
2383
- async getUserRedemptionHistory() {
2384
- return this.getMyRedemptionRedeems();
2385
- }
2386
- /**
2387
- * USER: Get user redemptions (backward compatibility)
2388
- *
2389
- * Deprecated: Use getUserRedemptionHistory() instead
2390
- */
2391
- async getUserRedeems() {
2392
- return this.getUserRedemptionHistory();
2393
- }
2394
- // ==========================================
2395
- // ADMIN OPERATIONS (Tenant Admin JWT)
2396
- // ==========================================
2397
- /**
2398
- * ADMIN: Get redemptions with filtering (using intelligent endpoint)
2399
- *
2400
- * Updated: /redemption/admin → /redemptions (intelligent access detection)
2401
- * The unified endpoint will detect admin privileges and allow filtering
2402
- */
2403
- async getRedemptionsAsAdmin(active) {
2404
- return this.getRedemptions(active); // Uses intelligent endpoint
2405
- }
2406
- /**
2407
- * ADMIN: Create redemption
2408
- *
2409
- * Updated: /redemption/admin → /redemptions
2410
- */
2411
- async createRedemption(redemption) {
2412
- return this.apiClient.post(`${this.basePath}`, redemption);
2413
- }
2414
- /**
2415
- * ADMIN: Update redemption
2416
- *
2417
- * Updated: /redemption/admin/:id → /redemptions/:id
2418
- */
2419
- async updateRedemption(id, redemptionCreateRequest) {
2420
- return this.apiClient.put(`${this.basePath}/${id}`, redemptionCreateRequest);
2421
- }
2422
- /**
2423
- * ADMIN: Toggle redemption status
2424
- *
2425
- * Updated: /redemption/admin/:id/toggle-active → /redemptions/:id/status
2426
- * Following standard /status pattern used across domains
2427
- */
2428
- async toggleRedemptionStatus(redemptionId) {
2429
- return this.apiClient.put(`${this.basePath}/${redemptionId}/status`, {});
2430
- }
2431
- /**
2432
- * ADMIN: Toggle redemption active (backward compatibility)
2433
- *
2434
- * Deprecated: Use toggleRedemptionStatus() instead
2435
- */
2436
- async toggleRedemptionActive(redemptionId) {
2437
- return this.toggleRedemptionStatus(redemptionId);
2438
- }
2439
- /**
2440
- * ADMIN: Delete redemption
2441
- *
2442
- * Updated: /redemption/admin/:id → /redemptions/:id
2443
- */
2444
- async deleteRedemption(id) {
2445
- return this.apiClient.delete(`${this.basePath}/${id}`);
2446
- }
2447
- /**
2448
- * ADMIN: Create redemption type
2449
- *
2450
- * Updated: /redemption/admin/type → /redemptions/types
2451
- */
2452
- async createRedemptionType(redemptionType) {
2453
- return this.apiClient.post(`${this.basePath}/redemption-types`, redemptionType);
2454
- }
2455
- // ==========================================
2456
- // TOKEN UNIT MANAGEMENT (Admin)
2457
- // ==========================================
2458
- /**
2459
- * ADMIN: Create redemption token unit
2460
- *
2461
- * Updated: /redemption/admin/:id/token-units → /redemptions/:id/token-units
2462
- */
2463
- async createRedemptionTokenUnit(redemptionId, redemptionTokenUnit) {
2464
- return this.apiClient.post(`${this.basePath}/${redemptionId}/token-units`, redemptionTokenUnit);
2465
- }
2466
- /**
2467
- * ADMIN: Update redemption token unit
2468
- *
2469
- * Updated: /redemption/admin/:id/token-units/:tokenUnitId → /redemptions/:id/token-units/:tokenUnitId
2470
- */
2471
- async updateRedemptionTokenUnit(redemptionId, tokenUnitId, redemptionTokenUnit) {
2472
- return this.apiClient.put(`${this.basePath}/${redemptionId}/token-units/${tokenUnitId}`, redemptionTokenUnit);
2473
- }
2474
- /**
2475
- * ADMIN: Delete redemption token unit
2476
- *
2477
- * Updated: /redemption/admin/:id/token-units/:tokenUnitId → /redemptions/:id/token-units/:tokenUnitId
2478
- */
2479
- async deleteRedemptionTokenUnit(redemptionId, redemptionTokenUnitId) {
2480
- return this.apiClient.delete(`${this.basePath}/${redemptionId}/token-units/${redemptionTokenUnitId}`);
2481
- }
2482
- // ==========================================
2483
- // BACKWARD COMPATIBILITY METHODS
2484
- // ==========================================
2485
- /**
2486
- * @deprecated Use getRedemptions() instead
2487
- * Backward compatibility for old admin endpoint
2488
- */
2489
- async getRedemptionsAdmin(active) {
2490
- return this.getRedemptionsAsAdmin(active);
2491
- }
2492
- /**
2493
- * @deprecated Use redeemRedemption() instead
2494
- * Backward compatibility for old redeem method
2495
- */
2496
- async redeem(redemptionId) {
2497
- return this.redeemRedemption(redemptionId);
2498
- }
2499
- }
2500
-
2501
- /**
2502
- * Platform-Agnostic Redemption Service
2503
- *
2504
- * Contains redemption business logic and operations that work across platforms.
2505
- * No framework dependencies - pure TypeScript business logic.
2506
- *
2507
- * Focuses only on actual backend capabilities.
2508
- */
2509
- class RedemptionService {
2510
- constructor(redemptionApi) {
2511
- this.redemptionApi = redemptionApi;
2512
- }
2513
- // ==========================================
2514
- // PUBLIC OPERATIONS
2515
- // ==========================================
2516
- /**
2517
- * PUBLIC: Get active redemptions
2518
- */
2519
- async getActiveRedemptions() {
2520
- return this.redemptionApi.getActiveRedemptions();
2521
- }
2522
- /**
2523
- * PUBLIC: Get redemption types
2524
- */
2525
- async getRedemptionTypes() {
2526
- return this.redemptionApi.getRedemptionTypes();
2527
- }
2528
- // ==========================================
2529
- // AUTHENTICATED OPERATIONS
2530
- // ==========================================
2531
- /**
2532
- * AUTH: Redeem a redemption
2533
- */
2534
- async redeemRedemption(redemptionId) {
2535
- return this.redemptionApi.redeemRedemption(redemptionId);
2536
- }
2537
- /**
2538
- * AUTH: Get user redemptions
2539
- */
2540
- async getUserRedeems() {
2541
- return this.redemptionApi.getUserRedeems();
2542
- }
2543
- // ==========================================
2544
- // ADMIN OPERATIONS
2545
- // ==========================================
2546
- /**
2547
- * ADMIN: Get redemptions with optional active filter
2548
- */
2549
- async getRedemptionsAsAdmin(active) {
2550
- return this.redemptionApi.getRedemptionsAsAdmin(active);
2551
- }
2552
- /**
2553
- * ADMIN: Create redemption
2554
- */
2555
- async createRedemption(redemption) {
2556
- return this.redemptionApi.createRedemption(redemption);
2557
- }
2558
- /**
2559
- * ADMIN: Update redemption
2560
- */
2561
- async updateRedemption(id, redemptionCreateRequest) {
2562
- return this.redemptionApi.updateRedemption(id, redemptionCreateRequest); // ✅ CORRECTED: Fixed parameter
2563
- }
2564
- /**
2565
- * ADMIN: Toggle redemption active status
2566
- */
2567
- async toggleRedemptionActive(redemptionId) {
2568
- return this.redemptionApi.toggleRedemptionActive(redemptionId);
2569
- }
2570
- /**
2571
- * ADMIN: Create redemption token unit
2572
- */
2573
- async createRedemptionTokenUnit(redemptionId, redemptionTokenUnit) {
2574
- return this.redemptionApi.createRedemptionTokenUnit(redemptionId, redemptionTokenUnit);
2575
- }
2576
- /**
2577
- * ADMIN: Delete redemption token unit
2578
- */
2579
- async deleteRedemptionTokenUnit(redemptionId, redemptionTokenUnitId) {
2580
- return this.redemptionApi.deleteRedemptionTokenUnit(redemptionId, redemptionTokenUnitId);
2581
- }
2582
- }
2583
-
2584
- /**
2585
- * @explorins/pers-sdk-redemption
2586
- *
2587
- * Platform-agnostic Redemption Domain SDK for PERS ecosystem
2588
- * Handles redemption operations across different authorization levels
2589
- */
2590
- // API Layer
2591
- /**
2592
- * Create a complete Redemption SDK instance
2593
- *
2594
- * @param apiClient - Configured PERS API client
2595
- * @returns Redemption SDK with flattened structure for better DX
2596
- */
2597
- function createRedemptionSDK(apiClient) {
2598
- const redemptionApi = new RedemptionApi(apiClient);
2599
- const redemptionService = new RedemptionService(redemptionApi);
2600
- return {
2601
- // Direct access to service methods (primary interface)
2602
- // Public methods
2603
- getActiveRedemptions: () => redemptionService.getActiveRedemptions(),
2604
- getRedemptionTypes: () => redemptionService.getRedemptionTypes(),
2605
- // Auth methods
2606
- redeemRedemption: (redemptionId) => redemptionService.redeemRedemption(redemptionId),
2607
- getUserRedeems: () => redemptionService.getUserRedeems(),
2608
- // Admin methods
2609
- getRedemptionsAsAdmin: (active) => redemptionService.getRedemptionsAsAdmin(active),
2610
- createRedemption: (redemption) => redemptionService.createRedemption(redemption),
2611
- updateRedemption: (id, redemptionCreateRequest) => redemptionService.updateRedemption(id, redemptionCreateRequest),
2612
- toggleRedemptionActive: (redemptionId) => redemptionService.toggleRedemptionActive(redemptionId),
2613
- createRedemptionTokenUnit: (redemptionId, redemptionTokenUnit) => redemptionService.createRedemptionTokenUnit(redemptionId, redemptionTokenUnit),
2614
- deleteRedemptionTokenUnit: (redemptionId, redemptionTokenUnitId) => redemptionService.deleteRedemptionTokenUnit(redemptionId, redemptionTokenUnitId),
2615
- // Advanced access for edge cases
2616
- api: redemptionApi,
2617
- service: redemptionService
2618
- };
2619
- }
2620
-
2621
- /**
2622
- * Platform-Agnostic Tenant API Client
2623
- *
2624
- * Handles tenant and admin operations using the PERS backend.
2625
- * Matches framework TenantApiService methods exactly.
2626
- *
2627
- * Note: Special header handling (bypass-auth-interceptor) should be handled by PersApiClient internally
2628
- * or through endpoint-specific configuration.
2629
- */
2630
- class TenantApi {
2631
- constructor(apiClient) {
2632
- this.apiClient = apiClient;
2633
- this.basePath = '/tenants';
2634
- this.adminPath = '/admins';
2635
- }
2636
- // ==========================================
2637
- // PUBLIC OPERATIONS
2638
- // ==========================================
2639
- /**
2640
- * PUBLIC: Get tenant public information
2641
- * ✅ FIXED: Matches framework cache busting pattern exactly
2642
- */
2643
- async getRemoteTenant() {
2644
- const timestamp = Date.now().toString();
2645
- const url = `${this.basePath}/public?date=${timestamp}`;
2646
- return this.apiClient.get(url);
2647
- }
2648
- /**
2649
- * PUBLIC: Get remote login token
2650
- */
2651
- async getRemoteLoginToken() {
2652
- return this.apiClient.get(`${this.basePath}/login-token`);
2653
- }
2654
- /**
2655
- * PUBLIC: Get remote client configuration
2656
- * ✅ FIXED: Removed second parameter - PersApiClient handles bypass auth internally
2657
- * Note: The /tenants/client-config endpoint should be configured to bypass auth at the API client level
2658
- */
2659
- async getRemoteClientConfig() {
2660
- return this.apiClient.get(`${this.basePath}/client-config`);
2661
- }
2662
- // ==========================================
2663
- // ADMIN OPERATIONS
2664
- // ==========================================
2665
- /**
2666
- * ADMIN: Update tenant information
2667
- * ✅ FIXED: Uses TenantPublicDTO directly like framework
2668
- */
2669
- async updateRemoteTenant(tenantData) {
2670
- return this.apiClient.put(`${this.basePath}`, tenantData);
2671
- }
2672
- /**
2673
- * ADMIN: Get all tenant admins
2674
- */
2675
- async getAdmins() {
2676
- return this.apiClient.get(`${this.adminPath}`);
2677
- }
2678
- /**
2679
- * ADMIN: Create new admin
2680
- * ✅ FIXED: Renamed to match framework postAdmin method
2681
- */
2682
- async postAdmin(adminData) {
2683
- return this.apiClient.post(`${this.adminPath}`, adminData);
2684
- }
2685
- /**
2686
- * ADMIN: Update admin (toggle tenant association)
2687
- * ✅ FIXED: Renamed to match framework putAdmin method
2688
- */
2689
- async putAdmin(adminId, adminData) {
2690
- return this.apiClient.put(`${this.adminPath}/${adminId}/tenant`, adminData);
2691
- }
2692
- }
2693
-
2694
- /**
2695
- * Platform-Agnostic Tenant Service
2696
- *
2697
- * Contains tenant business logic and operations that work across platforms.
2698
- * No framework dependencies - pure TypeScript business logic.
2699
- * Matches framework TenantApiService capabilities exactly.
2700
- */
2701
- class TenantService {
2702
- constructor(tenantApi) {
2703
- this.tenantApi = tenantApi;
2704
- }
2705
- // ==========================================
2706
- // PUBLIC OPERATIONS
2707
- // ==========================================
2708
- /**
2709
- * PUBLIC: Get tenant public information
2710
- */
2711
- async getRemoteTenant() {
2712
- return this.tenantApi.getRemoteTenant();
2713
- }
2714
- /**
2715
- * PUBLIC: Get remote login token
2716
- */
2717
- async getRemoteLoginToken() {
2718
- return this.tenantApi.getRemoteLoginToken();
2719
- }
2720
- /**
2721
- * PUBLIC: Get remote client configuration
2722
- */
2723
- async getRemoteClientConfig() {
2724
- return this.tenantApi.getRemoteClientConfig();
2725
- }
2726
- // ==========================================
2727
- // ADMIN OPERATIONS
2728
- // ==========================================
2729
- /**
2730
- * ADMIN: Update tenant information
2731
- * ✅ FIXED: Uses TenantPublicDTO directly like framework
2732
- */
2733
- async updateRemoteTenant(tenantData) {
2734
- return this.tenantApi.updateRemoteTenant(tenantData);
2735
- }
2736
- /**
2737
- * ADMIN: Get all tenant admins
2738
- */
2739
- async getAdmins() {
2740
- return this.tenantApi.getAdmins();
2741
- }
2742
- /**
2743
- * ADMIN: Create new admin
2744
- * ✅ FIXED: Renamed to match framework postAdmin method
2745
- */
2746
- async postAdmin(adminData) {
2747
- return this.tenantApi.postAdmin(adminData);
2748
- }
2749
- /**
2750
- * ADMIN: Update admin (toggle tenant association)
2751
- * ✅ FIXED: Renamed to match framework putAdmin method
2752
- */
2753
- async putAdmin(adminId, adminData) {
2754
- return this.tenantApi.putAdmin(adminId, adminData);
2755
- }
2756
- }
2757
-
2758
- /**
2759
- * @explorins/pers-sdk-tenant
2760
- *
2761
- * Platform-agnostic Tenant Domain SDK for PERS ecosystem
2762
- * Handles tenant management and admin operations for multi-tenant architecture
2763
- */
2764
- // API Layer
2765
- /**
2766
- * Create a complete Tenant SDK instance
2767
- *
2768
- * @param apiClient - Configured PERS API client
2769
- * @returns Tenant SDK with flattened structure for better DX
2770
- */
2771
- function createTenantSDK(apiClient) {
2772
- const tenantApi = new TenantApi(apiClient);
2773
- const tenantService = new TenantService(tenantApi);
2774
- return {
2775
- // Direct access to service methods (primary interface)
2776
- // ✅ FRAMEWORK ALIGNED: Only methods actually used by framework
2777
- // Public methods
2778
- getRemoteTenant: () => tenantService.getRemoteTenant(),
2779
- getRemoteLoginToken: () => tenantService.getRemoteLoginToken(),
2780
- getRemoteClientConfig: () => tenantService.getRemoteClientConfig(),
2781
- // Admin methods - ✅ FIXED: Matches framework method names exactly
2782
- updateRemoteTenant: (tenantData) => tenantService.updateRemoteTenant(tenantData),
2783
- getAdmins: () => tenantService.getAdmins(),
2784
- postAdmin: (adminData) => tenantService.postAdmin(adminData),
2785
- putAdmin: (adminId, adminData) => tenantService.putAdmin(adminId, adminData),
2786
- // Advanced access for edge cases
2787
- api: tenantApi,
2788
- service: tenantService
2789
- };
2790
- }
2791
-
2792
- class TokenApi {
2793
- constructor(apiClient) {
2794
- this.apiClient = apiClient;
2795
- this.basePath = '/tokens';
2796
- }
2797
- // ==========================================
2798
- // PUBLIC OPERATIONS
2799
- // ==========================================
2800
- /**
2801
- * PUBLIC: Get all remote tokens
2802
- * ENHANCED: Added admin filtering capability
2803
- */
2804
- async getRemoteTokens(includeInactive = false) {
2805
- const url = includeInactive ? `${this.basePath}?active=false` : `${this.basePath}`;
2806
- return this.apiClient.get(url);
2807
- }
2808
- /**
2809
- * PUBLIC: Get all remote token types
2810
- */
2811
- async getRemoteTokenTypes() {
2812
- return this.apiClient.get(`${this.basePath}/types`);
2813
- }
2814
- /**
2815
- * PUBLIC: Get active point token (was credit token)
2816
- */
2817
- async getRemoteActiveCreditToken() {
2818
- return this.apiClient.get(`${this.basePath}/points`);
2819
- }
2820
- /**
2821
- * PUBLIC: Get reward tokens
2822
- * ENHANCED: Added admin filtering capability
2823
- */
2824
- async getRemoteRewardTokens(includeInactive = false) {
2825
- const url = includeInactive ? `${this.basePath}/rewards?active=false` : `${this.basePath}/rewards`;
2826
- return this.apiClient.get(url);
2827
- }
2828
- /**
2829
- * PUBLIC: Get stamp tokens (was status tokens)
2830
- * ENHANCED: Added admin filtering capability
2831
- */
2832
- async getRemoteStatusTokens(includeInactive = false) {
2833
- const url = includeInactive ? `${this.basePath}/stamps?active=false` : `${this.basePath}/stamps`;
2834
- return this.apiClient.get(url);
2835
- }
2836
- /**
2837
- * PUBLIC: Get token by contract address
2838
- */
2839
- async getTokenByContractAddress(contractAddress, contractTokenId) {
2840
- let url = `${this.basePath}/address/${contractAddress}`;
2841
- if (contractTokenId) {
2842
- url += `?contractTokenId=${contractTokenId}`;
2843
- }
2844
- return this.apiClient.get(url);
2845
- }
2846
- // ==========================================
2847
- // ADMIN OPERATIONS
2848
- // ==========================================
2849
- /**
2850
- * ADMIN: Create new token
2851
- */
2852
- async createToken(tokenData) {
2853
- return this.apiClient.post(`${this.basePath}`, tokenData);
2854
- }
2855
- /**
2856
- * ADMIN: Update token
2857
- */
2858
- async updateToken(tokenId, tokenData) {
2859
- return this.apiClient.put(`${this.basePath}/${tokenId}`, tokenData);
2860
- }
2861
- /**
2862
- * ADMIN: Toggle token active status
2863
- * FIXED: Now calls correct endpoint
2864
- */
2865
- async toggleTokenActive(tokenId) {
2866
- return this.apiClient.put(`${this.basePath}/${tokenId}/status`, {});
2867
- }
2868
- /**
2869
- * ADMIN: Set mainnet contract address
2870
- */
2871
- async setMainnetContract(tokenId, contractAddress, chainId) {
2872
- return this.apiClient.put(`${this.basePath}/${tokenId}/mainnet`, {
2873
- contractAddress,
2874
- chainId
2875
- });
2876
- }
2877
- /**
2878
- * ADMIN: Create token metadata
2879
- */
2880
- async createTokenMetadata(tokenId, tokenData) {
2881
- return this.apiClient.post(`${this.basePath}/${tokenId}/metadata`, tokenData);
2882
- }
2883
- /**
2884
- * ADMIN: Toggle token metadata status (separate from token status)
2885
- */
2886
- async toggleTokenMetadataStatus(metadataId) {
2887
- return this.apiClient.put(`${this.basePath}/metadata/${metadataId}/status`, {});
2888
- }
2889
- /**
2890
- * ADMIN: Create token type
2891
- */
2892
- async createTokenType(tokenType) {
2893
- return this.apiClient.post(`${this.basePath}/types`, tokenType);
2894
- }
2895
- }
2896
-
2897
- /**
2898
- * Platform-Agnostic Token Service
2899
- *
2900
- * Contains token business logic and operations that work across platforms.
2901
- * No framework dependencies - pure TypeScript business logic.
2902
- * Matches framework TokenApiService capabilities exactly.
2903
- */
2904
- class TokenService {
2905
- constructor(tokenApi) {
2906
- this.tokenApi = tokenApi;
2907
- }
2908
- // ==========================================
2909
- // PUBLIC OPERATIONS
2910
- // ==========================================
2911
- /**
2912
- * PUBLIC: Get all remote tokens
2913
- */
2914
- async getRemoteTokens() {
2915
- return this.tokenApi.getRemoteTokens();
2916
- }
2917
- /**
2918
- * PUBLIC: Get all remote token types
2919
- */
2920
- async getRemoteTokenTypes() {
2921
- return this.tokenApi.getRemoteTokenTypes();
2922
- }
2923
- /**
2924
- * PUBLIC: Get active credit token
2925
- */
2926
- async getRemoteActiveCreditToken() {
2927
- return this.tokenApi.getRemoteActiveCreditToken();
2928
- }
2929
- /**
2930
- * PUBLIC: Get reward tokens
2931
- */
2932
- async getRemoteRewardTokens() {
2933
- return this.tokenApi.getRemoteRewardTokens();
2934
- }
2935
- /**
2936
- * PUBLIC: Get status tokens
2937
- */
2938
- async getRemoteStatusTokens() {
2939
- return this.tokenApi.getRemoteStatusTokens();
2940
- }
2941
- /**
2942
- * PUBLIC: Get token by contract address
2943
- * ✅ FIXED: Matches framework parameter types exactly
2944
- */
2945
- async getTokenByContractAddress(contractAddress, contractTokenId) {
2946
- return this.tokenApi.getTokenByContractAddress(contractAddress, contractTokenId);
2947
- }
2948
- // ==========================================
2949
- // ADMIN OPERATIONS
2950
- // ==========================================
2951
- /**
2952
- * ADMIN: Create token metadata
2953
- */
2954
- async createTokenMetadata(tokenId, tokenData) {
2955
- return this.tokenApi.createTokenMetadata(tokenId, tokenData);
2956
- }
2957
- /**
2958
- * ADMIN: Toggle token active status
2959
- */
2960
- async toggleTokenActive(tokenId) {
2961
- return this.tokenApi.toggleTokenActive(tokenId);
2962
- }
2963
- /**
2964
- * ADMIN: Create new token
2965
- */
2966
- async createToken(tokenData) {
2967
- return this.tokenApi.createToken(tokenData);
2968
- }
2969
- /**
2970
- * ADMIN: Update token
2971
- */
2972
- async updateToken(tokenId, tokenData) {
2973
- return this.tokenApi.updateToken(tokenId, tokenData);
2974
- }
2975
- /**
2976
- * ADMIN: Set mainnet contract address
2977
- */
2978
- async setMainnetContract(tokenId, contractAddress, chainId) {
2979
- return this.tokenApi.setMainnetContract(tokenId, contractAddress, chainId);
2980
- }
2981
- /**
2982
- * ADMIN: Toggle token metadata status
2983
- */
2984
- async toggleTokenMetadataStatus(metadataId) {
2985
- return this.tokenApi.toggleTokenMetadataStatus(metadataId);
2986
- }
2987
- /**
2988
- * ADMIN: Create token type
2989
- */
2990
- async createTokenType(tokenType) {
2991
- return this.tokenApi.createTokenType(tokenType);
2992
- }
2993
- }
2994
-
2995
- /**
2996
- * Token SDK - Class-based Promise SDK for Token Operations
2997
- *
2998
- * Modern, performant SDK with direct method access and excellent TypeScript support.
2999
- * Optimized for bundle size, performance, and developer experience.
3000
- *
3001
- * Usage:
3002
- * const tokenSDK = new TokenSDK(apiClient);
3003
- * const tokens = await tokenSDK.getTokens();
3004
- * const creditToken = await tokenSDK.getActiveCreditToken();
3005
- */
3006
- class TokenSDK {
3007
- constructor(apiClient) {
3008
- this.tokenApi = new TokenApi(apiClient);
3009
- this.tokenService = new TokenService(this.tokenApi);
3010
- }
3011
- // ==========================================
3012
- // CONVENIENCE METHODS - Direct Promise API
3013
- // ==========================================
3014
- // Simplified method names for better developer experience
3015
- /**
3016
- * Get all tokens
3017
- * @returns Promise with all available tokens
3018
- */
3019
- async getTokens() {
3020
- return this.tokenService.getRemoteTokens();
3021
- }
3022
- /**
3023
- * Get all token types
3024
- * @returns Promise with all available token types
3025
- */
3026
- async getTokenTypes() {
3027
- return this.tokenService.getRemoteTokenTypes();
3028
- }
3029
- /**
3030
- * Get the active credit token
3031
- * @returns Promise with the current active credit token
3032
- */
3033
- async getActiveCreditToken() {
3034
- return this.tokenService.getRemoteActiveCreditToken();
3035
- }
3036
- /**
3037
- * Get all reward tokens
3038
- * @returns Promise with all reward tokens
3039
- */
3040
- async getRewardTokens() {
3041
- return this.tokenService.getRemoteRewardTokens();
3042
- }
3043
- /**
3044
- * Get all status tokens
3045
- * @returns Promise with all status tokens
3046
- */
3047
- async getStatusTokens() {
3048
- return this.tokenService.getRemoteStatusTokens();
3049
- }
3050
- /**
3051
- * Get token by contract address
3052
- * @param contractAddress - The contract address to search for
3053
- * @param contractTokenId - Optional contract token ID
3054
- * @returns Promise with the matching token
3055
- */
3056
- async getTokenByContract(contractAddress, contractTokenId = null) {
3057
- return this.tokenService.getTokenByContractAddress(contractAddress, contractTokenId);
3058
- }
3059
- // ==========================================
3060
- // ADMIN METHODS - Token Management
3061
- // ==========================================
3062
- /**
3063
- * Create token metadata
3064
- * @param tokenId - The token ID
3065
- * @param tokenData - The token storage data
3066
- * @returns Promise with the updated token
3067
- */
3068
- async createTokenMetadata(tokenId, tokenData) {
3069
- return this.tokenService.createTokenMetadata(tokenId, tokenData);
3070
- }
3071
- /**
3072
- * Toggle token active status
3073
- * @param tokenId - The token ID to toggle
3074
- * @returns Promise with the updated token
3075
- */
3076
- async toggleTokenActive(tokenId) {
3077
- return this.tokenService.toggleTokenActive(tokenId);
3078
- }
3079
- /**
3080
- * Create a new token
3081
- * @param tokenData - The token creation data
3082
- * @returns Promise with the created token
3083
- */
3084
- async createToken(tokenData) {
3085
- return this.tokenService.createToken(tokenData);
3086
- }
3087
- /**
3088
- * Update an existing token
3089
- * @param tokenId - The token ID to update
3090
- * @param tokenData - The token update data
3091
- * @returns Promise with the updated token
3092
- */
3093
- async updateToken(tokenId, tokenData) {
3094
- return this.tokenService.updateToken(tokenId, tokenData);
3095
- }
3096
- /**
3097
- * Set mainnet contract address for a token
3098
- * @param tokenId - The token ID
3099
- * @param contractAddress - The contract address
3100
- * @param chainId - The blockchain chain ID
3101
- * @returns Promise with the updated token
3102
- */
3103
- async setMainnetContract(tokenId, contractAddress, chainId) {
3104
- return this.tokenService.setMainnetContract(tokenId, contractAddress, chainId);
3105
- }
3106
- /**
3107
- * Toggle token metadata status
3108
- * @param metadataId - The metadata ID to toggle
3109
- * @returns Promise with the updated metadata
3110
- */
3111
- async toggleTokenMetadataStatus(metadataId) {
3112
- return this.tokenService.toggleTokenMetadataStatus(metadataId);
3113
- }
3114
- /**
3115
- * Create a new token type
3116
- * @param tokenType - The token type data
3117
- * @returns Promise with the created token type
3118
- */
3119
- async createTokenType(tokenType) {
3120
- return this.tokenService.createTokenType(tokenType);
3121
- }
3122
- // ==========================================
3123
- // ADVANCED ACCESS - For Complex Operations
3124
- // ==========================================
3125
- /**
3126
- * Get direct access to the token service for advanced operations
3127
- * @returns The underlying TokenService instance
3128
- */
3129
- getTokenService() {
3130
- return this.tokenService;
3131
- }
3132
- /**
3133
- * Get direct access to the token API for low-level operations
3134
- * @returns The underlying TokenApi instance
3135
- */
3136
- getTokenApi() {
3137
- return this.tokenApi;
3138
- }
3139
- // ==========================================
3140
- // FRAMEWORK COMPATIBILITY METHODS
3141
- // ==========================================
3142
- // These maintain compatibility with existing framework method names
3143
- /**
3144
- * @deprecated Use getTokens() instead
3145
- * Framework compatibility method
3146
- */
3147
- async getRemoteTokens() {
3148
- return this.getTokens();
3149
- }
3150
- /**
3151
- * @deprecated Use getTokenTypes() instead
3152
- * Framework compatibility method
3153
- */
3154
- async getRemoteTokenTypes() {
3155
- return this.getTokenTypes();
3156
- }
3157
- /**
3158
- * @deprecated Use getActiveCreditToken() instead
3159
- * Framework compatibility method
3160
- */
3161
- async getRemoteActiveCreditToken() {
3162
- return this.getActiveCreditToken();
3163
- }
3164
- /**
3165
- * @deprecated Use getRewardTokens() instead
3166
- * Framework compatibility method
3167
- */
3168
- async getRemoteRewardTokens() {
3169
- return this.getRewardTokens();
3170
- }
3171
- /**
3172
- * @deprecated Use getStatusTokens() instead
3173
- * Framework compatibility method
3174
- */
3175
- async getRemoteStatusTokens() {
3176
- return this.getStatusTokens();
3177
- }
3178
- /**
3179
- * @deprecated Use getTokenByContract() instead
3180
- * Framework compatibility method
3181
- */
3182
- async getTokenByContractAddress(contractAddress, contractTokenId) {
3183
- return this.getTokenByContract(contractAddress, contractTokenId);
3184
- }
3185
- }
3186
-
3187
- /**
3188
- * Abstract Base Token Service - Explicit Initialization Pattern
3189
- *
3190
- * Platform-agnostic token operations with Promise-based API.
3191
- * Framework services extend this and control initialization lifecycle.
3192
- *
3193
- * Benefits:
3194
- * - Explicit initialization control
3195
- * - Better error boundaries
3196
- * - Clear lifecycle management
3197
- * - Testable initialization state
3198
- * - Zero framework dependencies
3199
- */
3200
- class BaseTokenService {
3201
- constructor() {
3202
- this._isInitialized = false;
3203
- }
3204
- // ==========================================
3205
- // INITIALIZATION LIFECYCLE
3206
- // ==========================================
3207
- /**
3208
- * LIFECYCLE: Initialize token service with API client
3209
- * Must be called before using any token operations
3210
- */
3211
- initializeTokenService(apiClient) {
3212
- if (!apiClient) {
3213
- throw new Error('Cannot initialize TokenService: apiClient is null or undefined');
3214
- }
3215
- if (!this._isInitialized) {
3216
- this._tokenApi = new TokenApi(apiClient);
3217
- this._tokenBusinessService = new TokenService(this._tokenApi);
3218
- this._isInitialized = true;
3219
- }
3220
- }
3221
- /**
3222
- * LIFECYCLE: Check if token service is initialized
3223
- */
3224
- get isTokenServiceInitialized() {
3225
- return this._isInitialized;
3226
- }
3227
- /**
3228
- * INTERNAL: Get token business service (throws if not initialized)
3229
- */
3230
- get tokenBusinessService() {
3231
- if (!this._tokenBusinessService) {
3232
- throw new Error('TokenService not initialized. Call initializeTokenService(apiClient) first.');
3233
- }
3234
- return this._tokenBusinessService;
3235
- }
3236
- // ==========================================
3237
- // PUBLIC OPERATIONS
3238
- // ==========================================
3239
- /**
3240
- * PUBLIC: Get all remote tokens
3241
- */
3242
- getRemoteTokens() {
3243
- return this.tokenBusinessService.getRemoteTokens();
3244
- }
3245
- /**
3246
- * PUBLIC: Get all remote token types
3247
- */
3248
- getRemoteTokenTypes() {
3249
- return this.tokenBusinessService.getRemoteTokenTypes();
3250
- }
3251
- /**
3252
- * PUBLIC: Get active credit token
3253
- */
3254
- getRemoteActiveCreditToken() {
3255
- return this.tokenBusinessService.getRemoteActiveCreditToken();
3256
- }
3257
- /**
3258
- * PUBLIC: Get reward tokens
3259
- */
3260
- getRemoteRewardTokens() {
3261
- return this.tokenBusinessService.getRemoteRewardTokens();
3262
- }
3263
- /**
3264
- * PUBLIC: Get status tokens
3265
- */
3266
- getRemoteStatusTokens() {
3267
- return this.tokenBusinessService.getRemoteStatusTokens();
3268
- }
3269
- /**
3270
- * PUBLIC: Get token by contract address
3271
- */
3272
- getTokenByContractAddress(contractAddress, contractTokenId) {
3273
- return this.tokenBusinessService.getTokenByContractAddress(contractAddress, contractTokenId);
3274
- }
3275
- // ==========================================
3276
- // ADMIN OPERATIONS
3277
- // ==========================================
3278
- /**
3279
- * ADMIN: Create token metadata
3280
- */
3281
- createTokenMetadata(tokenId, tokenData) {
3282
- return this.tokenBusinessService.createTokenMetadata(tokenId, tokenData);
3283
- }
3284
- /**
3285
- * ADMIN: Toggle token active status
3286
- */
3287
- toggleTokenActive(tokenId) {
3288
- return this.tokenBusinessService.toggleTokenActive(tokenId);
3289
- }
3290
- /**
3291
- * ADMIN: Create new token
3292
- */
3293
- createToken(tokenData) {
3294
- return this.tokenBusinessService.createToken(tokenData);
3295
- }
3296
- /**
3297
- * ADMIN: Update token
3298
- */
3299
- updateToken(tokenId, tokenData) {
3300
- return this.tokenBusinessService.updateToken(tokenId, tokenData);
3301
- }
3302
- /**
3303
- * ADMIN: Set mainnet contract address
3304
- */
3305
- setMainnetContract(tokenId, contractAddress, chainId) {
3306
- return this.tokenBusinessService.setMainnetContract(tokenId, contractAddress, chainId);
3307
- }
3308
- /**
3309
- * ADMIN: Toggle token metadata status
3310
- */
3311
- toggleTokenMetadataStatus(metadataId) {
3312
- return this.tokenBusinessService.toggleTokenMetadataStatus(metadataId);
3313
- }
3314
- /**
3315
- * ADMIN: Create token type
3316
- */
3317
- createTokenType(tokenType) {
3318
- return this.tokenBusinessService.createTokenType(tokenType);
3319
- }
3320
- }
3321
-
3322
- /**
3323
- * Platform-Agnostic User API Client
3324
- *
3325
- * Handles user operations using the PERS backend RESTful API.
3326
- * Updated to use new /users endpoints with enhanced security and consistency.
3327
- * Maintains framework UserApiService method compatibility.
3328
- */
3329
- class UserApi {
3330
- constructor(apiClient) {
3331
- this.apiClient = apiClient;
3332
- this.basePath = '/users';
3333
- }
3334
- // ==========================================
3335
- // PUBLIC OPERATIONS
3336
- // ==========================================
3337
- /**
3338
- * PUBLIC: Get all users public profiles with optional filtering
3339
- * ✅ UPDATED: Uses new RESTful /users/public endpoint
3340
- */
3341
- async getAllUsersPublicProfiles(filter = null) {
3342
- let url = `${this.basePath}/public`;
3343
- if (filter) {
3344
- // ✅ MAINTAINED: Same parameter pattern for compatibility
3345
- const params = new URLSearchParams();
3346
- params.set('filterKey', filter.key);
3347
- params.set('filterValue', filter.value);
3348
- url += `?${params.toString()}`;
3349
- }
3350
- return this.apiClient.get(url);
3351
- }
3352
- // ==========================================
3353
- // AUTHENTICATED OPERATIONS
3354
- // ==========================================
3355
- /**
3356
- * AUTH: Get current authenticated user
3357
- * ✅ UPDATED: Uses new RESTful /users/me endpoint
3358
- */
3359
- async getRemoteUser() {
3360
- return this.apiClient.get(`${this.basePath}/me`);
3361
- }
3362
- /**
3363
- * AUTH: Update current authenticated user
3364
- * ✅ UPDATED: Uses new RESTful /users/me endpoint
3365
- */
3366
- async updateRemoteUser(updateRequest) {
3367
- return this.apiClient.put(`${this.basePath}/me`, updateRequest);
3368
- }
3369
- // ==========================================
3370
- // ADMIN OPERATIONS
3371
- // ==========================================
3372
- /**
3373
- * ADMIN: Get all remote users with query parameters
3374
- * ✅ UPDATED: Uses new RESTful /users endpoint with role-based access
3375
- * Note: Admin users get full data, non-admin users get public profiles only
3376
- */
3377
- async getAllRemoteUsers() {
3378
- // ✅ MAINTAINED: Same merge=soft parameter for compatibility
3379
- const url = `${this.basePath}?merge=soft`;
3380
- return this.apiClient.get(url);
3381
- }
3382
- /**
3383
- * ADMIN: Update user as admin
3384
- * ✅ UPDATED: Uses new RESTful /users/{id} endpoint
3385
- */
3386
- async updateUserAsAdmin(id, userData) {
3387
- return this.apiClient.put(`${this.basePath}/${id}`, userData);
3388
- }
3389
- /**
3390
- * ADMIN: Toggle user active status
3391
- * ✅ UPDATED: Uses new consistent /users/{id}/status endpoint
3392
- * Enhanced: Follows RESTful status management pattern across all domains
3393
- */
3394
- async toggleUserActiveStatusByUser(user) {
3395
- return this.apiClient.put(`${this.basePath}/${user.id}/status`, {});
3396
- }
3397
- /**
3398
- * ADMIN: Get user by unique identifier
3399
- * ✅ UPDATED: Uses new RESTful /users/{id} endpoint
3400
- */
3401
- async getUserByUniqueIdentifier(id) {
3402
- return this.apiClient.get(`${this.basePath}/${id}`);
3403
- }
3404
- }
3405
-
3406
- /**
3407
- * Platform-Agnostic User Service
3408
- *
3409
- * Contains user business logic and operations that work across platforms.
3410
- * No framework dependencies - pure TypeScript business logic.
3411
- * Matches framework UserApiService capabilities exactly.
3412
- */
3413
- class UserService {
3414
- constructor(userApi) {
3415
- this.userApi = userApi;
3416
- }
3417
- // ==========================================
3418
- // PUBLIC OPERATIONS
3419
- // ==========================================
3420
- /**
3421
- * PUBLIC: Get all users public profiles with optional filtering
3422
- * ✅ FIXED: Uses framework-compatible inline filter type
3423
- */
3424
- async getAllUsersPublicProfiles(filter = null) {
3425
- return this.userApi.getAllUsersPublicProfiles(filter);
3426
- }
3427
- // ==========================================
3428
- // AUTHENTICATED OPERATIONS
3429
- // ==========================================
3430
- /**
3431
- * AUTH: Get current authenticated user
3432
- */
3433
- async getRemoteUser() {
3434
- return this.userApi.getRemoteUser();
3435
- }
3436
- /**
3437
- * AUTH: Update current authenticated user
3438
- */
3439
- async updateRemoteUser(updateRequest) {
3440
- return this.userApi.updateRemoteUser(updateRequest);
3441
- }
3442
- // ==========================================
3443
- // ADMIN OPERATIONS
3444
- // ==========================================
3445
- /**
3446
- * ADMIN: Get all remote users
3447
- * ✅ FIXED: Matches API method signature (no parameters needed)
3448
- */
3449
- async getAllRemoteUsers() {
3450
- return this.userApi.getAllRemoteUsers();
3451
- }
3452
- /**
3453
- * ADMIN: Update user as admin
3454
- */
3455
- async updateUserAsAdmin(id, userData) {
3456
- return this.userApi.updateUserAsAdmin(id, userData);
3457
- }
3458
- async getUserByUniqueIdentifier(id) {
3459
- return this.userApi.getUserByUniqueIdentifier(id);
3460
- }
3461
- /**
3462
- * ADMIN: Toggle user active status by user object
3463
- * ✅ FIXED: Matches API method signature exactly
3464
- */
3465
- async toggleUserActiveStatusByUser(user) {
3466
- return this.userApi.toggleUserActiveStatusByUser(user);
3467
- }
3468
- }
3469
-
3470
- /**
3471
- * @explorins/pers-sdk-user
3472
- *
3473
- * Platform-agnostic User Domain SDK for PERS ecosystem
3474
- * Handles user management, profiles, and authentication operations
3475
- */
3476
- // API Layer
3477
- /**
3478
- * Create a complete User SDK instance
3479
- *
3480
- * @param apiClient - Configured PERS API client
3481
- * @returns User SDK with flattened structure for better DX
3482
- */
3483
- function createUserSDK(apiClient) {
3484
- const userApi = new UserApi(apiClient);
3485
- const userService = new UserService(userApi);
3486
- return {
3487
- // Direct access to service methods (primary interface)
3488
- // Public methods - matches framework exactly
3489
- getAllUsersPublicProfiles: (filter = null) => userService.getAllUsersPublicProfiles(filter),
3490
- // Auth methods - matches framework exactly
3491
- getRemoteUser: () => userService.getRemoteUser(),
3492
- updateRemoteUser: (updateRequest) => userService.updateRemoteUser(updateRequest),
3493
- // Admin methods - matches framework exactly
3494
- getAllRemoteUsers: () => userService.getAllRemoteUsers(),
3495
- updateUserAsAdmin: (id, userData) => userService.updateUserAsAdmin(id, userData),
3496
- toggleUserActiveStatusByUser: (user) => userService.toggleUserActiveStatusByUser(user),
3497
- getUserByUniqueIdentifier: (id) => userService.getUserByUniqueIdentifier(id),
3498
- // Advanced access for edge cases
3499
- api: userApi,
3500
- service: userService
3501
- };
3502
- }
3503
-
3504
- /**
3505
- * Platform-Agnostic User Status API Client
3506
- *
3507
- * Handles user status operations using the PERS backend.
3508
- * Matches framework UserStatusApiService methods exactly.
3509
- *
3510
- * ✅ UPDATED: All endpoints updated to new RESTful /users patterns
3511
- *
3512
- * Error handling patterns follow framework implementation:
3513
- * - getRemoteEarnedUserStatus() uses silent fallback (empty array)
3514
- * - Other operations throw errors for proper error handling
3515
- */
3516
- class UserStatusApi {
3517
- constructor(apiClient) {
3518
- this.apiClient = apiClient;
3519
- this.basePath = '/users';
3520
- }
3521
- // ==========================================
3522
- // PUBLIC OPERATIONS
3523
- // ==========================================
3524
- /**
3525
- * PUBLIC: Get remote user status types
3526
- * ✅ UPDATED: /user/status-type → /users/status-types
3527
- */
3528
- async getRemoteUserStatusTypes() {
3529
- try {
3530
- return await this.apiClient.get(`${this.basePath}/status-types`);
3531
- }
3532
- catch (error) {
3533
- console.error('Error getting user status types', error);
3534
- throw error;
3535
- }
3536
- }
3537
- // ==========================================
3538
- // AUTHENTICATED OPERATIONS
3539
- // ==========================================
3540
- /**
3541
- * AUTH: Get earned user status for authenticated user
3542
- * ✅ UPDATED: /user/auth/status → /users/me/status
3543
- * ✅ FIXED: Returns UserStatusTypeDTO[] to match framework exactly
3544
- * Note: Uses silent fallback pattern from framework - returns empty array on error
3545
- */
3546
- async getRemoteEarnedUserStatus() {
3547
- try {
3548
- return await this.apiClient.get(`${this.basePath}/me/status`);
3549
- }
3550
- catch (error) {
3551
- console.error('Error getting user status', error);
3552
- // ✅ FIXED: Silent fallback pattern from framework implementation
3553
- return [];
3554
- }
3555
- }
3556
- // ==========================================
3557
- // ADMIN OPERATIONS
3558
- // ==========================================
3559
- /**
3560
- * ADMIN: Create user status type
3561
- * ✅ UPDATED: /user/admin/status-type → /users/status-types
3562
- */
3563
- async createUserStatusType(userStatusType) {
3564
- try {
3565
- return await this.apiClient.post(`${this.basePath}/status-types`, userStatusType);
3566
- }
3567
- catch (error) {
3568
- console.error('Error creating user status type', error);
3569
- throw error;
3570
- }
3571
- }
3572
- }
3573
-
3574
- /**
3575
- * Platform-Agnostic User Status Service
3576
- *
3577
- * Contains user status business logic and operations that work across platforms.
3578
- * No framework dependencies - pure TypeScript business logic.
3579
- * Matches framework UserStatusApiService capabilities exactly.
3580
- */
3581
- class UserStatusService {
3582
- constructor(userStatusApi) {
3583
- this.userStatusApi = userStatusApi;
3584
- }
3585
- // ==========================================
3586
- // PUBLIC OPERATIONS
3587
- // ==========================================
3588
- /**
3589
- * PUBLIC: Get remote user status types
3590
- */
3591
- async getRemoteUserStatusTypes() {
3592
- return this.userStatusApi.getRemoteUserStatusTypes();
3593
- }
3594
- // ==========================================
3595
- // AUTHENTICATED OPERATIONS
3596
- // ==========================================
3597
- /**
3598
- * AUTH: Get earned user status for authenticated user
3599
- */
3600
- async getRemoteEarnedUserStatus() {
3601
- return this.userStatusApi.getRemoteEarnedUserStatus();
3602
- }
3603
- // ==========================================
3604
- // ADMIN OPERATIONS
3605
- // ==========================================
3606
- /**
3607
- * ADMIN: Create user status type
3608
- */
3609
- async createUserStatusType(userStatusType) {
3610
- return this.userStatusApi.createUserStatusType(userStatusType);
3611
- }
3612
- }
3613
-
3614
- /**
3615
- * @explorins/pers-sdk-user-status
3616
- *
3617
- * Platform-agnostic User Status Domain SDK for PERS ecosystem
3618
- * Handles user status management and type operations
3619
- */
3620
- // API Layer
3621
- /**
3622
- * Create a complete User Status SDK instance
3623
- *
3624
- * @param apiClient - Configured PERS API client
3625
- * @returns User Status SDK with flattened structure for better DX
3626
- */
3627
- function createUserStatusSDK(apiClient) {
3628
- const userStatusApi = new UserStatusApi(apiClient);
3629
- const userStatusService = new UserStatusService(userStatusApi);
3630
- return {
3631
- // Direct access to service methods (primary interface)
3632
- // ✅ FRAMEWORK ALIGNED: Only methods actually used by framework
3633
- // Public methods
3634
- getRemoteUserStatusTypes: () => userStatusService.getRemoteUserStatusTypes(),
3635
- // Auth methods
3636
- getRemoteEarnedUserStatus: () => userStatusService.getRemoteEarnedUserStatus(),
3637
- // Admin methods
3638
- createUserStatusType: (userStatusType) => userStatusService.createUserStatusType(userStatusType),
3639
- // Advanced access for edge cases
3640
- api: userStatusApi,
3641
- service: userStatusService
3642
- };
3643
- }
3644
-
3645
- /**
3646
- * Platform-Agnostic Web3 Chain API Client
3647
- *
3648
- * Handles blockchain chain operations using the PERS backend.
3649
- * Uses @explorins/web3-ts types for perfect framework compatibility.
3650
- */
3651
- class Web3ChainApi {
3652
- constructor(apiClient) {
3653
- this.apiClient = apiClient;
3654
- this.basePath = '/chains';
3655
- }
3656
- // ==========================================
3657
- // PUBLIC OPERATIONS
3658
- // ==========================================
3659
- /**
3660
- * PUBLIC: Get chain data by chain ID
3661
- * ✅ Returns ChainData exactly as framework expects from @explorins/web3-ts
3662
- */
3663
- async getChainData(chainId) {
3664
- try {
3665
- console.log('🔍 [Web3ChainApi] Fetching chain data for chainId:', chainId);
3666
- const response = await this.apiClient.get(`${this.basePath}/${chainId}`);
3667
- if (!response) {
3668
- throw new Error(`No chain data received for chainId: ${chainId}`);
3669
- }
3670
- return response;
3671
- }
3672
- catch (error) {
3673
- console.error('❌ [Web3ChainApi] Failed to get chain data:', {
3674
- chainId,
3675
- error: error instanceof Error ? error.message : String(error)
3676
- });
3677
- throw error;
3678
- }
3679
- }
3680
- }
3681
-
3682
- const isTokenExpired = (token, margin = 60) => {
3683
- // ✅ SANITIZE: Remove any words (Bearer etc) if exists and get the token
3684
- const cleanToken = token.split(' ')[1] || token;
3685
- // ✅ VALIDATION: Check if token is jwt
3686
- if (!cleanToken || cleanToken.split('.').length !== 3) {
3687
- return true; // Consider invalid tokens as expired
3688
- }
3689
- try {
3690
- // ✅ TYPE-SAFE: Decode with proper typing
3691
- const decoded = jwtDecode.jwtDecode(cleanToken);
3692
- const currentTime = Math.floor(Date.now() / 1000);
3693
- // ✅ CONFIGURABLE: Use provided margin (default 60 seconds)
3694
- return decoded.exp < (currentTime + margin);
3695
- }
3696
- catch (error) {
3697
- console.error('[SDK JWT Utils] Error decoding JWT token:', error);
3698
- return true; // Consider unparseable tokens as expired
3699
- }
3700
- };
3701
-
3702
- class Web3ChainService {
3703
- constructor(web3ChainApi, providerService) {
3704
- this.web3ChainApi = web3ChainApi;
3705
- this.providerService = providerService;
3706
- this.web3InstanceCache = new Map();
3707
- }
3708
- async getWeb3ByChainId(chainId) {
3709
- const cached = this.web3InstanceCache.get(chainId);
3710
- // ✅ SMART CACHE: Check if cache is valid based on token expiration
3711
- if (cached && !this.checkIsTokenExpired(cached.chainData.authHeader)) {
3712
- console.log(`♻️ [Web3ChainService] Using cached Web3 instance for chain ${chainId}`);
3713
- return cached.web3Instance;
3714
- }
3715
- // ✅ CREATE WITH ERROR RECOVERY: Handle auth errors gracefully
3716
- try {
3717
- console.log(`🔧 [Web3ChainService] Creating new Web3 instance for chain ${chainId}`);
3718
- const { web3, chainData } = await this.createWeb3Instance(chainId);
3719
- // ✅ CACHE NEW INSTANCE
3720
- this.web3InstanceCache.set(chainId, {
3721
- web3Instance: web3,
3722
- chainData: chainData,
3723
- createdAt: Date.now(),
3724
- chainId
3725
- });
3726
- return web3;
3727
- }
3728
- catch (error) {
3729
- // ✅ AUTH ERROR RECOVERY: Clear cache and retry once
3730
- if (this.isAuthError(error)) {
3731
- console.warn(`🔄 [Web3ChainService] Auth error detected, clearing cache and retrying...`);
3732
- this.web3InstanceCache.delete(chainId);
3733
- // Retry once with fresh instance
3734
- const { web3, chainData } = await this.createWeb3Instance(chainId);
3735
- this.web3InstanceCache.set(chainId, {
3736
- web3Instance: web3,
3737
- chainData: chainData,
3738
- createdAt: Date.now(),
3739
- chainId
3740
- });
3741
- return web3;
3742
- }
3743
- throw error;
3744
- }
3745
- }
3746
- async getChainDataWithCache(chainId) {
3747
- const cached = this.web3InstanceCache.get(chainId);
3748
- //const now = Date.now();
3749
- if (cached && !this.checkIsTokenExpired(cached.chainData.authHeader)) {
3750
- console.log(`♻️ [Web3ChainService] Using cached ChainData for chain ${chainId}`);
3751
- return cached.chainData;
3752
- }
3753
- // If not cached, fetch fresh data
3754
- const chainData = await this.getChainDataById(chainId);
3755
- if (!chainData) {
3756
- throw new Error(`Chain data not found for chainId: ${chainId}`);
3757
- }
3758
- return chainData;
3759
- }
3760
- checkIsTokenExpired(authHeader) {
3761
- // ✅ NULL CHECK: Handle undefined case
3762
- if (!authHeader) {
3763
- return false; // No token means no expiration (public chains)
3764
- }
3765
- // ✅ FUNCTION CALL: Use imported function, not method
3766
- return isTokenExpired(authHeader);
3767
- }
3768
- async createWeb3Instance(chainId) {
3769
- const chainData = await this.getChainDataById(chainId);
3770
- if (!chainData) {
3771
- throw new Error(`Chain data not found for chainId: ${chainId}`);
3772
- }
3773
- // ✅ CRITICAL CHECK: Ensure authHeader is present for private chains
3774
- if (chainData.chainType === 'PRIVATE' && !chainData.authHeader) {
3775
- console.error('❌ [Web3ChainService] CRITICAL: Private chain missing authHeader!');
3776
- throw new Error(`Private chain ${chainId} missing authentication header`);
3777
- }
3778
- const web3 = await this.providerService.getWeb3(chainId, chainData.chainType || 'PUBLIC', chainData);
3779
- return { web3, chainData };
3780
- }
3781
- // ✅ HELPER: Type-safe error checking
3782
- isAuthError(error) {
3783
- const message = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
3784
- return (message.includes('unauthorized') ||
3785
- message.includes('401') ||
3786
- message.includes('token expired') ||
3787
- message.includes('invalid token'));
3788
- }
3789
- async getChainDataById(chainId) {
3790
- try {
3791
- return await this.web3ChainApi.getChainData(chainId);
3792
- }
3793
- catch (error) {
3794
- console.error('❌ [SDK Web3ChainService] Error getting chain data for chainId:', chainId, error);
3795
- return null;
3796
- }
3797
- }
3798
- }
3799
-
3800
- // ✅ REVERT: Función síncrona como el código comentado que funciona
3801
- const getWeb3ProviderFromChainData = (chainData, timeout = 15000, customUserAgentName = '', tokenRefresher) => {
3802
- console.log(`🔧 [getWeb3FCD] Creating provider for chain ${chainData.chainId || 'unknown'}`);
3803
- let ethersProvider;
3804
- if (chainData.authHeader) {
3805
- // ✅ AUTHENTICATED: For private chains
3806
- const fetchRequest = new ethers.FetchRequest(chainData.rpcUrl);
3807
- fetchRequest.timeout = timeout;
3808
- // ✅ IMPROVED AUTH HEADER: Better handling
3809
- const authValue = chainData.authHeader.startsWith('Bearer ')
3810
- ? chainData.authHeader
3811
- : `Bearer ${chainData.authHeader}`;
3812
- fetchRequest.setHeader('Authorization', authValue);
3813
- fetchRequest.setHeader('Content-Type', 'application/json');
3814
- fetchRequest.setHeader('Accept', 'application/json');
3815
- if (customUserAgentName) {
3816
- fetchRequest.setHeader('User-Agent', customUserAgentName);
3817
- }
3818
- ethersProvider = new ethers.JsonRpcProvider(fetchRequest, undefined, {
3819
- staticNetwork: false,
3820
- polling: false,
3821
- batchMaxCount: 1, // ✅ DISABLE BATCHING: Better for private chains
3822
- });
3823
- }
3824
- else {
3825
- // ✅ PUBLIC: For public chains
3826
- ethersProvider = new ethers.JsonRpcProvider(chainData.rpcUrl, undefined, {
3827
- staticNetwork: false,
3828
- polling: false,
3829
- });
3830
- }
3831
- console.log(`✅ [getWeb3FCD] Provider created successfully`);
3832
- return {
3833
- web3Provider: null,
3834
- ethersProvider: ethersProvider,
3835
- isAuthenticated: !!chainData.authHeader,
3836
- };
3837
- };
3838
- // ✅ NEW: Async wrapper with retry for higher-level usage
3839
- const getWeb3ProviderWithRetry = async (chainData, timeout = 15000, customUserAgentName = '', tokenRefresher, retryConfig = { maxAttempts: 3, baseDelay: 1000, maxDelay: 8000 }) => {
3840
- let lastError = null;
3841
- for (let attempt = 1; attempt <= retryConfig.maxAttempts; attempt++) {
3842
- try {
3843
- console.log(`🔄 [Web3Provider] Attempt ${attempt}/${retryConfig.maxAttempts} for chain ${chainData.chainId || 'unknown'}`);
3844
- // ✅ SYNC CALL: Use the original sync function
3845
- const provider = getWeb3ProviderFromChainData(chainData, timeout, customUserAgentName, tokenRefresher);
3846
- await validateChainConnection(provider.ethersProvider, chainData.authHeader ? 'private' : 'public');
3847
- console.log(`✅ [Web3Provider] Successfully connected on attempt ${attempt}`);
3848
- return provider;
3849
- }
3850
- catch (error) {
3851
- lastError = error instanceof Error ? error : new Error(String(error));
3852
- console.warn(`⚠️ [Web3Provider] Attempt ${attempt} failed:`, lastError.message);
3853
- // ✅ NO RETRY: if auth error, no retry
3854
- if (isAuthError(lastError) && chainData.authHeader) {
3855
- console.error(`❌ [Web3Provider] Auth error, stopping retries`);
3856
- break;
3857
- }
3858
- if (attempt === retryConfig.maxAttempts)
3859
- break;
3860
- const delay = Math.min(retryConfig.baseDelay * Math.pow(2, attempt - 1), retryConfig.maxDelay);
3861
- console.log(`⏳ [Web3Provider] Retrying in ${delay}ms...`);
3862
- await sleep(delay);
3863
- }
3864
- }
3865
- throw new Error(`Failed to create Web3 provider after ${retryConfig.maxAttempts} attempts. Last error: ${lastError?.message}`);
3866
- };
3867
- async function validateChainConnection(provider, chainType) {
3868
- try {
3869
- console.log(`🔍 [Validation] Testing ${chainType} chain connection...`);
3870
- // ✅ LIGHTWEIGHT TEST: Use eth_chainId (works for both public and private)
3871
- const timeoutPromise = new Promise((_, reject) => {
3872
- setTimeout(() => reject(new Error(`${chainType} chain validation timeout`)), 3000);
3873
- });
3874
- // Try chainId first (fast, lightweight, universal)
3875
- const chainIdPromise = provider.send('eth_chainId', []);
3876
- const result = await Promise.race([chainIdPromise, timeoutPromise]);
3877
- console.log(`✅ [Validation] ${chainType} chain connection validated - Chain ID: ${result}`);
3878
- }
3879
- catch (error) {
3880
- // ✅ FALLBACK: Try net_version if chainId fails
3881
- try {
3882
- console.log(`🔄 [Validation] Trying fallback validation for ${chainType} chain...`);
3883
- const timeoutPromise = new Promise((_, reject) => {
3884
- setTimeout(() => reject(new Error(`${chainType} chain fallback validation timeout`)), 3000);
3885
- });
3886
- const versionPromise = provider.send('net_version', []);
3887
- const result = await Promise.race([versionPromise, timeoutPromise]);
3888
- console.log(`✅ [Validation] ${chainType} chain connection validated via fallback - Network Version: ${result}`);
3889
- }
3890
- catch (fallbackError) {
3891
- throw new Error(`${chainType} chain validation failed: ${error instanceof Error ? error.message : String(error)}`);
3892
- }
3893
- }
3894
- }
3895
- // ✅ HELPER: Auth error detection
3896
- function isAuthError(error) {
3897
- const message = error.message.toLowerCase();
3898
- return (message.includes('unauthorized') ||
3899
- message.includes('401') ||
3900
- message.includes('token expired') ||
3901
- message.includes('-40100'));
3902
- }
3903
- // ✅ HELPER: Sleep utility
3904
- function sleep(ms) {
3905
- return new Promise(resolve => setTimeout(resolve, ms));
3906
- }
3907
- /*
3908
- //IMPORTANT//
3909
- //This function is temporary so we install ethers just to make it work, once we delete this function we must uninstall Ethers
3910
-
3911
- import { ChainData } from "@explorins/web3-ts";
3912
- import { FetchRequest, JsonRpcProvider } from "ethers";
3913
-
3914
- export const getWeb3ProviderFromChainData = (
3915
- chainData: ChainData,
3916
- timeout = 15000,
3917
- customUserAgentName = '',
3918
- tokenRefresher?: () => Promise<string>
3919
- ) => {
3920
-
3921
- // Fixed ethers provider setup for authenticated requests
3922
- let ethersProvider: JsonRpcProvider;
3923
-
3924
- if (chainData.authHeader) {
3925
- // For authenticated requests, create a custom FetchRequest
3926
- const fetchRequest = new FetchRequest(chainData.rpcUrl);
3927
- fetchRequest.timeout = timeout;
3928
- fetchRequest.setHeader('Authorization', chainData.authHeader);
3929
- fetchRequest.setHeader('Content-Type', 'application/json');
3930
-
3931
- if (customUserAgentName) {
3932
- fetchRequest.setHeader('User-Agent', customUserAgentName);
3933
- }
3934
-
3935
- // Create provider with the configured FetchRequest
3936
- ethersProvider = new JsonRpcProvider(fetchRequest, undefined, {
3937
- staticNetwork: false,
3938
- polling: false, // Disable polling for better Lambda performance
3939
- });
3940
- } else {
3941
- // For public chains, use simple URL-based provider
3942
- ethersProvider = new JsonRpcProvider(chainData.rpcUrl, undefined, {
3943
- staticNetwork: false,
3944
- polling: false,
3945
- });
3946
- }
3947
-
3948
- return {
3949
- web3Provider: null,
3950
- ethersProvider: ethersProvider,
3951
- isAuthenticated: !!chainData.authHeader,
3952
- };
3953
- }; */
3954
-
3955
- class Web3ProviderService {
3956
- constructor() {
3957
- this._web3 = null;
3958
- this._currentChainId = null;
3959
- this._creationPromise = null;
3960
- }
3961
- async getWeb3(chainId, chainType, chainData) {
3962
- // ✅ EARLY RETURN: Reuse existing provider
3963
- if (this._web3 && this._currentChainId === chainId) {
3964
- return this._web3;
3965
- }
3966
- // ✅ PREVENT RACE CONDITION: Wait for ongoing creation
3967
- if (this._creationPromise) {
3968
- return await this._creationPromise;
3969
- }
3970
- if (!chainId)
3971
- throw new Error('ChainId not found');
3972
- if (!chainData)
3973
- throw new Error('ChainData not found');
3974
- // ✅ CREATE AND CACHE: Single promise for concurrent calls
3975
- this._creationPromise = this.createProvider(chainId, chainType, chainData);
3976
- try {
3977
- const web3Instance = await this._creationPromise;
3978
- this._web3 = web3Instance;
3979
- this._currentChainId = chainId;
3980
- return web3Instance;
3981
- }
3982
- finally {
3983
- // ✅ CLEANUP: Always reset promise after completion
3984
- this._creationPromise = null;
3985
- }
3986
- }
3987
- async createProvider(chainId, chainType, chainData) {
3988
- const provider = await getWeb3ProviderWithRetry(chainData);
3989
- return this.convertToWeb3(provider);
3990
- }
3991
- convertToWeb3(provider) {
3992
- if (provider instanceof Web3) {
3993
- return provider;
3994
- }
3995
- if (provider && typeof provider === 'object' && 'web3Provider' in provider) {
3996
- const providerObj = provider;
3997
- // If we want to user the web3Provider directly:
3998
- /*if (providerObj.web3Provider) {
3999
- return new Web3(providerObj.web3Provider as never);
4000
- }*/
4001
- if (providerObj.ethersProvider) {
4002
- const url = this.extractUrlFromEthersProvider(providerObj.ethersProvider);
4003
- const headers = this.extractHeadersFromEthersProvider(providerObj.ethersProvider);
4004
- const web3 = new Web3(url);
4005
- const currentProvider = web3.currentProvider;
4006
- if (currentProvider) {
4007
- currentProvider['url'] = url;
4008
- if (headers && Object.keys(headers).length > 0) {
4009
- currentProvider['request'] = async (payload) => {
4010
- const response = await fetch(url, {
4011
- method: 'POST',
4012
- headers: {
4013
- 'Content-Type': 'application/json',
4014
- ...headers
4015
- },
4016
- body: JSON.stringify(payload)
4017
- });
4018
- if (!response.ok) {
4019
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
4020
- }
4021
- return await response.json();
4022
- };
4023
- }
4024
- }
4025
- return web3;
4026
- }
4027
- }
4028
- return new Web3(provider);
4029
- }
4030
- extractUrlFromEthersProvider(ethersProvider) {
4031
- return ethersProvider.connection?.url ||
4032
- ethersProvider._getConnection?.()?.url ||
4033
- ethersProvider.url ||
4034
- '';
4035
- }
4036
- extractHeadersFromEthersProvider(ethersProvider) {
4037
- return ethersProvider.connection?.headers ||
4038
- ethersProvider._getConnection?.()?.headers ||
4039
- {};
4040
- }
4041
- }
4042
- /* import Web3 from "web3";
4043
- import { ChainData, ChainType, ChainTypes } from "@explorins/web3-ts";
4044
- import { PublicHttpProviderService } from "./public-http-provider.service";
4045
- import { getWeb3ProviderFromChainData } from "./getWeb3FCD.service";
4046
-
4047
-
4048
- export class Web3ProviderService {
4049
-
4050
- private _web3: Web3 | null = null;
4051
- private _currentChainId: number | null = null;
4052
-
4053
- constructor(
4054
- private readonly publicHttpProviderService: PublicHttpProviderService,
4055
- ) {
4056
- }
4057
-
4058
- public async getWeb3(chainId: number, chainType: ChainType, privateChainData: ChainData | null = null) {
4059
- if (!this._web3 || this._currentChainId !== chainId) {
4060
-
4061
- if(!chainId) throw new Error('ChainId not found')
4062
-
4063
- try {
4064
- this._currentChainId = chainId;
4065
- const provider = await this.getWeb3ByChainId(chainId, chainType, privateChainData);
4066
- this._web3 = this.convertToWeb3(provider);
4067
- } catch (error) {
4068
- console.error('Error getting web3 connection from chain id ' + chainId , error)
4069
- throw new Error('Error getting web3 connection from chain id ' + chainId)
4070
- }
4071
- }
4072
- return this._web3 as Web3;
4073
- }
4074
-
4075
- // Keep return type as 'any' to avoid TypeScript errors while still being adapted later
4076
- private getWeb3ByChainId(chainId: number, chainType: ChainType, privateChainData: ChainData | null = null): any {
4077
- // Rest of the method remains the same
4078
- if(chainType === ChainTypes.PRIVATE && privateChainData) {
4079
- //const privateProvider = this.privateChainProviderService.getProviderFromChainData(privateChainData)
4080
- const privateProvider = getWeb3ProviderFromChainData(privateChainData);
4081
-
4082
- if(!privateProvider || privateProvider instanceof Error) throw new Error('Error getting web3 provider');
4083
-
4084
-
4085
- return privateProvider;
4086
-
4087
- } else {
4088
-
4089
- const publicProvider = this.publicHttpProviderService.getProvider(chainId)
4090
- if(!publicProvider || publicProvider instanceof Error) throw new Error('Error getting web3 provider');
4091
-
4092
- return publicProvider;
4093
- }
4094
- }
4095
-
4096
- private convertToWeb3(provider: unknown): Web3 {
4097
- if (provider instanceof Web3) {
4098
- return provider as Web3;
4099
- }
4100
-
4101
- if (provider && typeof provider === 'object' && 'web3Provider' in provider) {
4102
- const providerObj = provider as {
4103
- web3Provider?: unknown;
4104
- ethersProvider?: any;
4105
- isAuthenticated?: boolean;
4106
- };
4107
-
4108
- // If we want to user the web3Provider directly:
4109
- /*if (providerObj.web3Provider) {
4110
- return new Web3(providerObj.web3Provider as never);
4111
- }*/
4112
- /*if (providerObj.ethersProvider) {
4113
-
4114
- const url = this.extractUrlFromEthersProvider(providerObj.ethersProvider);
4115
- const headers = this.extractHeadersFromEthersProvider(providerObj.ethersProvider);
4116
-
4117
- const web3 = new Web3(url);
4118
- const currentProvider = web3.currentProvider as unknown as Record<string, unknown>;
4119
-
4120
- if (currentProvider) {
4121
- currentProvider['url'] = url;
4122
-
4123
- if (headers && Object.keys(headers).length > 0) {
4124
- currentProvider['request'] = async (payload: Record<string, unknown>): Promise<Record<string, unknown>> => {
4125
- const response = await fetch(url, {
4126
- method: 'POST',
4127
- headers: {
4128
- 'Content-Type': 'application/json',
4129
- ...headers
4130
- },
4131
- body: JSON.stringify(payload)
4132
- });
4133
-
4134
- if (!response.ok) {
4135
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
4136
- }
4137
-
4138
- return await response.json() as Record<string, unknown>;
4139
- };
4140
- }
4141
- }
4142
-
4143
- return web3;
4144
- }
4145
- }
4146
-
4147
- return new Web3(provider as never);
4148
- }
4149
-
4150
-
4151
- private extractUrlFromEthersProvider(ethersProvider: any): string {
4152
- return ethersProvider.connection?.url ||
4153
- ethersProvider._getConnection?.()?.url ||
4154
- ethersProvider.url ||
4155
- '';
4156
- }
4157
-
4158
- private extractHeadersFromEthersProvider(ethersProvider: any): Record<string, string> {
4159
- return ethersProvider.connection?.headers ||
4160
- ethersProvider._getConnection?.()?.headers ||
4161
- {};
4162
- }
4163
- } */
4164
-
4165
- /**
4166
- * Web3 Chain Domain Models
4167
- *
4168
- * Minimal interface definitions matching framework usage exactly.
4169
- * Local ChainData interface to avoid external dependency issues.
4170
- */
4171
- const ChainTypes = {
4172
- PUBLIC: 'PUBLIC',
4173
- PRIVATE: 'PRIVATE'
4174
- };
4175
-
4176
- function createWeb3ChainSDK(apiClient, providerService) {
4177
- const web3ChainApi = new Web3ChainApi(apiClient);
4178
- const web3ChainService = new Web3ChainService(web3ChainApi, providerService); // ✅ DIRECT INJECTION
4179
- return {
4180
- // ✅ REPLICA: Same methods as framework
4181
- getChainDataById: (chainId) => web3ChainService.getChainDataById(chainId),
4182
- getWeb3ByChainId: (chainId) => web3ChainService.getWeb3ByChainId(chainId),
4183
- api: web3ChainApi,
4184
- service: web3ChainService
4185
- };
4186
- }
4187
-
4188
- /**
4189
- * TokenDomainService - Domain service for token operations
4190
- * Implements business logic for token balance, metadata, and collection operations
4191
- */
4192
- class TokenDomainService {
4193
- constructor(web3Api, metadataService, contractService) {
4194
- this.web3Api = web3Api;
4195
- this.metadataService = metadataService;
4196
- this.contractService = contractService;
4197
- }
4198
- async getTokenBalance(request) {
4199
- const balance = await this.web3Api.getTokenBalance({
4200
- accountAddress: request.accountAddress,
4201
- contractAddress: request.contractAddress,
4202
- abi: request.abi,
4203
- tokenId: request.tokenId,
4204
- chainId: request.chainId
4205
- });
4206
- return {
4207
- tokenId: request.tokenId,
4208
- balance,
4209
- hasBalance: balance > 0,
4210
- metadata: null
4211
- };
4212
- }
4213
- async getTokenWithMetadata(params) {
4214
- try {
4215
- const balance = await this.web3Api.getTokenBalance({
4216
- accountAddress: params.accountAddress,
4217
- contractAddress: params.contractAddress,
4218
- abi: params.abi,
4219
- tokenId: params.tokenId,
4220
- chainId: params.chainId
4221
- });
4222
- let metadata = null;
4223
- if (balance > 0) {
4224
- const tokenUri = await this.web3Api.getTokenUri({
4225
- contractAddress: params.contractAddress,
4226
- abi: params.abi,
4227
- tokenId: params.tokenId,
4228
- chainId: params.chainId
4229
- });
4230
- if (tokenUri) {
4231
- metadata = await this.metadataService.fetchAndProcessMetadata(tokenUri, params.chainId);
4232
- }
4233
- }
4234
- return {
4235
- tokenId: params.tokenId,
4236
- balance,
4237
- hasBalance: balance > 0,
4238
- metadata
4239
- };
4240
- }
4241
- catch (error) {
4242
- console.error('Error getting token with metadata:', error);
4243
- return {
4244
- tokenId: params.tokenId,
4245
- balance: 0,
4246
- hasBalance: false,
4247
- metadata: null
4248
- };
4249
- }
4250
- }
4251
- async getTokenCollection(params) {
4252
- try {
4253
- const contractAnalysis = this.contractService.analyzeContract(params.abi);
4254
- const tokens = [];
4255
- if (!contractAnalysis.hasEnumeration && !contractAnalysis.isERC1155) {
4256
- console.warn('Contract does not support enumeration, cannot retrieve full collection');
4257
- return {
4258
- accountAddress: params.accountAddress,
4259
- contractAddress: params.contractAddress,
4260
- totalBalance: 0,
4261
- tokensRetrieved: 0,
4262
- tokens: [],
4263
- note: 'Contract does not support enumeration'
4264
- };
4265
- }
4266
- else if (contractAnalysis.isERC1155) {
4267
- const tokenIdsToProcess = params.tokenIds || [];
4268
- if (tokenIdsToProcess.length > 0) {
4269
- for (const tokenId of tokenIdsToProcess) {
4270
- const tokenBalance = await this.getTokenWithMetadata({
4271
- accountAddress: params.accountAddress,
4272
- contractAddress: params.contractAddress,
4273
- abi: params.abi,
4274
- tokenId,
4275
- chainId: params.chainId
4276
- });
4277
- tokens.push(tokenBalance);
4278
- }
4279
- }
4280
- console.log('ERC-1155 User balances:', tokens);
4281
- // ERC-1155: Cannot enumerate without knowing token IDs
4282
- // Would need to use events or provide specific token IDs
4283
- console.warn('ERC-1155 collection retrieval requires specific token IDs or event analysis');
4284
- return {
4285
- accountAddress: params.accountAddress,
4286
- contractAddress: params.contractAddress,
4287
- totalBalance: 0,
4288
- tokensRetrieved: 0,
4289
- tokens: tokens,
4290
- note: 'ERC-1155 collection retrieval requires specific token IDs. Use getTokenWithMetadata() for individual tokens.'
4291
- };
4292
- }
4293
- // Handle different token standards
4294
- if (contractAnalysis.isERC721) {
4295
- // ERC-721: Get user's total balance and enumerate through tokens
4296
- const userBalance = await this.web3Api.getTokenBalance({
4297
- accountAddress: params.accountAddress,
4298
- contractAddress: params.contractAddress,
4299
- abi: params.abi,
4300
- tokenId: null, // null for ERC-721 total balance
4301
- chainId: params.chainId
4302
- });
4303
- console.log(`ERC-721 User balance for ${params.accountAddress}:`, userBalance);
4304
- if (userBalance === 0) {
4305
- return {
4306
- accountAddress: params.accountAddress,
4307
- contractAddress: params.contractAddress,
4308
- totalBalance: 0,
4309
- tokensRetrieved: 0,
4310
- tokens: []
4311
- };
4312
- }
4313
- // Enumerate through user's tokens
4314
- const maxTokens = params.maxTokens || userBalance;
4315
- const tokensToRetrieve = Math.min(maxTokens, userBalance);
4316
- for (let i = 0; i < tokensToRetrieve; i++) {
4317
- try {
4318
- const tokenId = await this.web3Api.getTokenOfOwnerByIndex({
4319
- contractAddress: params.contractAddress,
4320
- abi: params.abi,
4321
- accountAddress: params.accountAddress,
4322
- tokenIndex: i,
4323
- chainId: params.chainId
4324
- });
4325
- const tokenWithMetadata = await this.getTokenWithMetadata({
4326
- accountAddress: params.accountAddress,
4327
- contractAddress: params.contractAddress,
4328
- abi: params.abi,
4329
- tokenId,
4330
- chainId: params.chainId
4331
- });
4332
- if (tokenWithMetadata.hasBalance) {
4333
- tokens.push(tokenWithMetadata);
4334
- }
4335
- }
4336
- catch (error) {
4337
- console.warn(`Error retrieving ERC-721 token at index ${i}:`, error);
4338
- continue;
4339
- }
4340
- }
4341
- }
4342
- else {
4343
- // Unknown standard
4344
- return {
4345
- accountAddress: params.accountAddress,
4346
- contractAddress: params.contractAddress,
4347
- totalBalance: 0,
4348
- tokensRetrieved: 0,
4349
- tokens: [],
4350
- note: 'Unsupported token standard for collection retrieval'
4351
- };
4352
- }
4353
- // Calculate total balance based on retrieved tokens
4354
- let totalBalance = 0;
4355
- if (contractAnalysis.isERC721) {
4356
- // For ERC-721, total balance is the number of unique tokens owned
4357
- totalBalance = tokens.length;
4358
- }
4359
- else {
4360
- // For other standards, sum up individual token balances
4361
- totalBalance = tokens.reduce((sum, token) => sum + token.balance, 0);
4362
- }
4363
- return {
4364
- accountAddress: params.accountAddress,
4365
- contractAddress: params.contractAddress,
4366
- totalBalance,
4367
- tokensRetrieved: tokens.length,
4368
- tokens
4369
- };
4370
- }
4371
- catch (error) {
4372
- console.error('Error getting token collection:', error);
4373
- return {
4374
- accountAddress: params.accountAddress,
4375
- contractAddress: params.contractAddress,
4376
- totalBalance: 0,
4377
- tokensRetrieved: 0,
4378
- tokens: [],
4379
- note: 'Error retrieving collection'
4380
- };
4381
- }
4382
- }
4383
- async getTokenMetadata(params) {
4384
- try {
4385
- const tokenUri = await this.web3Api.getTokenUri({
4386
- contractAddress: params.contractAddress,
4387
- abi: params.abi,
4388
- tokenId: params.tokenId,
4389
- chainId: params.chainId
4390
- });
4391
- let metadata = null;
4392
- if (tokenUri) {
4393
- metadata = await this.metadataService.fetchAndProcessMetadata(tokenUri, params.chainId);
4394
- }
4395
- return {
4396
- tokenId: params.tokenId,
4397
- tokenUri,
4398
- metadata
4399
- };
4400
- }
4401
- catch (error) {
4402
- console.error('Error getting token metadata:', error);
4403
- return {
4404
- tokenId: params.tokenId,
4405
- tokenUri: null,
4406
- metadata: null
4407
- };
4408
- }
4409
- }
4410
- }
4411
-
4412
- /**
4413
- * MetadataDomainService - Clean IPFS metadata resolution
4414
- */
4415
- class MetadataDomainService {
4416
- constructor(ipfsApi) {
4417
- this.ipfsApi = ipfsApi;
4418
- }
4419
- async fetchAndProcessMetadata(tokenUri, chainId) {
4420
- return this.ipfsApi.fetchAndProcessMetadata(tokenUri, chainId);
4421
- }
4422
- async resolveIPFSUrl(url, chainId) {
4423
- return this.ipfsApi.resolveIPFSUrl(url, chainId);
4424
- }
4425
- }
4426
-
4427
- /**
4428
- * ContractDomainService - Clean contract analysis without external dependencies
4429
- */
4430
- class ContractDomainService {
4431
- constructor() { }
4432
- analyzeContract(abi) {
4433
- const methods = abi.filter(item => item.type === 'function').map(item => item.name);
4434
- // ERC-721 detection
4435
- const hasOwnerOf = methods.includes('ownerOf');
4436
- const hasTokenURI = methods.includes('tokenURI');
4437
- const hasTransferFrom = methods.includes('transferFrom');
4438
- const isERC721 = hasOwnerOf && hasTokenURI && hasTransferFrom;
4439
- // ERC-1155 detection
4440
- const hasBalanceOfBatch = methods.includes('balanceOfBatch');
4441
- const hasSafeBatchTransferFrom = methods.includes('safeBatchTransferFrom');
4442
- const hasURI = methods.includes('uri');
4443
- const isERC1155 = hasBalanceOfBatch && hasSafeBatchTransferFrom && hasURI;
4444
- return {
4445
- hasEnumeration: methods.includes('tokenByIndex') && methods.includes('totalSupply'),
4446
- hasOwnerOf,
4447
- hasBalanceOf: methods.includes('balanceOf'),
4448
- hasTokenURI,
4449
- hasTransfer: methods.includes('transfer') || methods.includes('transferFrom'),
4450
- hasApprove: methods.includes('approve'),
4451
- isERC721,
4452
- isERC1155
4453
- };
4454
- }
4455
- supportsEnumeration(abi) {
4456
- return this.analyzeContract(abi).hasEnumeration;
4457
- }
4458
- supportsMethod(abi, methodName) {
4459
- const methods = abi.filter(item => item.type === 'function').map(item => item.name);
4460
- return methods.includes(methodName);
4461
- }
4462
- }
4463
-
4464
- /**
4465
- * Web3ApplicationService - Application layer entrance point
4466
- * Orchestrates domain services and provides clean public interface
4467
- * Simplified architecture with concrete classes
4468
- */
4469
- class Web3ApplicationService {
4470
- constructor(web3Api, ipfsApi) {
4471
- // Type-safe metadata conversion methods for ERC-721/ERC-1155 standards
4472
- this.metadataMapper = {
4473
- fromERCStandard: (ercMetadata) => ({
4474
- name: ercMetadata.name || '',
4475
- description: ercMetadata.description || '',
4476
- imageUrl: ercMetadata.image || '',
4477
- externalUrl: ercMetadata.external_url,
4478
- animationUrl: ercMetadata.animation_url,
4479
- animationUrlConverted: undefined, // Will be set by IPFS conversion
4480
- attributes: ercMetadata.attributes || [],
4481
- ...ercMetadata
4482
- }),
4483
- toERCStandard: (metadata) => ({
4484
- name: metadata.name,
4485
- description: metadata.description,
4486
- image: metadata.imageUrl,
4487
- animation_url: metadata.animationUrl,
4488
- external_url: metadata.externalUrl,
4489
- attributes: metadata.attributes,
4490
- ...Object.fromEntries(Object.entries(metadata).filter(([key]) => !['name', 'description', 'imageUrl', 'animationUrl', 'externalUrl', 'attributes', 'animationUrlConverted'].includes(key)))
4491
- })
4492
- };
4493
- // Create domain services with injected infrastructure dependencies
4494
- this.contractDomainService = new ContractDomainService();
4495
- this.metadataDomainService = new MetadataDomainService(ipfsApi);
4496
- this.tokenDomainService = new TokenDomainService(web3Api, this.metadataDomainService, this.contractDomainService);
4497
- }
4498
- /**
4499
- * Get balance and metadata for a specific token
4500
- */
4501
- async getSpecificTokenBalance(request) {
4502
- if (!request.tokenId) {
4503
- return this.tokenDomainService.getTokenBalance({
4504
- accountAddress: request.accountAddress || '',
4505
- contractAddress: request.contractAddress,
4506
- abi: request.abi,
4507
- tokenId: '',
4508
- chainId: request.chainId
4509
- });
4510
- }
4511
- return this.tokenDomainService.getTokenWithMetadata({
4512
- accountAddress: request.accountAddress || '',
4513
- contractAddress: request.contractAddress,
4514
- abi: request.abi,
4515
- tokenId: request.tokenId || '',
4516
- chainId: request.chainId
4517
- });
4518
- }
4519
- /**
4520
- * Get metadata for a specific token from on-chain
4521
- */
4522
- async getTokenMetadata(request) {
4523
- const domainResult = await this.tokenDomainService.getTokenMetadata({
4524
- contractAddress: request.contractAddress,
4525
- abi: request.abi,
4526
- tokenId: request.tokenId || '',
4527
- chainId: request.chainId
4528
- });
4529
- return domainResult.metadata;
4530
- }
4531
- /**
4532
- * Retrieve entire collection of tokens with balance and metadata
4533
- */
4534
- async getTokenCollection(request) {
4535
- return this.tokenDomainService.getTokenCollection({
4536
- accountAddress: request.accountAddress || '',
4537
- contractAddress: request.contractAddress,
4538
- abi: request.abi,
4539
- chainId: request.chainId,
4540
- maxTokens: request.maxTokens,
4541
- tokenIds: request.tokenIds
4542
- });
4543
- }
4544
- /**
4545
- * Resolve IPFS URLs to HTTPS if needed
4546
- */
4547
- async resolveIPFSUrl(url, chainId) {
4548
- return this.metadataDomainService.resolveIPFSUrl(url, chainId);
4549
- }
4550
- /**
4551
- * Fetch and process metadata from URI with IPFS conversion
4552
- */
4553
- async fetchAndProcessMetadata(tokenUri, chainId) {
4554
- const domainMetadata = await this.metadataDomainService.fetchAndProcessMetadata(tokenUri, chainId);
4555
- if (!domainMetadata)
4556
- return null;
4557
- // Convert from ERC token standard to our clean interface
4558
- const cleanMetadata = this.metadataMapper.fromERCStandard(domainMetadata);
4559
- // Add IPFS conversion if needed
4560
- if (cleanMetadata.animationUrl?.startsWith('ipfs://')) {
4561
- return {
4562
- ...cleanMetadata,
4563
- animationUrlConverted: await this.resolveIPFSUrl(cleanMetadata.animationUrl, chainId)
4564
- };
4565
- }
4566
- return cleanMetadata;
4567
- }
4568
- }
4569
-
4570
- /**
4571
- * Web3InfrastructureApi - Infrastructure implementation for blockchain operations
4572
- * Uses @explorins/web3-ts for Web3 interactions
4573
- */
4574
- class Web3InfrastructureApi {
4575
- constructor(web3ChainService) {
4576
- this.web3ChainService = web3ChainService;
4577
- }
4578
- async getTokenBalance(request) {
4579
- try {
4580
- if (request.tokenId !== null)
4581
- request.tokenId = request.tokenId.toString();
4582
- const web3 = await this.web3ChainService.getWeb3ByChainId(request.chainId);
4583
- const contract = web3Ts.getSmartContractInstance(request.contractAddress, request.abi, web3);
4584
- return await web3Ts.getAccountTokenBalance(contract, request.accountAddress, request.tokenId);
4585
- }
4586
- catch (error) {
4587
- console.error(`Failed to get token balance for ${request.accountAddress} for ${request.contractAddress} and tokenId ${request.tokenId}, return 0 instead:`, error);
4588
- return 0;
4589
- }
4590
- }
4591
- async getTokenUri(request) {
4592
- try {
4593
- const web3 = await this.web3ChainService.getWeb3ByChainId(request.chainId);
4594
- const contract = web3Ts.getSmartContractInstance(request.contractAddress, request.abi, web3);
4595
- const tokenId = Number(request.tokenId);
4596
- const tokenUri = await web3Ts.getTokenUri(contract, tokenId);
4597
- return String(tokenUri);
4598
- }
4599
- catch (error) {
4600
- console.error(`Failed to get token URI for tokenId ${request.tokenId}:`, error);
4601
- throw error;
4602
- }
4603
- }
4604
- async getTokenOfOwnerByIndex(request) {
4605
- try {
4606
- const web3 = await this.web3ChainService.getWeb3ByChainId(request.chainId);
4607
- const tokenContract = web3Ts.getSmartContractInstance(request.contractAddress, request.abi, web3);
4608
- const tokenId = await web3Ts.getTokenOfOwnerByIndex(tokenContract, request.accountAddress, request.tokenIndex);
4609
- return String(tokenId);
4610
- }
4611
- catch (error) {
4612
- console.error(`Failed to get token by index ${request.tokenIndex} for ${request.accountAddress}:`, error);
4613
- throw error;
4614
- }
4615
- }
4616
- }
4617
-
4618
- /**
4619
- * IPFSInfrastructureApi - Infrastructure implementation for IPFS operations
4620
- * Uses Web3ChainService for IPFS gateway resolution
4621
- */
4622
- class IPFSInfrastructureApi {
4623
- constructor(web3ChainService) {
4624
- this.web3ChainService = web3ChainService;
4625
- this.defaultIpfsGatewayDomain = 'pers.mypinata.cloud';
4626
- }
4627
- async getIpfsGatewayDomain(chainId) {
4628
- try {
4629
- const chainData = await this.web3ChainService.getChainDataWithCache(chainId);
4630
- return chainData.ipfsGatewayDomain || this.defaultIpfsGatewayDomain;
4631
- }
4632
- catch (error) {
4633
- console.warn(`Failed to get chain data for chainId ${chainId}, using default IPFS gateway:`, error);
4634
- return this.defaultIpfsGatewayDomain;
4635
- }
4636
- }
4637
- async resolveIPFSUrl(url, chainId) {
4638
- if (url.startsWith('ipfs://')) {
4639
- const gateway = await this.getIpfsGatewayDomain(chainId);
4640
- return url.replace('ipfs://', `https://${gateway}/ipfs/`);
4641
- }
4642
- return url;
4643
- }
4644
- async fetchAndProcessMetadata(tokenUri, chainId) {
4645
- try {
4646
- const resolvedUri = await this.resolveIPFSUrl(tokenUri, chainId);
4647
- const response = await fetch(resolvedUri);
4648
- if (!response.ok) {
4649
- throw new Error(`HTTP error! status: ${response.status}`);
4650
- }
4651
- const metadata = await response.json();
4652
- // Process and return clean metadata
4653
- return {
4654
- name: metadata.name || '',
4655
- description: metadata.description || '',
4656
- image: metadata.image ? await this.resolveIPFSUrl(metadata.image, chainId) : '',
4657
- attributes: metadata.attributes || [],
4658
- animation_url: metadata.animation_url ? await this.resolveIPFSUrl(metadata.animation_url, chainId) : undefined,
4659
- external_url: metadata.external_url || undefined
4660
- };
4661
- }
4662
- catch (error) {
4663
- console.error('Error fetching metadata:', error);
4664
- return null;
4665
- }
4666
- }
4667
- async fetchFromUrl(url) {
4668
- try {
4669
- const response = await fetch(url);
4670
- if (!response.ok) {
4671
- throw new Error(`Failed to fetch from ${url}: ${response.statusText}`);
4672
- }
4673
- return await response.json();
4674
- }
4675
- catch (error) {
4676
- console.error(`Error fetching from URL ${url}:`, error);
4677
- throw error;
4678
- }
4679
- }
4680
- }
4681
-
4682
- function createWeb3SDK(apiClient) {
4683
- // TODO: FIX LATER - TEMPORARY CONSTRUCTION
4684
- const web3ProviderService = new Web3ProviderService();
4685
- const web3ChainSDK = createWeb3ChainSDK(apiClient, web3ProviderService);
4686
- // Create Web3ApplicationService - main entry point for all Web3 operations
4687
- const web3InfrastructureApi = new Web3InfrastructureApi(web3ChainSDK.service);
4688
- const ipfsInfrastructureApi = new IPFSInfrastructureApi(web3ChainSDK.service);
4689
- const web3ApplicationService = new Web3ApplicationService(web3InfrastructureApi, ipfsInfrastructureApi);
4690
- // Clean SDK - all functions route through Web3ApplicationService
4691
- return {
4692
- getTokenBalance: (request) => web3ApplicationService.getSpecificTokenBalance(request),
4693
- getTokenMetadata: (request) => web3ApplicationService.getTokenMetadata(request),
4694
- getTokenCollection: (request) => web3ApplicationService.getTokenCollection(request),
4695
- resolveIPFSUrl: (url, chainId) => web3ApplicationService.resolveIPFSUrl(url, chainId),
4696
- fetchAndProcessMetadata: (tokenUri, chainId) => web3ApplicationService.fetchAndProcessMetadata(tokenUri, chainId),
4697
- applicationService: web3ApplicationService
4698
- };
4699
- }
4700
-
4701
- exports.AnalyticsApi = AnalyticsApi;
4702
- exports.AnalyticsService = AnalyticsService;
4703
- exports.AuthAdminApi = AuthAdminApi;
4704
- exports.AuthAdminService = AuthAdminService;
4705
- exports.BaseTokenService = BaseTokenService;
4706
- exports.BusinessApi = BusinessApi;
4707
- exports.BusinessService = BusinessService;
4708
- exports.CampaignApi = CampaignApi;
4709
- exports.CampaignService = CampaignService;
4710
- exports.ChainTypes = ChainTypes;
4711
- exports.DEFAULT_PERS_CONFIG = DEFAULT_PERS_CONFIG;
4712
- exports.DonationApi = DonationApi;
4713
- exports.DonationService = DonationService;
4714
- exports.IPFSInfrastructureApi = IPFSInfrastructureApi;
4715
- exports.PaymentApi = PurchaseApi;
4716
- exports.PaymentService = PaymentService;
4717
- exports.PersApiClient = PersApiClient;
4718
- exports.PersApiError = PersApiError;
4719
- exports.PersSDK = PersSDK;
4720
- exports.RedemptionApi = RedemptionApi;
4721
- exports.RedemptionService = RedemptionService;
4722
- exports.TenantApi = TenantApi;
4723
- exports.TenantService = TenantService;
4724
- exports.TokenApi = TokenApi;
4725
- exports.TokenSDK = TokenSDK;
4726
- exports.TokenService = TokenService;
4727
- exports.TransactionApi = TransactionApi;
4728
- exports.TransactionService = TransactionService;
4729
- exports.UserApi = UserApi;
4730
- exports.UserService = UserService;
4731
- exports.UserStatusApi = UserStatusApi;
4732
- exports.UserStatusService = UserStatusService;
4733
- exports.Web3ApplicationService = Web3ApplicationService;
4734
- exports.Web3ChainApi = Web3ChainApi;
4735
- exports.Web3ChainService = Web3ChainService;
4736
- exports.Web3InfrastructureApi = Web3InfrastructureApi;
4737
- exports.Web3ProviderService = Web3ProviderService;
4738
- exports.buildApiRoot = buildApiRoot;
4739
- exports.createAnalyticsSDK = createAnalyticsSDK;
4740
- exports.createAuthAdminSDK = createAuthAdminSDK;
4741
- exports.createAuthProvider = createAuthProvider;
4742
- exports.createBusinessSDK = createBusinessSDK;
4743
- exports.createCampaignSDK = createCampaignSDK;
4744
- exports.createDonationSDK = createDonationSDK;
4745
- exports.createPaymentSDK = createPaymentSDK;
4746
- exports.createPersSDK = createPersSDK;
4747
- exports.createRedemptionSDK = createRedemptionSDK;
4748
- exports.createTenantSDK = createTenantSDK;
4749
- exports.createTransactionSDK = createTransactionSDK;
4750
- exports.createUserSDK = createUserSDK;
4751
- exports.createUserStatusSDK = createUserStatusSDK;
4752
- exports.createWeb3ChainSDK = createWeb3ChainSDK;
4753
- exports.createWeb3SDK = createWeb3SDK;
4754
- exports.mergeWithDefaults = mergeWithDefaults;
14
+ var user = require('./user.cjs');
15
+ var userStatus = require('./user-status.cjs');
16
+ var web3Chain = require('./web3-chain.cjs');
17
+ var web3 = require('./web3.cjs');
18
+ require('./chunks/jwt.function-BYiyl-z_.cjs');
19
+ require('jwt-decode');
20
+ require('web3');
21
+ require('ethers');
22
+ require('@explorins/web3-ts');
23
+
24
+
25
+
26
+ exports.DEFAULT_PERS_CONFIG = persSdk.DEFAULT_PERS_CONFIG;
27
+ exports.PersApiClient = persSdk.PersApiClient;
28
+ exports.PersSDK = persSdk.PersSDK;
29
+ exports.buildApiRoot = persSdk.buildApiRoot;
30
+ exports.createPersSDK = persSdk.createPersSDK;
31
+ exports.mergeWithDefaults = persSdk.mergeWithDefaults;
32
+ exports.BusinessApi = business.BusinessApi;
33
+ exports.BusinessService = business.BusinessService;
34
+ exports.createBusinessSDK = business.createBusinessSDK;
35
+ Object.defineProperty(exports, "TransactionAccountType", {
36
+ enumerable: true,
37
+ get: function () { return transaction.TransactionAccountType; }
38
+ });
39
+ exports.TransactionApi = transaction.TransactionApi;
40
+ exports.TransactionService = transaction.TransactionService;
41
+ exports.createTransactionSDK = transaction.createTransactionSDK;
42
+ exports.AnalyticsApi = analytics.AnalyticsApi;
43
+ exports.AnalyticsService = analytics.AnalyticsService;
44
+ exports.createAnalyticsSDK = analytics.createAnalyticsSDK;
45
+ exports.CampaignApi = campaign.CampaignApi;
46
+ exports.CampaignService = campaign.CampaignService;
47
+ exports.createCampaignSDK = campaign.createCampaignSDK;
48
+ exports.DonationApi = donation.DonationApi;
49
+ exports.DonationService = donation.DonationService;
50
+ exports.createDonationSDK = donation.createDonationSDK;
51
+ exports.PaymentApi = payment.PaymentApi;
52
+ exports.PaymentService = payment.PaymentService;
53
+ exports.createPaymentSDK = payment.createPaymentSDK;
54
+ exports.RedemptionApi = redemption.RedemptionApi;
55
+ exports.RedemptionService = redemption.RedemptionService;
56
+ exports.createRedemptionSDK = redemption.createRedemptionSDK;
57
+ exports.TenantApi = tenant.TenantApi;
58
+ exports.TenantService = tenant.TenantService;
59
+ exports.createTenantSDK = tenant.createTenantSDK;
60
+ exports.BaseTokenService = baseTokenService.BaseTokenService;
61
+ exports.TokenApi = baseTokenService.TokenApi;
62
+ exports.TokenSDK = baseTokenService.TokenSDK;
63
+ exports.TokenService = baseTokenService.TokenService;
64
+ Object.defineProperty(exports, "AccountOwnerType", {
65
+ enumerable: true,
66
+ get: function () { return persShared.AccountOwnerType; }
67
+ });
68
+ exports.UserApi = user.UserApi;
69
+ exports.UserService = user.UserService;
70
+ exports.createUserSDK = user.createUserSDK;
71
+ exports.UserStatusApi = userStatus.UserStatusApi;
72
+ exports.UserStatusService = userStatus.UserStatusService;
73
+ exports.createUserStatusSDK = userStatus.createUserStatusSDK;
74
+ exports.ChainTypes = web3Chain.ChainTypes;
75
+ exports.Web3ChainApi = web3Chain.Web3ChainApi;
76
+ exports.Web3ChainService = web3Chain.Web3ChainService;
77
+ exports.Web3ProviderService = web3Chain.Web3ProviderService;
78
+ exports.createWeb3ChainSDK = web3Chain.createWeb3ChainSDK;
79
+ exports.IPFSInfrastructureApi = web3.IPFSInfrastructureApi;
80
+ exports.Web3ApplicationService = web3.Web3ApplicationService;
81
+ exports.Web3InfrastructureApi = web3.Web3InfrastructureApi;
82
+ exports.createWeb3SDK = web3.createWeb3SDK;
4755
83
  //# sourceMappingURL=index.cjs.map