@bind-protocol/sdk 0.7.0 → 0.9.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 (36) hide show
  1. package/README.md +7 -11
  2. package/dist/{adapter-Cl7HtxU3.d.ts → adapter-J6D9MZJV.d.ts} +2 -2
  3. package/dist/{adapter-zyYSX6_e.d.cts → adapter-qe9f1ll3.d.cts} +2 -2
  4. package/dist/adapters/dimo/index.d.cts +3 -3
  5. package/dist/adapters/dimo/index.d.ts +3 -3
  6. package/dist/adapters/index.cjs +113 -137
  7. package/dist/adapters/index.cjs.map +1 -1
  8. package/dist/adapters/index.d.cts +4 -4
  9. package/dist/adapters/index.d.ts +4 -4
  10. package/dist/adapters/index.js +113 -137
  11. package/dist/adapters/index.js.map +1 -1
  12. package/dist/adapters/zktls/index.cjs +113 -137
  13. package/dist/adapters/zktls/index.cjs.map +1 -1
  14. package/dist/adapters/zktls/index.d.cts +3 -3
  15. package/dist/adapters/zktls/index.d.ts +3 -3
  16. package/dist/adapters/zktls/index.js +113 -137
  17. package/dist/adapters/zktls/index.js.map +1 -1
  18. package/dist/{client-CadOSqx6.d.ts → client-CfYXpFLk.d.cts} +70 -32
  19. package/dist/{client-BkohyCGJ.d.cts → client-CpJ87Xe0.d.ts} +70 -32
  20. package/dist/core/index.cjs +107 -124
  21. package/dist/core/index.cjs.map +1 -1
  22. package/dist/core/index.d.cts +2 -2
  23. package/dist/core/index.d.ts +2 -2
  24. package/dist/core/index.js +107 -124
  25. package/dist/core/index.js.map +1 -1
  26. package/dist/index.cjs +113 -137
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +4 -4
  29. package/dist/index.d.ts +4 -4
  30. package/dist/index.js +113 -137
  31. package/dist/index.js.map +1 -1
  32. package/dist/{types-Cz9q5U3r.d.cts → types-BcPssdQk.d.cts} +32 -174
  33. package/dist/{types-Cz9q5U3r.d.ts → types-BcPssdQk.d.ts} +32 -174
  34. package/dist/{types-Ca_xbN13.d.ts → types-D7Q7ymPa.d.ts} +1 -1
  35. package/dist/{types-DAN8BlbI.d.cts → types-ywkMNwun.d.cts} +1 -1
  36. package/package.json +1 -1
package/README.md CHANGED
@@ -18,13 +18,13 @@ const client = new BindClient({
18
18
  });
19
19
 
20
20
  // Submit a prove job
21
- const result = await client.submitProveJob('bind.mobility.riskband.v1', {
21
+ const { jobId } = await client.submitProveJob('bind.mobility.riskband.v1', {
22
22
  signals: JSON.stringify(telemetryData),
23
23
  timestamp: new Date().toISOString(),
24
24
  });
25
25
 
26
26
  // Wait for completion
27
- const job = await client.waitForProveJob(result.data.jobId);
27
+ const job = await client.waitForProveJob(jobId);
28
28
 
29
29
  if (job.status === 'completed') {
30
30
  console.log('Proof generated:', job.attestationId);
@@ -230,14 +230,10 @@ async function generateRiskCredential(vehicleTokenId: string) {
230
230
 
231
231
  // 3. Transform and submit prove job
232
232
  const inputs = dimo.toCircuitInputs(telemetry, 'bind.mobility.riskband.v1');
233
- const result = await bind.submitProveJob('bind.mobility.riskband.v1', inputs);
234
-
235
- if (!result.success) {
236
- throw new Error(result.error);
237
- }
233
+ const { jobId } = await bind.submitProveJob('bind.mobility.riskband.v1', inputs);
238
234
 
239
235
  // 4. Wait for proof generation
240
- const job = await bind.waitForProveJob(result.data.jobId, {
236
+ const job = await bind.waitForProveJob(jobId, {
241
237
  onProgress: (j) => console.log(`Status: ${j.status}`),
242
238
  });
243
239
 
@@ -268,10 +264,10 @@ import type {
268
264
  ProveJobInputs,
269
265
  ProveJob,
270
266
  ProveJobSummary,
271
- SubmitProveJobResponse,
272
- GetProveJobResponse,
267
+ SubmitProveJobResult,
273
268
  ListProveJobsOptions,
274
- ListProveJobsResponse,
269
+ Pagination,
270
+ PollOptions,
275
271
 
276
272
  // Credential types
277
273
  BindCredential,
@@ -1,5 +1,5 @@
1
- import { D as DataAdapter } from './types-Ca_xbN13.js';
2
- import { a as ProveJobInputs } from './types-Cz9q5U3r.js';
1
+ import { D as DataAdapter } from './types-D7Q7ymPa.js';
2
+ import { c as ProveJobInputs } from './types-BcPssdQk.js';
3
3
 
4
4
  /**
5
5
  * DIMO Adapter Types
@@ -1,5 +1,5 @@
1
- import { D as DataAdapter } from './types-DAN8BlbI.cjs';
2
- import { a as ProveJobInputs } from './types-Cz9q5U3r.cjs';
1
+ import { D as DataAdapter } from './types-ywkMNwun.cjs';
2
+ import { c as ProveJobInputs } from './types-BcPssdQk.cjs';
3
3
 
4
4
  /**
5
5
  * DIMO Adapter Types
@@ -1,6 +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 '../../adapter-zyYSX6_e.cjs';
2
- import '../../types-DAN8BlbI.cjs';
3
- import '../../types-Cz9q5U3r.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-qe9f1ll3.cjs';
2
+ import '../../types-ywkMNwun.cjs';
3
+ import '../../types-BcPssdQk.cjs';
4
4
  import '@bind-protocol/policy-spec';
5
5
 
6
6
  /**
@@ -1,6 +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 '../../adapter-Cl7HtxU3.js';
2
- import '../../types-Ca_xbN13.js';
3
- import '../../types-Cz9q5U3r.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-J6D9MZJV.js';
2
+ import '../../types-D7Q7ymPa.js';
3
+ import '../../types-BcPssdQk.js';
4
4
  import '@bind-protocol/policy-spec';
5
5
 
6
6
  /**
@@ -165,33 +165,42 @@ var BindClient = class {
165
165
  * @throws {InsufficientCreditsError} If there aren't enough credits
166
166
  */
167
167
  async submitProveJob(circuitId, inputs, options) {
168
- const response = await this.fetch("/api/prove", {
169
- method: "POST",
170
- body: JSON.stringify({
171
- circuitId,
172
- inputs,
173
- verificationMode: options?.verificationMode
174
- })
175
- });
176
- const result = await response.json();
177
- if (!result.success && result.requiredCredits !== void 0 && result.availableCredits !== void 0) {
178
- throw new InsufficientCreditsError(result.requiredCredits, result.availableCredits);
168
+ try {
169
+ return await this.fetchJson("/api/prove", {
170
+ method: "POST",
171
+ body: JSON.stringify({
172
+ circuitId,
173
+ inputs,
174
+ verificationMode: options?.verificationMode
175
+ })
176
+ });
177
+ } catch (err) {
178
+ if (err instanceof ApiError && err.response) {
179
+ const body = err.response;
180
+ if (body.requiredCredits !== void 0 && body.availableCredits !== void 0) {
181
+ throw new InsufficientCreditsError(
182
+ body.requiredCredits,
183
+ body.availableCredits
184
+ );
185
+ }
186
+ }
187
+ throw err;
179
188
  }
180
- return result;
181
189
  }
182
190
  /**
183
191
  * Get the status and results of a prove job
184
192
  * @param jobId - The unique job identifier
185
193
  * @returns The job details including status and outputs
194
+ * @throws {ApiError} If the API request fails
186
195
  */
187
196
  async getProveJob(jobId) {
188
- const response = await this.fetch(`/api/prove/${encodeURIComponent(jobId)}`);
189
- return response.json();
197
+ return this.fetchJson(`/api/prove/${encodeURIComponent(jobId)}`);
190
198
  }
191
199
  /**
192
200
  * List prove jobs for the authenticated organization
193
201
  * @param options - Optional filters for status, limit, and offset
194
202
  * @returns Paginated list of prove jobs
203
+ * @throws {ApiError} If the API request fails
195
204
  */
196
205
  async listProveJobs(options = {}) {
197
206
  const params = new URLSearchParams();
@@ -200,8 +209,7 @@ var BindClient = class {
200
209
  if (options.offset !== void 0) params.set("offset", options.offset.toString());
201
210
  const queryString = params.toString();
202
211
  const path = queryString ? `/api/prove?${queryString}` : "/api/prove";
203
- const response = await this.fetch(path);
204
- return response.json();
212
+ return this.fetchJson(path);
205
213
  }
206
214
  /**
207
215
  * Poll for prove job completion
@@ -209,21 +217,14 @@ var BindClient = class {
209
217
  * @param options - Polling options
210
218
  * @returns The completed or failed job
211
219
  * @throws {TimeoutError} If the job doesn't complete within the timeout
220
+ * @throws {ApiError} If the API request fails
212
221
  */
213
222
  async waitForProveJob(jobId, options = {}) {
214
223
  const intervalMs = options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
215
224
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
216
225
  const startTime = Date.now();
217
226
  while (Date.now() - startTime < timeoutMs) {
218
- const result = await this.getProveJob(jobId);
219
- if (!result.success || !result.data) {
220
- throw new ApiError(
221
- result.error || "Failed to get prove job",
222
- 500,
223
- result
224
- );
225
- }
226
- const job = result.data;
227
+ const job = await this.getProveJob(jobId);
227
228
  if (options.onProgress) {
228
229
  options.onProgress(job);
229
230
  }
@@ -243,41 +244,28 @@ var BindClient = class {
243
244
  /**
244
245
  * List all available public policies
245
246
  * @returns Array of public policy specifications
247
+ * @throws {ApiError} If the API request fails
246
248
  */
247
249
  async listPolicies() {
248
- const response = await fetch(`${this.baseUrl}/api/policies`, {
249
- method: "GET"
250
- });
251
- if (!response.ok) {
252
- throw new ApiError(
253
- `Failed to fetch policies: ${response.statusText}`,
254
- response.status
255
- );
256
- }
257
- const json = await response.json();
258
- return json.data ?? json;
250
+ return this.fetchJson("/api/policies");
259
251
  }
260
252
  /**
261
253
  * Get a specific policy by ID
262
254
  * @param policyId - The unique policy identifier
263
255
  * @returns The public policy specification, or null if not found
256
+ * @throws {ApiError} If the API request fails (except 404)
264
257
  */
265
258
  async getPolicy(policyId) {
266
- const response = await fetch(
267
- `${this.baseUrl}/api/policies/${encodeURIComponent(policyId)}`,
268
- { method: "GET" }
269
- );
270
- if (response.status === 404) {
271
- return null;
272
- }
273
- if (!response.ok) {
274
- throw new ApiError(
275
- `Failed to fetch policy: ${response.statusText}`,
276
- response.status
259
+ try {
260
+ return await this.fetchJson(
261
+ `/api/policies/${encodeURIComponent(policyId)}`
277
262
  );
263
+ } catch (err) {
264
+ if (err instanceof ApiError && err.status === 404) {
265
+ return null;
266
+ }
267
+ throw err;
278
268
  }
279
- const json = await response.json();
280
- return json.data ?? json;
281
269
  }
282
270
  // ==========================================================================
283
271
  // zkTLS Methods
@@ -285,49 +273,49 @@ var BindClient = class {
285
273
  /**
286
274
  * List available zkTLS extractors (data sources)
287
275
  * @returns Array of available extractors
276
+ * @throws {ApiError} If the API request fails
288
277
  */
289
278
  async listExtractors() {
290
- const response = await this.fetch("/api/zktls/extractors");
291
- return response.json();
279
+ return this.fetchJson("/api/zktls/extractors");
292
280
  }
293
281
  /**
294
282
  * List zkTLS attestations for the authenticated organization
295
283
  * @returns Array of attestations
284
+ * @throws {ApiError} If the API request fails
296
285
  */
297
286
  async listAttestations() {
298
- const response = await this.fetch("/api/zktls/attestations");
299
- return response.json();
287
+ return this.fetchJson("/api/zktls/attestations");
300
288
  }
301
289
  /**
302
290
  * Get a specific attestation by ID
303
291
  * @param attestationId - The attestation UUID
304
- * @returns The attestation or null if not found
292
+ * @returns The attestation details
293
+ * @throws {ApiError} If the API request fails
305
294
  */
306
295
  async getAttestation(attestationId) {
307
- const response = await this.fetch(`/api/zktls/attestations/${encodeURIComponent(attestationId)}`);
308
- return response.json();
296
+ return this.fetchJson(`/api/zktls/attestations/${encodeURIComponent(attestationId)}`);
309
297
  }
310
298
  /**
311
299
  * Create a new zkTLS session for data attestation
312
300
  * @param extractorId - The extractor to use (e.g., "coinbase")
313
301
  * @param callbackUrl - URL to redirect to after authentication
314
302
  * @returns Session ID and auth URL to redirect user to
303
+ * @throws {ApiError} If the API request fails
315
304
  */
316
305
  async createZkTlsSession(extractorId, callbackUrl) {
317
- const response = await this.fetch("/api/zktls/sessions", {
306
+ return this.fetchJson("/api/zktls/sessions", {
318
307
  method: "POST",
319
308
  body: JSON.stringify({ extractor: extractorId, callbackUrl })
320
309
  });
321
- return response.json();
322
310
  }
323
311
  /**
324
312
  * Get the status of a zkTLS session
325
313
  * @param sessionId - The session UUID
326
314
  * @returns Session status and attestation if completed
315
+ * @throws {ApiError} If the API request fails
327
316
  */
328
317
  async getZkTlsSession(sessionId) {
329
- const response = await this.fetch(`/api/zktls/sessions/${encodeURIComponent(sessionId)}`);
330
- return response.json();
318
+ return this.fetchJson(`/api/zktls/sessions/${encodeURIComponent(sessionId)}`);
331
319
  }
332
320
  /**
333
321
  * Wait for a zkTLS session to complete
@@ -337,21 +325,14 @@ var BindClient = class {
337
325
  * @throws {ZkTlsSessionExpiredError} If session expires
338
326
  * @throws {ZkTlsSessionFailedError} If session fails
339
327
  * @throws {TimeoutError} If timeout is reached
328
+ * @throws {ApiError} If the API request fails
340
329
  */
341
330
  async waitForZkTlsSession(sessionId, options = {}) {
342
331
  const intervalMs = options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
343
332
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
344
333
  const startTime = Date.now();
345
334
  while (Date.now() - startTime < timeoutMs) {
346
- const result = await this.getZkTlsSession(sessionId);
347
- if (!result.success || !result.data) {
348
- throw new ApiError(
349
- result.error || "Failed to get zkTLS session",
350
- 500,
351
- result
352
- );
353
- }
354
- const session = result.data;
335
+ const session = await this.getZkTlsSession(sessionId);
355
336
  if (options.onProgress) {
356
337
  options.onProgress(session);
357
338
  }
@@ -378,6 +359,7 @@ var BindClient = class {
378
359
  * List available circuits
379
360
  * @param options - Optional filters
380
361
  * @returns Array of circuits
362
+ * @throws {ApiError} If the API request fails
381
363
  */
382
364
  async listCircuits(options = {}) {
383
365
  const params = new URLSearchParams();
@@ -385,28 +367,27 @@ var BindClient = class {
385
367
  if (options.policyId) params.set("policyId", options.policyId);
386
368
  const queryString = params.toString();
387
369
  const path = queryString ? `/api/circuits?${queryString}` : "/api/circuits";
388
- const response = await this.fetch(path);
389
- return response.json();
370
+ return this.fetchJson(path);
390
371
  }
391
372
  /**
392
373
  * Get a specific circuit by ID
393
374
  * @param circuitId - The circuit identifier
394
- * @returns The circuit details or null if not found
375
+ * @returns The circuit details
376
+ * @throws {ApiError} If the API request fails
395
377
  */
396
378
  async getCircuit(circuitId) {
397
- const response = await this.fetch(`/api/circuits/${encodeURIComponent(circuitId)}`);
398
- return response.json();
379
+ return this.fetchJson(`/api/circuits/${encodeURIComponent(circuitId)}`);
399
380
  }
400
381
  /**
401
382
  * Activate a circuit (requires validation to have passed)
402
383
  * @param circuitId - The circuit identifier to activate
403
384
  * @returns The activation result
385
+ * @throws {ApiError} If the API request fails
404
386
  */
405
387
  async activateCircuit(circuitId) {
406
- const response = await this.fetch(`/api/circuits/${encodeURIComponent(circuitId)}/activate`, {
388
+ return this.fetchJson(`/api/circuits/${encodeURIComponent(circuitId)}/activate`, {
407
389
  method: "POST"
408
390
  });
409
- return response.json();
410
391
  }
411
392
  // ==========================================================================
412
393
  // Shared Proof Methods
@@ -415,18 +396,19 @@ var BindClient = class {
415
396
  * Share a completed proof with a verifier organization
416
397
  * @param request - Share proof request with proveJobId and verifierOrgId
417
398
  * @returns The created shared proof
399
+ * @throws {ApiError} If the API request fails
418
400
  */
419
401
  async shareProof(request) {
420
- const response = await this.fetch("/api/shared-proofs", {
402
+ return this.fetchJson("/api/shared-proofs", {
421
403
  method: "POST",
422
404
  body: JSON.stringify(request)
423
405
  });
424
- return response.json();
425
406
  }
426
407
  /**
427
408
  * List shared proofs (outgoing or incoming)
428
409
  * @param options - Filter by direction, pagination, and inclusion options
429
410
  * @returns Paginated list of shared proofs
411
+ * @throws {ApiError} If the API request fails
430
412
  */
431
413
  async listSharedProofs(options = {}) {
432
414
  const params = new URLSearchParams();
@@ -437,28 +419,27 @@ var BindClient = class {
437
419
  if (options.includeRevoked) params.set("includeRevoked", "true");
438
420
  const queryString = params.toString();
439
421
  const path = queryString ? `/api/shared-proofs?${queryString}` : "/api/shared-proofs";
440
- const response = await this.fetch(path);
441
- return response.json();
422
+ return this.fetchJson(path);
442
423
  }
443
424
  /**
444
425
  * Get a specific shared proof by ID
445
426
  * @param sharedProofId - The shared proof ID
446
427
  * @returns The shared proof details
428
+ * @throws {ApiError} If the API request fails
447
429
  */
448
430
  async getSharedProof(sharedProofId) {
449
- const response = await this.fetch(`/api/shared-proofs/${encodeURIComponent(sharedProofId)}`);
450
- return response.json();
431
+ return this.fetchJson(`/api/shared-proofs/${encodeURIComponent(sharedProofId)}`);
451
432
  }
452
433
  /**
453
434
  * Revoke a shared proof. Only the sharing organization can revoke.
454
435
  * @param sharedProofId - The shared proof ID to revoke
455
436
  * @returns The revocation result
437
+ * @throws {ApiError} If the API request fails
456
438
  */
457
439
  async revokeSharedProof(sharedProofId) {
458
- const response = await this.fetch(`/api/shared-proofs/${encodeURIComponent(sharedProofId)}`, {
440
+ return this.fetchJson(`/api/shared-proofs/${encodeURIComponent(sharedProofId)}`, {
459
441
  method: "DELETE"
460
442
  });
461
- return response.json();
462
443
  }
463
444
  // ==========================================================================
464
445
  // Verification Methods
@@ -472,83 +453,70 @@ var BindClient = class {
472
453
  * @param sharedProofId - The shared proof ID to verify
473
454
  * @param options - Optional polling configuration
474
455
  * @returns The verification result
456
+ * @throws {ApiError} If the API request fails
457
+ * @throws {TimeoutError} If verification doesn't complete within the timeout
475
458
  */
476
459
  async verifySharedProof(sharedProofId, options) {
477
- const pollIntervalMs = options?.pollIntervalMs ?? 1e3;
478
- const maxWaitMs = options?.maxWaitMs ?? 12e4;
479
- const queueResponse = await this.fetch(`/api/verify/shared/${encodeURIComponent(sharedProofId)}`, {
460
+ const intervalMs = options?.intervalMs ?? 1e3;
461
+ const timeoutMs = options?.timeoutMs ?? 12e4;
462
+ const queueResult = await this.fetchJson(`/api/verify/shared/${encodeURIComponent(sharedProofId)}`, {
480
463
  method: "POST"
481
464
  });
482
- const queueResult = await queueResponse.json();
483
- if (!queueResult.success || !queueResult.data?.jobId) {
484
- return {
485
- success: false,
486
- error: queueResult.error ?? "Failed to queue verification job"
487
- };
488
- }
489
- const jobId = queueResult.data.jobId;
465
+ const jobId = queueResult.jobId;
490
466
  const startTime = Date.now();
491
- while (Date.now() - startTime < maxWaitMs) {
467
+ while (Date.now() - startTime < timeoutMs) {
492
468
  const statusResult = await this.getVerifyJobStatus(jobId);
493
- if (!statusResult.success) {
494
- return {
495
- success: false,
496
- error: statusResult.error ?? "Failed to get verification status"
497
- };
498
- }
499
- const status = statusResult.data?.status;
500
- if (status === "completed" || status === "failed") {
469
+ if (statusResult.status === "completed" || statusResult.status === "failed") {
501
470
  return {
502
- success: true,
503
- data: {
504
- isValid: statusResult.data?.isValid ?? false,
505
- error: statusResult.data?.error,
506
- verificationTimeMs: statusResult.data?.verificationTimeMs ?? 0,
507
- creditsCharged: statusResult.data?.creditsCharged ?? queueResult.data.creditsCharged,
508
- verificationResultId: statusResult.data?.verificationResultId ?? jobId
509
- }
471
+ isValid: statusResult.isValid ?? false,
472
+ error: statusResult.error,
473
+ verificationTimeMs: statusResult.verificationTimeMs ?? 0,
474
+ creditsCharged: statusResult.creditsCharged ?? queueResult.creditsCharged,
475
+ verificationResultId: statusResult.verificationResultId ?? jobId,
476
+ publicInputs: statusResult.publicInputs
510
477
  };
511
478
  }
512
- await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
479
+ await this.sleep(intervalMs);
513
480
  }
514
- return {
515
- success: false,
516
- error: `Verification timed out after ${maxWaitMs}ms. Job ID: ${jobId}`
517
- };
481
+ throw new TimeoutError(
482
+ `Verification timed out after ${timeoutMs}ms. Job ID: ${jobId}`,
483
+ timeoutMs
484
+ );
518
485
  }
519
486
  /**
520
487
  * Get the status of a verification job
521
488
  * @param jobId - The verification job ID
522
- * @returns The job status
489
+ * @returns The job status data
490
+ * @throws {ApiError} If the API request fails
523
491
  */
524
492
  async getVerifyJobStatus(jobId) {
525
- const response = await this.fetch(`/api/verify/jobs/${encodeURIComponent(jobId)}`);
526
- return response.json();
493
+ return this.fetchJson(`/api/verify/jobs/${encodeURIComponent(jobId)}`);
527
494
  }
528
495
  /**
529
496
  * Verify an uploaded proof
530
497
  * @param proofBuffer - The proof binary as ArrayBuffer, Uint8Array, or Buffer
531
498
  * @param vkBuffer - The verification key binary as ArrayBuffer, Uint8Array, or Buffer
532
499
  * @returns The verification result
500
+ * @throws {ApiError} If the API request fails
533
501
  */
534
502
  async verifyUploadedProof(proofBuffer, vkBuffer) {
535
503
  const proofBytes = proofBuffer instanceof Uint8Array ? proofBuffer : new Uint8Array(proofBuffer);
536
504
  const vkBytes = vkBuffer instanceof Uint8Array ? vkBuffer : new Uint8Array(vkBuffer);
537
505
  const proofBase64 = typeof Buffer !== "undefined" ? Buffer.from(proofBytes).toString("base64") : btoa(String.fromCharCode(...proofBytes));
538
506
  const vkBase64 = typeof Buffer !== "undefined" ? Buffer.from(vkBytes).toString("base64") : btoa(String.fromCharCode(...vkBytes));
539
- const response = await this.fetch("/api/verify/upload", {
507
+ return this.fetchJson("/api/verify/upload", {
540
508
  method: "POST",
541
509
  body: JSON.stringify({
542
510
  proof: proofBase64,
543
511
  vk: vkBase64
544
512
  })
545
513
  });
546
- return response.json();
547
514
  }
548
515
  /**
549
516
  * Get verification history for the authenticated organization
550
517
  * @param options - Pagination options
551
518
  * @returns Paginated list of verification results
519
+ * @throws {ApiError} If the API request fails
552
520
  */
553
521
  async getVerificationHistory(options = {}) {
554
522
  const params = new URLSearchParams();
@@ -556,8 +524,7 @@ var BindClient = class {
556
524
  if (options.offset !== void 0) params.set("offset", options.offset.toString());
557
525
  const queryString = params.toString();
558
526
  const path = queryString ? `/api/verify/history?${queryString}` : "/api/verify/history";
559
- const response = await this.fetch(path);
560
- return response.json();
527
+ return this.fetchJson(path);
561
528
  }
562
529
  // ==========================================================================
563
530
  // Private Helpers
@@ -573,8 +540,24 @@ var BindClient = class {
573
540
  if (response.status === 401) {
574
541
  throw new AuthenticationError();
575
542
  }
543
+ if (!response.ok) {
544
+ const body = await response.json().catch(() => ({}));
545
+ throw new ApiError(
546
+ body.error || `HTTP ${response.status}: ${response.statusText}`,
547
+ response.status,
548
+ body
549
+ );
550
+ }
576
551
  return response;
577
552
  }
553
+ async fetchJson(path, init) {
554
+ const response = await this.fetch(path, init);
555
+ const json = await response.json();
556
+ if (json.success === false) {
557
+ throw new ApiError(json.error || "Request failed", response.status, json);
558
+ }
559
+ return json.data ?? json;
560
+ }
578
561
  sleep(ms) {
579
562
  return new Promise((resolve) => setTimeout(resolve, ms));
580
563
  }
@@ -612,11 +595,7 @@ var ZkTlsAdapter = class {
612
595
  * Client should redirect user to this URL
613
596
  */
614
597
  async createSession(callbackUrl) {
615
- const result = await this.client.createZkTlsSession(this.extractorId, callbackUrl);
616
- if (!result.success || !result.data) {
617
- throw new Error(result.error || "Failed to create zkTLS session");
618
- }
619
- return result.data;
598
+ return this.client.createZkTlsSession(this.extractorId, callbackUrl);
620
599
  }
621
600
  /**
622
601
  * Wait for session completion and return attestation
@@ -627,7 +606,7 @@ var ZkTlsAdapter = class {
627
606
  throw new Error("Session completed but no attestation found");
628
607
  }
629
608
  const extractors = await this.client.listExtractors();
630
- const extractor = extractors.data?.find((e) => e.id === this.extractorId);
609
+ const extractor = extractors.find((e) => e.id === this.extractorId);
631
610
  if (!extractor) {
632
611
  throw new Error(`Extractor not found: ${this.extractorId}`);
633
612
  }
@@ -640,17 +619,14 @@ var ZkTlsAdapter = class {
640
619
  // Protected helpers
641
620
  // ===========================================================================
642
621
  async fetchExistingAttestation(attestationId) {
643
- const result = await this.client.getAttestation(attestationId);
644
- if (!result.success || !result.data) {
645
- throw new Error(result.error || "Attestation not found");
646
- }
622
+ const attestation = await this.client.getAttestation(attestationId);
647
623
  const extractors = await this.client.listExtractors();
648
- const extractor = extractors.data?.find((e) => e.id === result.data.extractor);
624
+ const extractor = extractors.find((e) => e.id === attestation.extractor);
649
625
  if (!extractor) {
650
- throw new Error(`Extractor not found: ${result.data.extractor}`);
626
+ throw new Error(`Extractor not found: ${attestation.extractor}`);
651
627
  }
652
628
  return {
653
- attestation: result.data,
629
+ attestation,
654
630
  extractor
655
631
  };
656
632
  }