@primethoughts/credence-sdk 1.0.0-rc.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.
package/dist/index.cjs ADDED
@@ -0,0 +1,1112 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ComplianceModule: () => ComplianceModule,
24
+ CredenceApiError: () => CredenceApiError,
25
+ CredenceAuthError: () => CredenceAuthError,
26
+ CredenceAuthorizationError: () => CredenceAuthorizationError,
27
+ CredenceClient: () => CredenceClient,
28
+ CredenceError: () => CredenceError,
29
+ CredenceNetworkError: () => CredenceNetworkError,
30
+ CredenceValidationError: () => CredenceValidationError,
31
+ CredentialsModule: () => CredentialsModule,
32
+ DEFAULT_RETRY_CONFIG: () => DEFAULT_RETRY_CONFIG,
33
+ EvidenceModule: () => EvidenceModule,
34
+ HttpClient: () => HttpClient,
35
+ IdentityModule: () => IdentityModule,
36
+ MessagingModule: () => MessagingModule,
37
+ Oid4vciModule: () => Oid4vciModule,
38
+ PaymentModule: () => PaymentModule,
39
+ PresentationsModule: () => PresentationsModule,
40
+ RegistryAdminModule: () => RegistryAdminModule,
41
+ RegistryModule: () => RegistryModule,
42
+ VdrModule: () => VdrModule,
43
+ isKeyMaterial: () => isKeyMaterial,
44
+ rejectKeyMaterial: () => rejectKeyMaterial,
45
+ toQueryParams: () => toQueryParams,
46
+ validateDid: () => validateDid,
47
+ validateRequired: () => validateRequired
48
+ });
49
+ module.exports = __toCommonJS(index_exports);
50
+
51
+ // src/utils/correlation.ts
52
+ function generateCorrelationId() {
53
+ if (typeof globalThis !== "undefined" && globalThis.crypto?.randomUUID) {
54
+ return globalThis.crypto.randomUUID();
55
+ }
56
+ return require("crypto").randomUUID();
57
+ }
58
+
59
+ // src/errors.ts
60
+ var CredenceError = class extends Error {
61
+ constructor(message) {
62
+ super(message);
63
+ this.name = "CredenceError";
64
+ }
65
+ };
66
+ var CredenceApiError = class extends CredenceError {
67
+ status;
68
+ title;
69
+ detail;
70
+ type;
71
+ instance;
72
+ correlationId;
73
+ method;
74
+ path;
75
+ constructor(params) {
76
+ const msg = `${params.method} ${params.path} failed with ${params.status}: ${params.title}${params.detail ? ` \u2014 ${params.detail}` : ""}${params.correlationId ? ` [correlationId=${params.correlationId}]` : ""}`;
77
+ super(msg);
78
+ this.name = "CredenceApiError";
79
+ this.status = params.status;
80
+ this.title = params.title;
81
+ this.detail = params.detail ?? null;
82
+ this.type = params.type ?? null;
83
+ this.instance = params.instance ?? null;
84
+ this.correlationId = params.correlationId ?? null;
85
+ this.method = params.method;
86
+ this.path = params.path;
87
+ }
88
+ };
89
+ var CredenceAuthError = class extends CredenceApiError {
90
+ constructor(params) {
91
+ super({
92
+ status: 401,
93
+ title: "Unauthorized",
94
+ detail: "Authentication required or token expired",
95
+ method: params.method,
96
+ path: params.path,
97
+ correlationId: params.correlationId
98
+ });
99
+ this.name = "CredenceAuthError";
100
+ }
101
+ };
102
+ var CredenceAuthorizationError = class extends CredenceApiError {
103
+ constructor(params) {
104
+ super({
105
+ status: 403,
106
+ title: "Forbidden",
107
+ detail: params.detail ?? "Insufficient permissions for this operation",
108
+ method: params.method,
109
+ path: params.path,
110
+ correlationId: params.correlationId
111
+ });
112
+ this.name = "CredenceAuthorizationError";
113
+ }
114
+ };
115
+ var CredenceNetworkError = class extends CredenceError {
116
+ cause;
117
+ constructor(message, cause) {
118
+ super(message);
119
+ this.name = "CredenceNetworkError";
120
+ this.cause = cause;
121
+ }
122
+ };
123
+ var CredenceValidationError = class extends CredenceError {
124
+ field;
125
+ constructor(field, message) {
126
+ super(`Validation error on '${field}': ${message}`);
127
+ this.name = "CredenceValidationError";
128
+ this.field = field;
129
+ }
130
+ };
131
+
132
+ // src/http/retry.ts
133
+ var DEFAULT_RETRY_CONFIG = {
134
+ maxRetries: 3,
135
+ baseDelay: 1e3,
136
+ maxDelay: 3e4
137
+ };
138
+ var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 502, 503, 504]);
139
+ function isRetryable(status) {
140
+ return RETRYABLE_STATUS_CODES.has(status);
141
+ }
142
+ function calculateDelay(attempt, config) {
143
+ const exponentialDelay = config.baseDelay * Math.pow(2, attempt);
144
+ const cappedDelay = Math.min(exponentialDelay, config.maxDelay);
145
+ const jitter = cappedDelay * (0.5 + Math.random() * 0.5);
146
+ return Math.floor(jitter);
147
+ }
148
+ function sleep(ms) {
149
+ return new Promise((resolve) => setTimeout(resolve, ms));
150
+ }
151
+
152
+ // src/http/interceptors.ts
153
+ var InterceptorChain = class {
154
+ requestInterceptors = [];
155
+ responseInterceptors = [];
156
+ addRequestInterceptor(fn) {
157
+ this.requestInterceptors.push(fn);
158
+ }
159
+ addResponseInterceptor(fn) {
160
+ this.responseInterceptors.push(fn);
161
+ }
162
+ async onRequest(info) {
163
+ for (const interceptor of this.requestInterceptors) {
164
+ await interceptor(info);
165
+ }
166
+ }
167
+ async onResponse(info) {
168
+ for (const interceptor of this.responseInterceptors) {
169
+ await interceptor(info);
170
+ }
171
+ }
172
+ };
173
+
174
+ // src/http/http-client.ts
175
+ var HttpClient = class {
176
+ baseUrl;
177
+ token;
178
+ retryConfig;
179
+ timeout;
180
+ correlationId;
181
+ interceptors;
182
+ constructor(config) {
183
+ this.baseUrl = config.baseUrl.replace(/\/+$/, "");
184
+ this.token = config.token;
185
+ this.retryConfig = { ...DEFAULT_RETRY_CONFIG, ...config.retry };
186
+ this.timeout = config.timeout ?? 3e4;
187
+ this.correlationId = config.correlationId ?? generateCorrelationId();
188
+ this.interceptors = new InterceptorChain();
189
+ }
190
+ /** Updates the JWT token for subsequent requests. */
191
+ setToken(token) {
192
+ this.token = token;
193
+ }
194
+ addRequestInterceptor(fn) {
195
+ this.interceptors.addRequestInterceptor(fn);
196
+ }
197
+ addResponseInterceptor(fn) {
198
+ this.interceptors.addResponseInterceptor(fn);
199
+ }
200
+ /** Performs a GET request. */
201
+ async get(path, queryParams) {
202
+ const url = this.buildUrl(path, queryParams);
203
+ return this.executeWithRetry("GET", url);
204
+ }
205
+ /** Performs a POST request with JSON body. */
206
+ async post(path, body) {
207
+ const url = this.buildUrl(path);
208
+ return this.executeWithRetry("POST", url, body);
209
+ }
210
+ /** Performs a PUT request with JSON body. */
211
+ async put(path, body) {
212
+ const url = this.buildUrl(path);
213
+ return this.executeWithRetry("PUT", url, body);
214
+ }
215
+ /** Performs a DELETE request. Returns void. */
216
+ async delete(path) {
217
+ const url = this.buildUrl(path);
218
+ await this.executeWithRetry("DELETE", url);
219
+ }
220
+ /** Performs a POST with multipart/form-data (for evidence upload). */
221
+ async upload(path, formData) {
222
+ const url = this.buildUrl(path);
223
+ return this.executeWithRetry("POST", url, formData, true);
224
+ }
225
+ /** Performs a POST with application/x-www-form-urlencoded body. */
226
+ async postForm(path, body) {
227
+ const url = this.buildUrl(path);
228
+ return this.executeWithRetry("POST", url, body, false, "application/x-www-form-urlencoded");
229
+ }
230
+ /** Performs a POST with a custom Bearer token (not the SDK's JWT). */
231
+ async postWithToken(path, body, token) {
232
+ const url = this.buildUrl(path);
233
+ return this.executeWithRetry("POST", url, body, false, void 0, token);
234
+ }
235
+ buildUrl(path, queryParams) {
236
+ if (!this.baseUrl) {
237
+ if (!queryParams || Object.keys(queryParams).length === 0) {
238
+ return path;
239
+ }
240
+ const params = new URLSearchParams(queryParams).toString();
241
+ return `${path}?${params}`;
242
+ }
243
+ const url = new URL(path, this.baseUrl);
244
+ if (queryParams) {
245
+ for (const [key, value] of Object.entries(queryParams)) {
246
+ url.searchParams.set(key, value);
247
+ }
248
+ }
249
+ return url.toString();
250
+ }
251
+ async executeWithRetry(method, url, body, isMultipart = false, contentType, tokenOverride) {
252
+ let lastError;
253
+ for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {
254
+ try {
255
+ return await this.execute(method, url, body, isMultipart, contentType, tokenOverride);
256
+ } catch (error) {
257
+ lastError = error;
258
+ if (error instanceof CredenceApiError && isRetryable(error.status)) {
259
+ if (attempt < this.retryConfig.maxRetries) {
260
+ const delay = calculateDelay(attempt, this.retryConfig);
261
+ await sleep(delay);
262
+ continue;
263
+ }
264
+ }
265
+ throw error;
266
+ }
267
+ }
268
+ throw lastError;
269
+ }
270
+ async execute(method, url, body, isMultipart = false, contentType, tokenOverride) {
271
+ const headers = {
272
+ "Authorization": `Bearer ${tokenOverride ?? this.token}`,
273
+ "X-Correlation-ID": this.correlationId
274
+ };
275
+ if (!isMultipart && body !== void 0) {
276
+ headers["Content-Type"] = contentType ?? "application/json";
277
+ }
278
+ let path;
279
+ try {
280
+ path = new URL(url).pathname;
281
+ } catch {
282
+ path = url.split("?")[0] ?? url;
283
+ }
284
+ const sanitizedHeaders = { ...headers };
285
+ delete sanitizedHeaders["Authorization"];
286
+ await this.interceptors.onRequest({ method, url, headers: sanitizedHeaders });
287
+ const startTime = Date.now();
288
+ let response;
289
+ try {
290
+ const controller = new AbortController();
291
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
292
+ response = await fetch(url, {
293
+ method,
294
+ headers,
295
+ body: isMultipart ? body : typeof body === "string" ? body : body !== void 0 ? JSON.stringify(body) : void 0,
296
+ signal: controller.signal
297
+ });
298
+ clearTimeout(timeoutId);
299
+ } catch (error) {
300
+ const durationMs2 = Date.now() - startTime;
301
+ await this.interceptors.onResponse({ status: 0, url, correlationId: this.correlationId, durationMs: durationMs2 });
302
+ if (error instanceof DOMException && error.name === "AbortError") {
303
+ throw new CredenceNetworkError(`Request timeout after ${this.timeout}ms: ${method} ${path}`, error);
304
+ }
305
+ throw new CredenceNetworkError(`Network error: ${method} ${path}`, error);
306
+ }
307
+ const durationMs = Date.now() - startTime;
308
+ const responseCorrelationId = response.headers.get("X-Correlation-ID") ?? this.correlationId;
309
+ await this.interceptors.onResponse({
310
+ status: response.status,
311
+ url,
312
+ correlationId: responseCorrelationId,
313
+ durationMs
314
+ });
315
+ if (response.status === 204) {
316
+ return void 0;
317
+ }
318
+ if (!response.ok) {
319
+ await this.handleError(response, method, path, responseCorrelationId);
320
+ }
321
+ return await response.json();
322
+ }
323
+ async handleError(response, method, path, correlationId) {
324
+ let problemDetail = {};
325
+ try {
326
+ problemDetail = await response.json();
327
+ } catch {
328
+ }
329
+ const params = {
330
+ status: problemDetail.status ?? response.status,
331
+ title: problemDetail.title ?? response.statusText,
332
+ detail: problemDetail.detail,
333
+ type: problemDetail.type,
334
+ instance: problemDetail.instance,
335
+ correlationId,
336
+ method,
337
+ path
338
+ };
339
+ if (response.status === 401) {
340
+ throw new CredenceAuthError({ method, path, correlationId });
341
+ }
342
+ if (response.status === 403) {
343
+ throw new CredenceAuthorizationError({ method, path, correlationId, detail: problemDetail.detail });
344
+ }
345
+ throw new CredenceApiError(params);
346
+ }
347
+ };
348
+
349
+ // src/types/common.ts
350
+ function toQueryParams(params) {
351
+ if (!params) return {};
352
+ const result = {};
353
+ if (params.page !== void 0) result["page"] = String(params.page);
354
+ if (params.size !== void 0) result["size"] = String(params.size);
355
+ if (params.sort !== void 0) result["sort"] = params.sort;
356
+ return result;
357
+ }
358
+
359
+ // src/modules/identity.ts
360
+ var IdentityModule = class {
361
+ constructor(http) {
362
+ this.http = http;
363
+ }
364
+ // --- Authentication ---
365
+ /**
366
+ * Registers a new user. Creates a Credence tenant, ACA-Py sub-wallet, and bootstrap DID.
367
+ * Returns a JWT for immediate authenticated access. (SCF Phase 3a FR-1)
368
+ */
369
+ async register(request) {
370
+ return this.http.post("/api/v1/auth/register", request);
371
+ }
372
+ /**
373
+ * Authenticates with email and password. Returns a JWT with tenantId and roles.
374
+ * Returns 401 for invalid credentials, 429 if the account is locked. (SCF Phase 3a FR-2)
375
+ */
376
+ async login(request) {
377
+ return this.http.post("/api/v1/auth/login", request);
378
+ }
379
+ /**
380
+ * Initiates a password reset flow. A single-use reset token is generated
381
+ * (MVP: logged to server console, no email sent). (SCF Phase 3a FR-3)
382
+ */
383
+ async forgotPassword(request) {
384
+ await this.http.post("/api/v1/auth/forgot-password", request);
385
+ }
386
+ /**
387
+ * Resets a user's password using a single-use token. Token expires after 1 hour.
388
+ * Returns 400 for expired or already-used tokens. (SCF Phase 3a FR-3)
389
+ */
390
+ async resetPassword(request) {
391
+ await this.http.post("/api/v1/auth/reset-password", request);
392
+ }
393
+ /**
394
+ * Refreshes a JWT before expiry. Requires a valid (non-expired) JWT.
395
+ * Returns a fresh JWT with the same claims and a new expiry. (SCF Phase 3a FR-2)
396
+ */
397
+ async refresh() {
398
+ return this.http.post("/api/v1/auth/refresh", {});
399
+ }
400
+ // --- Tenant lifecycle ---
401
+ /** Creates a new tenant with ACA-Py sub-wallet provisioning. (FR-8) */
402
+ async createTenant(request) {
403
+ return this.http.post("/api/v1/tenants", request);
404
+ }
405
+ /** Retrieves tenant details by ID. (FR-9) */
406
+ async getTenant(id) {
407
+ return this.http.get(`/api/v1/tenants/${encodeURIComponent(id)}`);
408
+ }
409
+ /** Lists tenants with pagination. (FR-10) */
410
+ async listTenants(params) {
411
+ return this.http.get("/api/v1/tenants", toQueryParams(params));
412
+ }
413
+ // --- Citizen Registration ---
414
+ /**
415
+ * Registers a citizen (Individual tenant). Creates a tenant with type=INDIVIDUAL,
416
+ * ACA-Py sub-wallet, and bootstrap did:key. Returns JWT with tenantType=INDIVIDUAL.
417
+ *
418
+ * @example
419
+ * ```typescript
420
+ * const auth = await credence.identity.registerCitizen({
421
+ * name: 'Jane Doe',
422
+ * email: 'jane@example.com',
423
+ * password: 'SecurePass123!',
424
+ * phone: '+91-9876543210',
425
+ * });
426
+ * ```
427
+ */
428
+ async registerCitizen(request) {
429
+ return this.http.post("/api/v1/auth/register/citizen", request);
430
+ }
431
+ // --- FIDO2 / WebAuthn ---
432
+ /**
433
+ * Begins FIDO2 passkey registration. Returns challenge and options for the authenticator.
434
+ * Requires JWT authentication (user must be logged in first).
435
+ */
436
+ async fido2BeginRegistration() {
437
+ return this.http.post("/api/v1/auth/fido2/register/begin", {});
438
+ }
439
+ /**
440
+ * Completes FIDO2 passkey registration with the authenticator's response.
441
+ */
442
+ async fido2CompleteRegistration(response) {
443
+ await this.http.post("/api/v1/auth/fido2/register/complete", response);
444
+ }
445
+ /**
446
+ * Begins FIDO2 passkey login. Returns challenge and allowed credentials.
447
+ * Public endpoint — no JWT required.
448
+ */
449
+ async fido2BeginLogin(request) {
450
+ return this.http.post("/api/v1/auth/fido2/login/begin", request);
451
+ }
452
+ /**
453
+ * Completes FIDO2 passkey login. Returns JWT on success.
454
+ */
455
+ async fido2CompleteLogin(response) {
456
+ return this.http.post("/api/v1/auth/fido2/login/complete", response);
457
+ }
458
+ };
459
+
460
+ // src/modules/messaging.ts
461
+ var MessagingModule = class {
462
+ constructor(http) {
463
+ this.http = http;
464
+ }
465
+ /** Creates an OOB DIDComm invitation. (FR-11) */
466
+ async createInvitation(request) {
467
+ return this.http.post("/api/v1/connections/create-invitation", request ?? {});
468
+ }
469
+ /**
470
+ * Accepts an OOB DIDComm invitation from a DIA authority or anchor buyer.
471
+ * Parses the invitation URL and calls ACA-Py receive-invitation.
472
+ * Returns the new connection record. (SCF Phase 3a FR-5, FR-13)
473
+ */
474
+ async acceptInvitation(request) {
475
+ return this.http.post("/api/v1/connections/accept-invitation", request);
476
+ }
477
+ /** Retrieves a connection by ID (tenant-scoped). (FR-12) */
478
+ async getConnection(id) {
479
+ return this.http.get(`/api/v1/connections/${encodeURIComponent(id)}`);
480
+ }
481
+ /** Lists connections with pagination (tenant-scoped). (FR-13) */
482
+ async listConnections(params) {
483
+ return this.http.get("/api/v1/connections", toQueryParams(params));
484
+ }
485
+ };
486
+
487
+ // src/modules/credentials.ts
488
+ var CredentialsModule = class {
489
+ constructor(http) {
490
+ this.http = http;
491
+ }
492
+ /** Issues a verifiable credential. (FR-14) */
493
+ async issue(request) {
494
+ return this.http.post("/api/v1/credentials", request);
495
+ }
496
+ /** Retrieves credential details by ID (tenant-scoped). (FR-15) */
497
+ async get(id) {
498
+ return this.http.get(`/api/v1/credentials/${encodeURIComponent(id)}`);
499
+ }
500
+ /** Lists credentials with pagination (tenant-scoped). (FR-16) */
501
+ async list(params) {
502
+ return this.http.get("/api/v1/credentials", toQueryParams(params));
503
+ }
504
+ /** Revokes a credential by ID. (FR-17) */
505
+ async revoke(id) {
506
+ await this.http.post(`/api/v1/credentials/${encodeURIComponent(id)}/revoke`);
507
+ }
508
+ /** Verifies a credential using legacy 3-check. (FR-18) */
509
+ async verify(request) {
510
+ return this.http.post("/api/v1/credentials/verify", request);
511
+ }
512
+ /** Verifies a credential using 5-check policy engine. (FR-19) */
513
+ async verifyV2(request) {
514
+ return this.http.post("/api/v1/credentials/verify/v2", request);
515
+ }
516
+ };
517
+
518
+ // src/modules/presentations.ts
519
+ var PresentationsModule = class {
520
+ constructor(http) {
521
+ this.http = http;
522
+ }
523
+ /** Creates a presentation request (DIDComm or OID4VP). (FR-20) */
524
+ async createRequest(request) {
525
+ return this.http.post("/api/v1/presentations/request", request);
526
+ }
527
+ /** Retrieves a presentation exchange by ID (returns full detail). (FR-21) */
528
+ async get(id) {
529
+ return this.http.get(`/api/v1/presentations/${encodeURIComponent(id)}`);
530
+ }
531
+ /** Lists presentation exchanges with pagination (returns summaries). (FR-22) */
532
+ async list(params) {
533
+ return this.http.get("/api/v1/presentations", toQueryParams(params));
534
+ }
535
+ /**
536
+ * Verifies a received presentation using the 5-check engine. (FR-23)
537
+ *
538
+ * Returns the full PresentationDetailExchangeResponse with updated
539
+ * verificationContext containing the 5-check results.
540
+ */
541
+ async verify(id) {
542
+ return this.http.post(`/api/v1/presentations/${encodeURIComponent(id)}/verify`);
543
+ }
544
+ /** Generates an OID4VP authorization URL. (FR-24) */
545
+ async generateOid4vpUrl(request) {
546
+ const result = await this.http.post("/api/v1/presentations/oid4vp/authorize", request);
547
+ return result.authorizationUrl;
548
+ }
549
+ /**
550
+ * Checks issuance prerequisite status for a credential type on a connection/context.
551
+ *
552
+ * Returns whether governance-driven prerequisites (e.g., verified presentation)
553
+ * are met. This is a lightweight read-only check; full cryptographic re-verification
554
+ * happens at actual issuance time.
555
+ */
556
+ async getPrerequisiteStatus(credentialType, connectionId, contextId) {
557
+ return this.http.get(
558
+ "/api/v1/presentations/prerequisites/status",
559
+ {
560
+ credentialType,
561
+ connectionId,
562
+ contextId
563
+ }
564
+ );
565
+ }
566
+ };
567
+
568
+ // src/modules/registry-admin.ts
569
+ var RegistryAdminModule = class {
570
+ constructor(http) {
571
+ this.http = http;
572
+ }
573
+ /** Creates a trust framework in DRAFT state. (FR-36) */
574
+ async createFramework(request) {
575
+ return this.http.post("/api/v1/admin/governance/frameworks", request);
576
+ }
577
+ /** Updates framework metadata. (FR-37) */
578
+ async updateFramework(id, request) {
579
+ return this.http.put(`/api/v1/admin/governance/frameworks/${encodeURIComponent(id)}`, request);
580
+ }
581
+ /** Activates a framework. (FR-38) */
582
+ async activateFramework(id) {
583
+ return this.http.post(`/api/v1/admin/governance/frameworks/${encodeURIComponent(id)}/activate`);
584
+ }
585
+ /** Deprecates a framework. (FR-39) */
586
+ async deprecateFramework(id) {
587
+ return this.http.post(`/api/v1/admin/governance/frameworks/${encodeURIComponent(id)}/deprecate`);
588
+ }
589
+ /** Archives a framework. (FR-40) */
590
+ async archiveFramework(id) {
591
+ return this.http.post(`/api/v1/admin/governance/frameworks/${encodeURIComponent(id)}/archive`);
592
+ }
593
+ /** Registers a trusted issuer. (FR-41) */
594
+ async registerIssuer(request) {
595
+ return this.http.post("/api/v1/admin/issuers", request);
596
+ }
597
+ /** Lists issuers (admin view). (FR-42) */
598
+ async listIssuers() {
599
+ return this.http.get("/api/v1/admin/issuers");
600
+ }
601
+ /** Revokes issuer authorization. (FR-43) */
602
+ async revokeIssuer(id) {
603
+ await this.http.delete(`/api/v1/admin/issuers/${encodeURIComponent(id)}`);
604
+ }
605
+ /** Registers a credential schema. (FR-44) */
606
+ async registerSchema(request) {
607
+ return this.http.post("/api/v1/admin/schemas", request);
608
+ }
609
+ /** Registers a verifier policy. (FR-45) */
610
+ async registerPolicy(request) {
611
+ return this.http.post("/api/v1/admin/policies", request);
612
+ }
613
+ /** Creates a governance VC in DRAFT state. (FR-46) */
614
+ async createGovernanceVc(request) {
615
+ return this.http.post("/api/v1/admin/governance/vcs", request);
616
+ }
617
+ /** Submits governance VC for review. (FR-47) */
618
+ async submitForReview(id, request) {
619
+ return this.http.post(`/api/v1/admin/governance/vcs/${encodeURIComponent(id)}/submit-for-review`, request);
620
+ }
621
+ /** Activates a governance VC. (FR-48) */
622
+ async activateGovernanceVc(id, request) {
623
+ return this.http.post(`/api/v1/admin/governance/vcs/${encodeURIComponent(id)}/activate`, request);
624
+ }
625
+ /** Suspends a governance VC. (FR-49) */
626
+ async suspendGovernanceVc(id, request) {
627
+ return this.http.post(`/api/v1/admin/governance/vcs/${encodeURIComponent(id)}/suspend`, request);
628
+ }
629
+ /** Reinstates a governance VC from SUSPENDED to ACTIVE. (FR-50) */
630
+ async reinstateGovernanceVc(id, request) {
631
+ return this.http.post(`/api/v1/admin/governance/vcs/${encodeURIComponent(id)}/reinstate`, request);
632
+ }
633
+ /** Revokes a governance VC (terminal state). (FR-51) */
634
+ async revokeGovernanceVc(id, request) {
635
+ return this.http.post(`/api/v1/admin/governance/vcs/${encodeURIComponent(id)}/revoke`, request);
636
+ }
637
+ /** Records a Fabric anchor hash for a governance VC. (FR-52) */
638
+ async anchorGovernanceVc(id, request) {
639
+ return this.http.post(`/api/v1/admin/governance/vcs/${encodeURIComponent(id)}/anchor`, request);
640
+ }
641
+ };
642
+
643
+ // src/modules/registry.ts
644
+ var RegistryModule = class {
645
+ constructor(http) {
646
+ this.http = http;
647
+ this.admin = new RegistryAdminModule(http);
648
+ }
649
+ /** Admin sub-module for write operations (PLATFORM_ADMIN role required). */
650
+ admin;
651
+ /** Lists active trust frameworks. (FR-25) */
652
+ async listFrameworks() {
653
+ return this.http.get("/api/v1/registry/governance/frameworks");
654
+ }
655
+ /** Retrieves a framework by ID. (FR-26) */
656
+ async getFramework(id) {
657
+ return this.http.get(`/api/v1/registry/governance/frameworks/${encodeURIComponent(id)}`);
658
+ }
659
+ /** Finds frameworks associated with a DID. (FR-27) */
660
+ async findFrameworksByDid(did) {
661
+ return this.http.get("/api/v1/registry/governance/frameworks/by-did", { did });
662
+ }
663
+ /** Lists authorized issuers with optional filters. (FR-28) */
664
+ async listIssuers(params) {
665
+ const query = {};
666
+ if (params?.credentialType) query["credentialType"] = params.credentialType;
667
+ if (params?.frameworkId) query["frameworkId"] = params.frameworkId;
668
+ return this.http.get("/api/v1/registry/issuers", query);
669
+ }
670
+ /** Retrieves a registered schema. (FR-29) */
671
+ async getSchema(schemaId) {
672
+ return this.http.get(`/api/v1/registry/schemas/${encodeURIComponent(schemaId)}`);
673
+ }
674
+ /** Retrieves a verifier policy. (FR-30) */
675
+ async getPolicy(policyId) {
676
+ return this.http.get(`/api/v1/registry/policies/${encodeURIComponent(policyId)}`);
677
+ }
678
+ /** Lists governance VCs with pagination and filters. (FR-31) */
679
+ async listGovernanceVcs(params) {
680
+ const query = {};
681
+ if (params?.page !== void 0) query["page"] = String(params.page);
682
+ if (params?.size !== void 0) query["size"] = String(params.size);
683
+ if (params?.frameworkId) query["frameworkId"] = params.frameworkId;
684
+ if (params?.vcType) query["vcType"] = params.vcType;
685
+ if (params?.status) query["status"] = params.status;
686
+ if (params?.issuerDid) query["issuerDid"] = params.issuerDid;
687
+ if (params?.subjectDid) query["subjectDid"] = params.subjectDid;
688
+ return this.http.get("/api/v1/registry/governance/vcs", query);
689
+ }
690
+ /** Retrieves a governance VC by ID. (FR-32) */
691
+ async getGovernanceVc(id) {
692
+ return this.http.get(`/api/v1/registry/governance/vcs/${encodeURIComponent(id)}`);
693
+ }
694
+ /** Retrieves the raw W3C VC JSON-LD for a governance VC. (FR-33) */
695
+ async getGovernanceVcJson(id) {
696
+ return this.http.get(`/api/v1/registry/governance/vcs/${encodeURIComponent(id)}/vc-json`);
697
+ }
698
+ /** Retrieves audit trail for a governance VC. (FR-34) */
699
+ async getGovernanceVcAudit(id) {
700
+ return this.http.get(`/api/v1/registry/governance/vcs/${encodeURIComponent(id)}/audit`);
701
+ }
702
+ /** Retrieves a BitstringStatusList credential. (FR-35) */
703
+ async getStatusList(statusListId) {
704
+ return this.http.get(`/api/v1/registry/status/${encodeURIComponent(statusListId)}`);
705
+ }
706
+ };
707
+
708
+ // src/modules/compliance.ts
709
+ var ComplianceAdminModule = class {
710
+ constructor(http) {
711
+ this.http = http;
712
+ }
713
+ /** Creates a compliance rule. (FR-57) */
714
+ async createRule(request) {
715
+ return this.http.post("/api/v1/admin/compliance/rules", request);
716
+ }
717
+ /** Deactivates a compliance rule. (FR-58) */
718
+ async deactivateRule(id) {
719
+ await this.http.delete(`/api/v1/admin/compliance/rules/${encodeURIComponent(id)}`);
720
+ }
721
+ };
722
+ var ComplianceModule = class {
723
+ constructor(http) {
724
+ this.http = http;
725
+ this.admin = new ComplianceAdminModule(http);
726
+ }
727
+ /** Admin sub-module for rule management (PLATFORM_ADMIN role required). */
728
+ admin;
729
+ /** Evaluates compliance, returning ALLOW/DENY/INCOMPLETE. (FR-53) */
730
+ async check(request) {
731
+ return this.http.post("/api/v1/compliance/check", request);
732
+ }
733
+ /** Creates an audit event. (FR-54) */
734
+ async createAuditEvent(request) {
735
+ return this.http.post("/api/v1/compliance/audit", request);
736
+ }
737
+ /** Lists audit events with pagination. (FR-55) */
738
+ async listAuditEvents(params) {
739
+ return this.http.get("/api/v1/compliance/audit", toQueryParams(params));
740
+ }
741
+ /** Retrieves a specific audit event. (FR-56) */
742
+ async getAuditEvent(id) {
743
+ return this.http.get(`/api/v1/compliance/audit/${encodeURIComponent(id)}`);
744
+ }
745
+ };
746
+
747
+ // src/modules/evidence.ts
748
+ var EvidenceModule = class {
749
+ constructor(http) {
750
+ this.http = http;
751
+ }
752
+ /** Uploads evidence as multipart/form-data. (FR-59) */
753
+ async upload(formData) {
754
+ return this.http.upload("/api/v1/evidence", formData);
755
+ }
756
+ /** Retrieves evidence metadata by ID. (FR-60) */
757
+ async get(id) {
758
+ return this.http.get(`/api/v1/evidence/${encodeURIComponent(id)}`);
759
+ }
760
+ /** Downloads evidence file content. (FR-61) */
761
+ async download(id) {
762
+ const response = await this.http.get(`/api/v1/evidence/${encodeURIComponent(id)}/content`);
763
+ return Buffer.from(response);
764
+ }
765
+ /** Lists evidence with pagination and filters. (FR-62) */
766
+ async list(params) {
767
+ const query = {};
768
+ if (params?.page !== void 0) query["page"] = String(params.page);
769
+ if (params?.size !== void 0) query["size"] = String(params.size);
770
+ if (params?.type) query["type"] = params.type;
771
+ if (params?.status) query["status"] = params.status;
772
+ return this.http.get("/api/v1/evidence", query);
773
+ }
774
+ /**
775
+ * Lists all evidence artifacts linked to a specific credential (reverse lookup).
776
+ *
777
+ * @param credentialId the credential ID to find linked evidence for
778
+ * @returns list of evidence summaries linked to the credential
779
+ */
780
+ async listByCredential(credentialId) {
781
+ return this.http.get(
782
+ `/api/v1/evidence/by-credential/${encodeURIComponent(credentialId)}`
783
+ );
784
+ }
785
+ /** Verifies evidence integrity (SHA-256 hash match). (FR-63) */
786
+ async verify(id) {
787
+ return this.http.post(`/api/v1/evidence/${encodeURIComponent(id)}/verify`);
788
+ }
789
+ /** Links a credential ID to an evidence record. (FR-64) */
790
+ async link(id, credentialId) {
791
+ await this.http.post(`/api/v1/evidence/${encodeURIComponent(id)}/link`, { credentialId });
792
+ }
793
+ /** Soft-deletes an evidence record. (FR-65) */
794
+ async delete(id) {
795
+ await this.http.delete(`/api/v1/evidence/${encodeURIComponent(id)}`);
796
+ }
797
+ /**
798
+ * Shares evidence over DIDComm to a connected peer.
799
+ *
800
+ * Issues an EvidenceSharingAttestation governance VC for provenance,
801
+ * then sends the evidence metadata via DIDComm basic message.
802
+ *
803
+ * @param evidenceId the evidence UUID to share
804
+ * @param request sharing parameters (connectionId, credentialId, etc.)
805
+ */
806
+ async share(evidenceId, request) {
807
+ await this.http.post(
808
+ `/api/v1/evidence/${encodeURIComponent(evidenceId)}/share`,
809
+ request
810
+ );
811
+ }
812
+ };
813
+
814
+ // src/modules/vdr.ts
815
+ var VdrModule = class {
816
+ constructor(http) {
817
+ this.http = http;
818
+ }
819
+ /** Writes a schema to the Indy VDR. (FR-66) */
820
+ async writeSchema(request) {
821
+ return this.http.post("/api/vdr/schemas", request);
822
+ }
823
+ /** Lists all registered schemas (merged ACA-Py + local). (FR-67) */
824
+ async listSchemas() {
825
+ return this.http.get("/api/vdr/schemas");
826
+ }
827
+ /** Retrieves a schema by ID. (FR-68) */
828
+ async getSchema(schemaId) {
829
+ return this.http.get(`/api/vdr/schemas/${encodeURIComponent(schemaId)}`);
830
+ }
831
+ /** Retrieves a schema using URL-safe query param. (FR-69) */
832
+ async lookupSchema(schemaId) {
833
+ return this.http.get("/api/vdr/schemas/lookup", { id: schemaId });
834
+ }
835
+ /** Writes a credential definition to Indy VDR. (FR-70) */
836
+ async writeCredentialDefinition(request) {
837
+ return this.http.post("/api/vdr/credential-definitions", request);
838
+ }
839
+ /** Lists all credential definitions. (FR-71) */
840
+ async listCredentialDefinitions() {
841
+ return this.http.get("/api/vdr/credential-definitions");
842
+ }
843
+ /** Retrieves a credential definition by ID. (FR-72) */
844
+ async getCredentialDefinition(credDefId) {
845
+ return this.http.get(`/api/vdr/credential-definitions/${encodeURIComponent(credDefId)}`);
846
+ }
847
+ /** Retrieves a credential definition using URL-safe query param. (FR-73) */
848
+ async lookupCredentialDefinition(credDefId) {
849
+ return this.http.get("/api/vdr/credential-definitions/lookup", { id: credDefId });
850
+ }
851
+ /** Writes a NYM transaction to Indy ledger. (FR-74) */
852
+ async writeNym(request) {
853
+ return this.http.post("/api/vdr/nyms", request);
854
+ }
855
+ /** Lists wallet DIDs (merged ACA-Py + local). (FR-75) */
856
+ async listNyms() {
857
+ return this.http.get("/api/vdr/nyms");
858
+ }
859
+ /** Resolves a NYM by DID. (FR-76) */
860
+ async resolveNym(did) {
861
+ return this.http.get(`/api/vdr/nyms/${encodeURIComponent(did)}`);
862
+ }
863
+ /** Creates a revocation registry. (FR-77) */
864
+ async createRevocationRegistry(request) {
865
+ return this.http.post("/api/vdr/revocation/registries", request);
866
+ }
867
+ /** Lists all revocation registries. (FR-78) */
868
+ async listRevocationRegistries() {
869
+ return this.http.get("/api/vdr/revocation/registries");
870
+ }
871
+ /** Retrieves a revocation registry. (FR-79) */
872
+ async getRevocationRegistry(revRegId) {
873
+ return this.http.get(`/api/vdr/revocation/registries/${encodeURIComponent(revRegId)}`);
874
+ }
875
+ /** Retrieves the revocation delta. (FR-80) */
876
+ async getRevocationDelta(revRegId) {
877
+ return this.http.get(`/api/vdr/revocation/registries/${encodeURIComponent(revRegId)}/delta`);
878
+ }
879
+ /** Publishes pending revocations to ledger. (FR-81) */
880
+ async publishRevocations() {
881
+ return this.http.post("/api/vdr/revocation/publish");
882
+ }
883
+ };
884
+
885
+ // src/modules/oid4vci.ts
886
+ var Oid4vciModule = class {
887
+ constructor(http) {
888
+ this.http = http;
889
+ }
890
+ /**
891
+ * Fetches the issuer metadata from the well-known endpoint.
892
+ * Public endpoint — no authentication required.
893
+ */
894
+ async getIssuerMetadata() {
895
+ return this.http.get("/.well-known/openid-credential-issuer");
896
+ }
897
+ /**
898
+ * Fetches the issuer's JSON Web Key Set (public keys for signature verification).
899
+ * Public endpoint — no authentication required.
900
+ */
901
+ async getJwks() {
902
+ return this.http.get("/.well-known/jwks.json");
903
+ }
904
+ /**
905
+ * Creates a credential offer for wallet scanning.
906
+ * Returns an offer URI suitable for QR code generation.
907
+ * Requires JWT authentication (issuer role).
908
+ *
909
+ * @example
910
+ * ```typescript
911
+ * const offer = await credence.oid4vci.createOffer({
912
+ * credentialType: 'KycCredential',
913
+ * claims: { name: 'Jane Doe', kycLevel: 'HIGH' },
914
+ * selectiveDisclosureClaims: ['name'],
915
+ * });
916
+ * // Display offer.credentialOfferUri as QR code
917
+ * ```
918
+ */
919
+ async createOffer(request) {
920
+ return this.http.post("/api/v1/oid4vci/offers", request);
921
+ }
922
+ /**
923
+ * Exchanges a pre-authorized code for an access token.
924
+ * Public endpoint — called by the wallet after scanning the QR code.
925
+ *
926
+ * Note: This sends as application/x-www-form-urlencoded per OAuth2 spec.
927
+ */
928
+ async exchangeToken(preAuthorizedCode) {
929
+ const body = new URLSearchParams({
930
+ grant_type: "urn:ietf:params:oauth:grant-type:pre-authorized_code",
931
+ "pre-authorized_code": preAuthorizedCode
932
+ });
933
+ return this.http.postForm("/api/v1/oid4vci/token", body.toString());
934
+ }
935
+ /**
936
+ * Issues a credential using the access token from token exchange.
937
+ * Called by the wallet with the access token as Bearer authentication.
938
+ *
939
+ * @param accessToken - The access token from exchangeToken()
940
+ * @param request - Credential request with format and optional proof
941
+ */
942
+ async issueCredential(accessToken, request) {
943
+ return this.http.postWithToken(
944
+ "/api/v1/oid4vci/credential",
945
+ request,
946
+ accessToken
947
+ );
948
+ }
949
+ };
950
+
951
+ // src/modules/payment.ts
952
+ var PaymentModule = class {
953
+ constructor(http) {
954
+ this.http = http;
955
+ }
956
+ /**
957
+ * Creates a new payment.
958
+ *
959
+ * @example
960
+ * ```typescript
961
+ * const payment = await credence.payments.create({
962
+ * amount: 50000,
963
+ * currency: 'INR',
964
+ * payerDid: 'did:key:z6Mk...',
965
+ * payeeDid: 'did:key:z6Mn...',
966
+ * contextId: 'credential-abc-123',
967
+ * });
968
+ * ```
969
+ */
970
+ async create(request) {
971
+ return this.http.post("/api/v1/payments", request);
972
+ }
973
+ /**
974
+ * Gets a payment by ID.
975
+ */
976
+ async get(paymentId) {
977
+ return this.http.get(`/api/v1/payments/${paymentId}`);
978
+ }
979
+ /**
980
+ * Lists payments with pagination. Tenant-scoped.
981
+ */
982
+ async list(params) {
983
+ const query = params ? `?${toQueryParams(params)}` : "";
984
+ return this.http.get(`/api/v1/payments${query}`);
985
+ }
986
+ /**
987
+ * Requests a refund for a completed payment.
988
+ */
989
+ async refund(paymentId) {
990
+ return this.http.post(`/api/v1/payments/${paymentId}/refund`, {});
991
+ }
992
+ };
993
+
994
+ // src/client.ts
995
+ var CredenceClient = class {
996
+ http;
997
+ /** Tenant and DID lifecycle management. */
998
+ identity;
999
+ /** DIDComm connections and invitations. */
1000
+ messaging;
1001
+ /** VC issuance, verification, and revocation. */
1002
+ credentials;
1003
+ /** Presentation exchange and OID4VP. */
1004
+ presentations;
1005
+ /** Trust Registry TRQP queries + admin write operations. */
1006
+ registry;
1007
+ /** Compliance checks and audit events. */
1008
+ compliance;
1009
+ /** IPFS evidence upload, retrieval, and verification. */
1010
+ evidence;
1011
+ /** Indy VDR operations: schemas, credential definitions, NYMs, revocation. */
1012
+ vdr;
1013
+ /** OID4VCI credential issuance to wallets (SD-JWT VCs). */
1014
+ oid4vci;
1015
+ /** Payment lifecycle management (HatchPay integration). */
1016
+ payments;
1017
+ constructor(config) {
1018
+ const httpConfig = {
1019
+ baseUrl: config.baseUrl,
1020
+ token: config.auth.token,
1021
+ retry: config.retry,
1022
+ timeout: config.timeout,
1023
+ correlationId: config.correlationId
1024
+ };
1025
+ this.http = new HttpClient(httpConfig);
1026
+ this.identity = new IdentityModule(this.http);
1027
+ this.messaging = new MessagingModule(this.http);
1028
+ this.credentials = new CredentialsModule(this.http);
1029
+ this.presentations = new PresentationsModule(this.http);
1030
+ this.registry = new RegistryModule(this.http);
1031
+ this.compliance = new ComplianceModule(this.http);
1032
+ this.evidence = new EvidenceModule(this.http);
1033
+ this.vdr = new VdrModule(this.http);
1034
+ this.oid4vci = new Oid4vciModule(this.http);
1035
+ this.payments = new PaymentModule(this.http);
1036
+ }
1037
+ /** Updates the JWT token for all subsequent requests. */
1038
+ setToken(token) {
1039
+ this.http.setToken(token);
1040
+ }
1041
+ /** Adds a request interceptor for logging or telemetry. */
1042
+ addRequestInterceptor(fn) {
1043
+ this.http.addRequestInterceptor(fn);
1044
+ }
1045
+ /** Adds a response interceptor for logging or telemetry. */
1046
+ addResponseInterceptor(fn) {
1047
+ this.http.addResponseInterceptor(fn);
1048
+ }
1049
+ };
1050
+
1051
+ // src/validation.ts
1052
+ var DID_PATTERN = /^did:(key|peer|indy|web):[a-zA-Z0-9._:%-]+$/;
1053
+ var KEY_MATERIAL_PATTERNS = [
1054
+ /^-----BEGIN\s+(RSA\s+)?(PRIVATE|PUBLIC)\s+KEY-----/,
1055
+ /^\{"kty":/,
1056
+ /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{43,}$/
1057
+ ];
1058
+ function validateDid(field, value) {
1059
+ if (!DID_PATTERN.test(value)) {
1060
+ throw new CredenceValidationError(
1061
+ field,
1062
+ `Invalid DID format or unsupported method. Supported: did:key, did:peer, did:indy, did:web. Got: ${value.substring(0, 30)}`
1063
+ );
1064
+ }
1065
+ }
1066
+ function validateRequired(field, value) {
1067
+ if (value === null || value === void 0 || typeof value === "string" && value.trim() === "") {
1068
+ throw new CredenceValidationError(field, "Required field is missing or empty");
1069
+ }
1070
+ }
1071
+ function isKeyMaterial(value) {
1072
+ return KEY_MATERIAL_PATTERNS.some((pattern) => pattern.test(value));
1073
+ }
1074
+ function rejectKeyMaterial(fields) {
1075
+ for (const [key, value] of Object.entries(fields)) {
1076
+ if (typeof value === "string" && isKeyMaterial(value)) {
1077
+ throw new CredenceValidationError(
1078
+ key,
1079
+ "Field appears to contain key material (private key, JWK, or base58 key). SDK must not transmit key material."
1080
+ );
1081
+ }
1082
+ }
1083
+ }
1084
+ // Annotate the CommonJS export names for ESM import in node:
1085
+ 0 && (module.exports = {
1086
+ ComplianceModule,
1087
+ CredenceApiError,
1088
+ CredenceAuthError,
1089
+ CredenceAuthorizationError,
1090
+ CredenceClient,
1091
+ CredenceError,
1092
+ CredenceNetworkError,
1093
+ CredenceValidationError,
1094
+ CredentialsModule,
1095
+ DEFAULT_RETRY_CONFIG,
1096
+ EvidenceModule,
1097
+ HttpClient,
1098
+ IdentityModule,
1099
+ MessagingModule,
1100
+ Oid4vciModule,
1101
+ PaymentModule,
1102
+ PresentationsModule,
1103
+ RegistryAdminModule,
1104
+ RegistryModule,
1105
+ VdrModule,
1106
+ isKeyMaterial,
1107
+ rejectKeyMaterial,
1108
+ toQueryParams,
1109
+ validateDid,
1110
+ validateRequired
1111
+ });
1112
+ //# sourceMappingURL=index.cjs.map