@bind-protocol/sdk 0.2.0 → 0.3.0

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 (38) hide show
  1. package/README.md +1 -0
  2. package/dist/{index-CASjN9Qe.d.ts → adapter-53dB8ogG.d.ts} +3 -67
  3. package/dist/{index-5j-fuebC.d.cts → adapter-DyAYLtIy.d.cts} +3 -67
  4. package/dist/adapters/dimo/index.d.cts +3 -2
  5. package/dist/adapters/dimo/index.d.ts +3 -2
  6. package/dist/adapters/index.cjs +499 -0
  7. package/dist/adapters/index.cjs.map +1 -1
  8. package/dist/adapters/index.d.cts +6 -2
  9. package/dist/adapters/index.d.ts +6 -2
  10. package/dist/adapters/index.js +497 -1
  11. package/dist/adapters/index.js.map +1 -1
  12. package/dist/adapters/zktls/index.cjs +503 -0
  13. package/dist/adapters/zktls/index.cjs.map +1 -0
  14. package/dist/adapters/zktls/index.d.cts +117 -0
  15. package/dist/adapters/zktls/index.d.ts +117 -0
  16. package/dist/adapters/zktls/index.js +499 -0
  17. package/dist/adapters/zktls/index.js.map +1 -0
  18. package/dist/client-BSwO4sTC.d.ts +135 -0
  19. package/dist/client-Bh8Di-5n.d.cts +135 -0
  20. package/dist/core/index.cjs +162 -1
  21. package/dist/core/index.cjs.map +1 -1
  22. package/dist/core/index.d.cts +25 -61
  23. package/dist/core/index.d.ts +25 -61
  24. package/dist/core/index.js +159 -2
  25. package/dist/core/index.js.map +1 -1
  26. package/dist/index.cjs +310 -1
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +6 -3
  29. package/dist/index.d.ts +6 -3
  30. package/dist/index.js +305 -2
  31. package/dist/index.js.map +1 -1
  32. package/dist/types-B6S0axfE.d.cts +200 -0
  33. package/dist/types-B6S0axfE.d.ts +200 -0
  34. package/dist/types-Be7Jc5V8.d.cts +68 -0
  35. package/dist/types-D1-qiyJO.d.ts +68 -0
  36. package/package.json +10 -2
  37. package/dist/types-o4sbOK_a.d.cts +0 -101
  38. package/dist/types-o4sbOK_a.d.ts +0 -101
package/README.md CHANGED
@@ -307,3 +307,4 @@ MIT
307
307
  - [Bind Protocol](https://bindprotocol.com)
308
308
  - [Documentation](https://docs.bindprotocol.com)
309
309
  - [DIMO Network](https://dimo.zone)
310
+ # sdk
@@ -1,69 +1,5 @@
1
- import { a as ProveJobInputs } from './types-o4sbOK_a.js';
2
-
3
- /**
4
- * Base types for data source adapters
5
- *
6
- * Adapters abstract away the data source specifics and provide a uniform
7
- * interface for fetching data that can be used as circuit inputs.
8
- */
9
-
10
- /**
11
- * Base interface for all data source adapters
12
- * Each adapter knows how to fetch data from a specific source
13
- * and transform it into circuit inputs.
14
- */
15
- interface DataAdapter<TConfig = unknown, TQuery = unknown, TData = unknown> {
16
- /** Unique identifier for this adapter */
17
- readonly id: string;
18
- /** Human-readable name */
19
- readonly name: string;
20
- /** Description of what data source this adapter connects to */
21
- readonly description: string;
22
- /**
23
- * Fetch raw data from the data source
24
- * @param query - Adapter-specific query parameters
25
- * @returns Raw data from the source
26
- */
27
- fetchData(query: TQuery): Promise<TData>;
28
- /**
29
- * Transform raw data into circuit inputs
30
- * @param data - Raw data from fetchData
31
- * @param circuitId - Target circuit ID (adapters may support multiple circuits)
32
- * @returns Inputs ready for prove job submission
33
- */
34
- toCircuitInputs(data: TData, circuitId: string): ProveJobInputs;
35
- }
36
- /**
37
- * Adapter registration entry
38
- */
39
- interface AdapterRegistration<TConfig = unknown> {
40
- /** Adapter factory function */
41
- create: (config: TConfig) => DataAdapter;
42
- /** Default configuration */
43
- defaultConfig?: Partial<TConfig>;
44
- /** Supported circuit IDs */
45
- supportedCircuits: string[];
46
- }
47
- /**
48
- * Common telemetry data structure that adapters can transform their data into
49
- */
50
- interface TelemetryData {
51
- /** Array of telemetry signal readings */
52
- signals: TelemetrySignal[];
53
- /** Timestamp of the data collection period start */
54
- periodStart: string;
55
- /** Timestamp of the data collection period end */
56
- periodEnd: string;
57
- /** Subject identifier (e.g., vehicle ID) */
58
- subjectId: string;
59
- }
60
- /**
61
- * Individual telemetry signal reading
62
- */
63
- interface TelemetrySignal {
64
- timestamp: string;
65
- [key: string]: string | number | boolean | string[] | null;
66
- }
1
+ import { D as DataAdapter } from './types-D1-qiyJO.js';
2
+ import { a as ProveJobInputs } from './types-B6S0axfE.js';
67
3
 
68
4
  /**
69
5
  * DIMO Adapter Types
@@ -152,4 +88,4 @@ declare class DimoAdapter implements DataAdapter<DimoAdapterConfig, DimoQuery, D
152
88
  */
153
89
  declare function createDimoAdapter(config: DimoAdapterConfig): DimoAdapter;
154
90
 
155
- export { type AdapterRegistration as A, DimoAdapter as D, type TelemetryData as T, type DimoAdapterConfig as a, type DimoQuery as b, createDimoAdapter as c, type DimoTelemetryData as d, type DimoSignal as e, type DimoClient as f, type DataAdapter as g, type TelemetrySignal as h };
91
+ export { DimoAdapter as D, type DimoAdapterConfig as a, type DimoQuery as b, createDimoAdapter as c, type DimoTelemetryData as d, type DimoSignal as e, type DimoClient as f };
@@ -1,69 +1,5 @@
1
- import { a as ProveJobInputs } from './types-o4sbOK_a.cjs';
2
-
3
- /**
4
- * Base types for data source adapters
5
- *
6
- * Adapters abstract away the data source specifics and provide a uniform
7
- * interface for fetching data that can be used as circuit inputs.
8
- */
9
-
10
- /**
11
- * Base interface for all data source adapters
12
- * Each adapter knows how to fetch data from a specific source
13
- * and transform it into circuit inputs.
14
- */
15
- interface DataAdapter<TConfig = unknown, TQuery = unknown, TData = unknown> {
16
- /** Unique identifier for this adapter */
17
- readonly id: string;
18
- /** Human-readable name */
19
- readonly name: string;
20
- /** Description of what data source this adapter connects to */
21
- readonly description: string;
22
- /**
23
- * Fetch raw data from the data source
24
- * @param query - Adapter-specific query parameters
25
- * @returns Raw data from the source
26
- */
27
- fetchData(query: TQuery): Promise<TData>;
28
- /**
29
- * Transform raw data into circuit inputs
30
- * @param data - Raw data from fetchData
31
- * @param circuitId - Target circuit ID (adapters may support multiple circuits)
32
- * @returns Inputs ready for prove job submission
33
- */
34
- toCircuitInputs(data: TData, circuitId: string): ProveJobInputs;
35
- }
36
- /**
37
- * Adapter registration entry
38
- */
39
- interface AdapterRegistration<TConfig = unknown> {
40
- /** Adapter factory function */
41
- create: (config: TConfig) => DataAdapter;
42
- /** Default configuration */
43
- defaultConfig?: Partial<TConfig>;
44
- /** Supported circuit IDs */
45
- supportedCircuits: string[];
46
- }
47
- /**
48
- * Common telemetry data structure that adapters can transform their data into
49
- */
50
- interface TelemetryData {
51
- /** Array of telemetry signal readings */
52
- signals: TelemetrySignal[];
53
- /** Timestamp of the data collection period start */
54
- periodStart: string;
55
- /** Timestamp of the data collection period end */
56
- periodEnd: string;
57
- /** Subject identifier (e.g., vehicle ID) */
58
- subjectId: string;
59
- }
60
- /**
61
- * Individual telemetry signal reading
62
- */
63
- interface TelemetrySignal {
64
- timestamp: string;
65
- [key: string]: string | number | boolean | string[] | null;
66
- }
1
+ import { D as DataAdapter } from './types-Be7Jc5V8.cjs';
2
+ import { a as ProveJobInputs } from './types-B6S0axfE.cjs';
67
3
 
68
4
  /**
69
5
  * DIMO Adapter Types
@@ -152,4 +88,4 @@ declare class DimoAdapter implements DataAdapter<DimoAdapterConfig, DimoQuery, D
152
88
  */
153
89
  declare function createDimoAdapter(config: DimoAdapterConfig): DimoAdapter;
154
90
 
155
- export { type AdapterRegistration as A, DimoAdapter as D, type TelemetryData as T, type DimoAdapterConfig as a, type DimoQuery as b, createDimoAdapter as c, type DimoTelemetryData as d, type DimoSignal as e, type DimoClient as f, type DataAdapter as g, type TelemetrySignal as h };
91
+ export { DimoAdapter as D, type DimoAdapterConfig as a, type DimoQuery as b, createDimoAdapter as c, type DimoTelemetryData as d, type DimoSignal as e, type DimoClient as f };
@@ -1,5 +1,6 @@
1
- export { D as DimoAdapter, a as DimoAdapterConfig, f as DimoClient, b as DimoQuery, e as DimoSignal, d as DimoTelemetryData, c as createDimoAdapter } from '../../index-5j-fuebC.cjs';
2
- import '../../types-o4sbOK_a.cjs';
1
+ export { D as DimoAdapter, a as DimoAdapterConfig, f as DimoClient, b as DimoQuery, e as DimoSignal, d as DimoTelemetryData, c as createDimoAdapter } from '../../adapter-DyAYLtIy.cjs';
2
+ import '../../types-Be7Jc5V8.cjs';
3
+ import '../../types-B6S0axfE.cjs';
3
4
 
4
5
  /**
5
6
  * DIMO GraphQL query builders
@@ -1,5 +1,6 @@
1
- export { D as DimoAdapter, a as DimoAdapterConfig, f as DimoClient, b as DimoQuery, e as DimoSignal, d as DimoTelemetryData, c as createDimoAdapter } from '../../index-CASjN9Qe.js';
2
- import '../../types-o4sbOK_a.js';
1
+ export { D as DimoAdapter, a as DimoAdapterConfig, f as DimoClient, b as DimoQuery, e as DimoSignal, d as DimoTelemetryData, c as createDimoAdapter } from '../../adapter-53dB8ogG.js';
2
+ import '../../types-D1-qiyJO.js';
3
+ import '../../types-B6S0axfE.js';
3
4
 
4
5
  /**
5
6
  * DIMO GraphQL query builders
@@ -78,6 +78,505 @@ var DimoAdapter = class {
78
78
  }
79
79
  };
80
80
 
81
+ // src/core/errors.ts
82
+ var BindError = class extends Error {
83
+ constructor(message, code, details) {
84
+ super(message);
85
+ this.code = code;
86
+ this.details = details;
87
+ this.name = "BindError";
88
+ }
89
+ };
90
+ var ApiError = class extends BindError {
91
+ constructor(message, status, response) {
92
+ super(message, "API_ERROR", { status, response });
93
+ this.status = status;
94
+ this.response = response;
95
+ this.name = "ApiError";
96
+ }
97
+ };
98
+ var AuthenticationError = class extends BindError {
99
+ constructor(message = "Authentication failed") {
100
+ super(message, "AUTH_ERROR");
101
+ this.name = "AuthenticationError";
102
+ }
103
+ };
104
+ var TimeoutError = class extends BindError {
105
+ constructor(message, timeoutMs) {
106
+ super(message, "TIMEOUT_ERROR", { timeoutMs });
107
+ this.timeoutMs = timeoutMs;
108
+ this.name = "TimeoutError";
109
+ }
110
+ };
111
+ var InsufficientCreditsError = class extends BindError {
112
+ constructor(required, available) {
113
+ super(
114
+ `Insufficient credits: need ${required}, have ${available}`,
115
+ "INSUFFICIENT_CREDITS",
116
+ { required, available }
117
+ );
118
+ this.required = required;
119
+ this.available = available;
120
+ this.name = "InsufficientCreditsError";
121
+ }
122
+ };
123
+ var ZkTlsSessionExpiredError = class extends BindError {
124
+ constructor(sessionId) {
125
+ super(`zkTLS session expired: ${sessionId}`, "ZKTLS_SESSION_EXPIRED", { sessionId });
126
+ this.sessionId = sessionId;
127
+ this.name = "ZkTlsSessionExpiredError";
128
+ }
129
+ };
130
+ var ZkTlsSessionFailedError = class extends BindError {
131
+ constructor(sessionId, sessionError) {
132
+ super(`zkTLS session failed: ${sessionError}`, "ZKTLS_SESSION_FAILED", { sessionId, sessionError });
133
+ this.sessionId = sessionId;
134
+ this.sessionError = sessionError;
135
+ this.name = "ZkTlsSessionFailedError";
136
+ }
137
+ };
138
+
139
+ // src/core/client.ts
140
+ var DEFAULT_BASE_URL = "https://api.bindprotocol.com";
141
+ var DEFAULT_POLL_INTERVAL_MS = 2e3;
142
+ var DEFAULT_TIMEOUT_MS = 3e5;
143
+ var BindClient = class {
144
+ apiKey;
145
+ baseUrl;
146
+ headers;
147
+ constructor(options) {
148
+ this.apiKey = options.apiKey;
149
+ this.baseUrl = options.baseUrl || process.env.BIND_API_URL || DEFAULT_BASE_URL;
150
+ this.headers = {
151
+ "X-API-Key": this.apiKey,
152
+ "Content-Type": "application/json"
153
+ };
154
+ }
155
+ // ==========================================================================
156
+ // Prove Job Methods
157
+ // ==========================================================================
158
+ /**
159
+ * Submit a prove job for async processing
160
+ * @param circuitId - The circuit identifier (e.g., "bind.mobility.riskband.v1")
161
+ * @param inputs - Circuit inputs as key-value pairs (all values must be strings)
162
+ * @returns The submitted job details
163
+ * @throws {ApiError} If the API request fails
164
+ * @throws {InsufficientCreditsError} If there aren't enough credits
165
+ */
166
+ async submitProveJob(circuitId, inputs) {
167
+ const response = await this.fetch("/api/prove", {
168
+ method: "POST",
169
+ body: JSON.stringify({ circuitId, inputs })
170
+ });
171
+ const result = await response.json();
172
+ if (!result.success && result.requiredCredits !== void 0 && result.availableCredits !== void 0) {
173
+ throw new InsufficientCreditsError(result.requiredCredits, result.availableCredits);
174
+ }
175
+ return result;
176
+ }
177
+ /**
178
+ * Get the status and results of a prove job
179
+ * @param jobId - The unique job identifier
180
+ * @returns The job details including status and outputs
181
+ */
182
+ async getProveJob(jobId) {
183
+ const response = await this.fetch(`/api/prove/${encodeURIComponent(jobId)}`);
184
+ return response.json();
185
+ }
186
+ /**
187
+ * List prove jobs for the authenticated organization
188
+ * @param options - Optional filters for status, limit, and offset
189
+ * @returns Paginated list of prove jobs
190
+ */
191
+ async listProveJobs(options = {}) {
192
+ const params = new URLSearchParams();
193
+ if (options.status) params.set("status", options.status);
194
+ if (options.limit !== void 0) params.set("limit", options.limit.toString());
195
+ if (options.offset !== void 0) params.set("offset", options.offset.toString());
196
+ const queryString = params.toString();
197
+ const path = queryString ? `/api/prove?${queryString}` : "/api/prove";
198
+ const response = await this.fetch(path);
199
+ return response.json();
200
+ }
201
+ /**
202
+ * Poll for prove job completion
203
+ * @param jobId - The unique job identifier
204
+ * @param options - Polling options
205
+ * @returns The completed or failed job
206
+ * @throws {TimeoutError} If the job doesn't complete within the timeout
207
+ */
208
+ async waitForProveJob(jobId, options = {}) {
209
+ const intervalMs = options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
210
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
211
+ const startTime = Date.now();
212
+ while (Date.now() - startTime < timeoutMs) {
213
+ const result = await this.getProveJob(jobId);
214
+ if (!result.success || !result.data) {
215
+ throw new ApiError(
216
+ result.error || "Failed to get prove job",
217
+ 500,
218
+ result
219
+ );
220
+ }
221
+ const job = result.data;
222
+ if (options.onProgress) {
223
+ options.onProgress(job);
224
+ }
225
+ if (job.status === "completed" || job.status === "failed") {
226
+ return job;
227
+ }
228
+ await this.sleep(intervalMs);
229
+ }
230
+ throw new TimeoutError(
231
+ `Timeout waiting for prove job ${jobId} after ${timeoutMs}ms`,
232
+ timeoutMs
233
+ );
234
+ }
235
+ // ==========================================================================
236
+ // Policy Methods (Public, no authentication required)
237
+ // ==========================================================================
238
+ /**
239
+ * List all available public policies
240
+ * @returns Array of public policy specifications
241
+ */
242
+ async listPolicies() {
243
+ const response = await fetch(`${this.baseUrl}/api/policies`, {
244
+ method: "GET"
245
+ });
246
+ if (!response.ok) {
247
+ throw new ApiError(
248
+ `Failed to fetch policies: ${response.statusText}`,
249
+ response.status
250
+ );
251
+ }
252
+ const json = await response.json();
253
+ return json.data ?? json;
254
+ }
255
+ /**
256
+ * Get a specific policy by ID
257
+ * @param policyId - The unique policy identifier
258
+ * @returns The public policy specification, or null if not found
259
+ */
260
+ async getPolicy(policyId) {
261
+ const response = await fetch(
262
+ `${this.baseUrl}/api/policies/${encodeURIComponent(policyId)}`,
263
+ { method: "GET" }
264
+ );
265
+ if (response.status === 404) {
266
+ return null;
267
+ }
268
+ if (!response.ok) {
269
+ throw new ApiError(
270
+ `Failed to fetch policy: ${response.statusText}`,
271
+ response.status
272
+ );
273
+ }
274
+ const json = await response.json();
275
+ return json.data ?? json;
276
+ }
277
+ // ==========================================================================
278
+ // zkTLS Methods
279
+ // ==========================================================================
280
+ /**
281
+ * List available zkTLS extractors (data sources)
282
+ * @returns Array of available extractors
283
+ */
284
+ async listExtractors() {
285
+ const response = await this.fetch("/api/zktls/extractors");
286
+ return response.json();
287
+ }
288
+ /**
289
+ * List zkTLS attestations for the authenticated organization
290
+ * @returns Array of attestations
291
+ */
292
+ async listAttestations() {
293
+ const response = await this.fetch("/api/zktls/attestations");
294
+ return response.json();
295
+ }
296
+ /**
297
+ * Get a specific attestation by ID
298
+ * @param attestationId - The attestation UUID
299
+ * @returns The attestation or null if not found
300
+ */
301
+ async getAttestation(attestationId) {
302
+ const response = await this.fetch(`/api/zktls/attestations/${encodeURIComponent(attestationId)}`);
303
+ return response.json();
304
+ }
305
+ /**
306
+ * Create a new zkTLS session for data attestation
307
+ * @param extractorId - The extractor to use (e.g., "coinbase")
308
+ * @param callbackUrl - URL to redirect to after authentication
309
+ * @returns Session ID and auth URL to redirect user to
310
+ */
311
+ async createZkTlsSession(extractorId, callbackUrl) {
312
+ const response = await this.fetch("/api/zktls/sessions", {
313
+ method: "POST",
314
+ body: JSON.stringify({ extractor: extractorId, callbackUrl })
315
+ });
316
+ return response.json();
317
+ }
318
+ /**
319
+ * Get the status of a zkTLS session
320
+ * @param sessionId - The session UUID
321
+ * @returns Session status and attestation if completed
322
+ */
323
+ async getZkTlsSession(sessionId) {
324
+ const response = await this.fetch(`/api/zktls/sessions/${encodeURIComponent(sessionId)}`);
325
+ return response.json();
326
+ }
327
+ /**
328
+ * Wait for a zkTLS session to complete
329
+ * @param sessionId - The session UUID
330
+ * @param options - Polling options
331
+ * @returns The completed session with attestation
332
+ * @throws {ZkTlsSessionExpiredError} If session expires
333
+ * @throws {ZkTlsSessionFailedError} If session fails
334
+ * @throws {TimeoutError} If timeout is reached
335
+ */
336
+ async waitForZkTlsSession(sessionId, options = {}) {
337
+ const intervalMs = options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
338
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
339
+ const startTime = Date.now();
340
+ while (Date.now() - startTime < timeoutMs) {
341
+ const result = await this.getZkTlsSession(sessionId);
342
+ if (!result.success || !result.data) {
343
+ throw new ApiError(
344
+ result.error || "Failed to get zkTLS session",
345
+ 500,
346
+ result
347
+ );
348
+ }
349
+ const session = result.data;
350
+ if (options.onProgress) {
351
+ options.onProgress(session);
352
+ }
353
+ if (session.status === "completed") {
354
+ return session;
355
+ }
356
+ if (session.status === "failed") {
357
+ throw new ZkTlsSessionFailedError(sessionId, session.error || "Unknown error");
358
+ }
359
+ if (session.status === "expired") {
360
+ throw new ZkTlsSessionExpiredError(sessionId);
361
+ }
362
+ await this.sleep(intervalMs);
363
+ }
364
+ throw new TimeoutError(
365
+ `Timeout waiting for zkTLS session ${sessionId} after ${timeoutMs}ms`,
366
+ timeoutMs
367
+ );
368
+ }
369
+ // ==========================================================================
370
+ // Circuit Methods
371
+ // ==========================================================================
372
+ /**
373
+ * List available circuits
374
+ * @param options - Optional filters
375
+ * @returns Array of circuits
376
+ */
377
+ async listCircuits(options = {}) {
378
+ const params = new URLSearchParams();
379
+ if (options.status) params.set("status", options.status);
380
+ if (options.policyId) params.set("policyId", options.policyId);
381
+ const queryString = params.toString();
382
+ const path = queryString ? `/api/circuits?${queryString}` : "/api/circuits";
383
+ const response = await this.fetch(path);
384
+ return response.json();
385
+ }
386
+ /**
387
+ * Get a specific circuit by ID
388
+ * @param circuitId - The circuit identifier
389
+ * @returns The circuit details or null if not found
390
+ */
391
+ async getCircuit(circuitId) {
392
+ const response = await this.fetch(`/api/circuits/${encodeURIComponent(circuitId)}`);
393
+ return response.json();
394
+ }
395
+ /**
396
+ * Activate a circuit (requires validation to have passed)
397
+ * @param circuitId - The circuit identifier to activate
398
+ * @returns The activation result
399
+ */
400
+ async activateCircuit(circuitId) {
401
+ const response = await this.fetch(`/api/circuits/${encodeURIComponent(circuitId)}/activate`, {
402
+ method: "POST"
403
+ });
404
+ return response.json();
405
+ }
406
+ // ==========================================================================
407
+ // Private Helpers
408
+ // ==========================================================================
409
+ async fetch(path, init) {
410
+ const response = await fetch(`${this.baseUrl}${path}`, {
411
+ ...init,
412
+ headers: {
413
+ ...this.headers,
414
+ ...init?.headers
415
+ }
416
+ });
417
+ if (response.status === 401) {
418
+ throw new AuthenticationError();
419
+ }
420
+ return response;
421
+ }
422
+ sleep(ms) {
423
+ return new Promise((resolve) => setTimeout(resolve, ms));
424
+ }
425
+ };
426
+
427
+ // src/adapters/zktls/adapter.ts
428
+ var ZkTlsAdapter = class {
429
+ client;
430
+ constructor(config) {
431
+ this.client = new BindClient({
432
+ apiKey: config.apiKey,
433
+ baseUrl: config.baseUrl
434
+ });
435
+ }
436
+ /**
437
+ * Fetch attestation data - either from existing attestation or by creating session
438
+ */
439
+ async fetchData(query) {
440
+ if (query.attestationId) {
441
+ return this.fetchExistingAttestation(query.attestationId);
442
+ }
443
+ if (query.callbackUrl) {
444
+ return this.initiateSession(query.callbackUrl);
445
+ }
446
+ throw new Error("Either attestationId or callbackUrl must be provided");
447
+ }
448
+ /**
449
+ * Get supported circuits
450
+ */
451
+ getSupportedCircuits() {
452
+ return [...this.supportedCircuits];
453
+ }
454
+ /**
455
+ * Create a zkTLS session and return the auth URL
456
+ * Client should redirect user to this URL
457
+ */
458
+ async createSession(callbackUrl) {
459
+ const result = await this.client.createZkTlsSession(this.extractorId, callbackUrl);
460
+ if (!result.success || !result.data) {
461
+ throw new Error(result.error || "Failed to create zkTLS session");
462
+ }
463
+ return result.data;
464
+ }
465
+ /**
466
+ * Wait for session completion and return attestation
467
+ */
468
+ async waitForSession(sessionId, options) {
469
+ const session = await this.client.waitForZkTlsSession(sessionId, options);
470
+ if (!session.attestation) {
471
+ throw new Error("Session completed but no attestation found");
472
+ }
473
+ const extractors = await this.client.listExtractors();
474
+ const extractor = extractors.data?.find((e) => e.id === this.extractorId);
475
+ if (!extractor) {
476
+ throw new Error(`Extractor not found: ${this.extractorId}`);
477
+ }
478
+ return {
479
+ attestation: session.attestation,
480
+ extractor
481
+ };
482
+ }
483
+ // ===========================================================================
484
+ // Protected helpers
485
+ // ===========================================================================
486
+ async fetchExistingAttestation(attestationId) {
487
+ const result = await this.client.getAttestation(attestationId);
488
+ if (!result.success || !result.data) {
489
+ throw new Error(result.error || "Attestation not found");
490
+ }
491
+ const extractors = await this.client.listExtractors();
492
+ const extractor = extractors.data?.find((e) => e.id === result.data.extractor);
493
+ if (!extractor) {
494
+ throw new Error(`Extractor not found: ${result.data.extractor}`);
495
+ }
496
+ return {
497
+ attestation: result.data,
498
+ extractor
499
+ };
500
+ }
501
+ async initiateSession(callbackUrl) {
502
+ const { sessionId } = await this.createSession(callbackUrl);
503
+ return this.waitForSession(sessionId);
504
+ }
505
+ validateCircuit(circuitId) {
506
+ if (!this.supportedCircuits.includes(circuitId)) {
507
+ throw new Error(
508
+ `Circuit "${circuitId}" is not supported by ${this.name}. Supported circuits: ${this.supportedCircuits.join(", ")}`
509
+ );
510
+ }
511
+ }
512
+ };
513
+
514
+ // src/adapters/zktls/coinbase.ts
515
+ var SUPPORTED_CIRCUITS2 = [
516
+ "bind.identity.kyc.v1",
517
+ "bind.identity.coinbase.v1"
518
+ ];
519
+ var CoinbaseAdapter = class extends ZkTlsAdapter {
520
+ id = "coinbase-kyc";
521
+ name = "Coinbase KYC";
522
+ description = "Fetches KYC verification status from Coinbase via zkTLS attestation";
523
+ extractorId = "coinbase";
524
+ supportedCircuits = SUPPORTED_CIRCUITS2;
525
+ constructor(config) {
526
+ super(config);
527
+ }
528
+ /**
529
+ * Transform Coinbase attestation to circuit inputs
530
+ */
531
+ toCircuitInputs(data, circuitId) {
532
+ this.validateCircuit(circuitId);
533
+ const claims = data.attestation.claims;
534
+ switch (circuitId) {
535
+ case "bind.identity.kyc.v1":
536
+ return this.toKycInputs(data, claims);
537
+ case "bind.identity.coinbase.v1":
538
+ return this.toCoinbaseInputs(data, claims);
539
+ default:
540
+ throw new Error(`No input transformer for circuit: ${circuitId}`);
541
+ }
542
+ }
543
+ // ===========================================================================
544
+ // Private transformers
545
+ // ===========================================================================
546
+ toKycInputs(data, claims) {
547
+ return {
548
+ kycVerified: String(claims.kyc_verified),
549
+ kycLevel: String(claims.kyc_level ?? 0),
550
+ countryCode: claims.country_code ?? "",
551
+ attestationId: data.attestation.id,
552
+ witnessId: data.attestation.witness.id,
553
+ signature: data.attestation.signature,
554
+ timestamp: String(data.attestation.createdAt)
555
+ };
556
+ }
557
+ toCoinbaseInputs(data, claims) {
558
+ return {
559
+ kycVerified: String(claims.kyc_verified),
560
+ kycLevel: String(claims.kyc_level ?? 0),
561
+ countryCode: claims.country_code ?? "",
562
+ accountCreatedAt: claims.account_created_at ?? "",
563
+ attestationId: data.attestation.id,
564
+ witnessId: data.attestation.witness.id,
565
+ witnessPublicKey: data.attestation.witness.publicKey,
566
+ signature: data.attestation.signature,
567
+ url: data.attestation.url,
568
+ method: data.attestation.method,
569
+ expiresAt: String(data.attestation.expiresAt)
570
+ };
571
+ }
572
+ };
573
+ function createCoinbaseAdapter(config) {
574
+ return new CoinbaseAdapter(config);
575
+ }
576
+
577
+ exports.CoinbaseAdapter = CoinbaseAdapter;
81
578
  exports.DimoAdapter = DimoAdapter;
579
+ exports.ZkTlsAdapter = ZkTlsAdapter;
580
+ exports.createCoinbaseAdapter = createCoinbaseAdapter;
82
581
  //# sourceMappingURL=index.cjs.map
83
582
  //# sourceMappingURL=index.cjs.map