@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
@@ -1,5 +1,5 @@
1
- export { B as BindClient, d as deriveCircuitId } from '../client-BkohyCGJ.cjs';
2
- export { A as ActivateCircuitResponse, B as BindClientOptions, l as BindCredential, i as Circuit, C as CircuitStatus, h as CircuitValidationStatus, t as CreateSessionResponse, s as GetAttestationResponse, k as GetCircuitResponse, G as GetProveJobResponse, u as GetSessionResponse, D as GetSharedProofResponse, O as GetVerificationHistoryOptions, Q as GetVerificationHistoryResponse, r as ListAttestationsResponse, j as ListCircuitsResponse, q as ListExtractorsResponse, L as ListProveJobsOptions, g as ListProveJobsResponse, y as ListSharedProofsOptions, z as ListSharedProofsResponse, c as ProofDownloadUrls, d as ProveJob, a as ProveJobInputs, b as ProveJobOutputs, P as ProveJobStatus, e as ProveJobSummary, R as RevokeSharedProofResponse, w as ShareProofRequest, x as ShareProofResponse, v as SharedProof, S as SubmitProveJobRequest, f as SubmitProveJobResponse, N as VerificationHistoryEntry, V as VerificationMode, I as VerificationResult, F as VerifyJobQueuedResponse, E as VerifyJobStatus, H as VerifyJobStatusResponse, J as VerifySharedProofResponse, K as VerifyUploadedProofRequest, M as VerifyUploadedProofResponse, o as ZkTlsAttestation, m as ZkTlsExtractor, p as ZkTlsSession, Z as ZkTlsSessionStatus, n as ZkTlsWitness } from '../types-Cz9q5U3r.cjs';
1
+ export { B as BindClient, d as deriveCircuitId } from '../client-CfYXpFLk.cjs';
2
+ export { A as ActivateCircuitResult, B as BindClientOptions, j as BindCredential, i as Circuit, C as CircuitStatus, h as CircuitValidationStatus, G as GetVerificationHistoryOptions, L as ListProveJobsOptions, q as ListSharedProofsOptions, P as Pagination, a as PollOptions, e as ProofDownloadUrls, f as ProveJob, c as ProveJobInputs, d as ProveJobOutputs, b as ProveJobStatus, g as ProveJobSummary, R as RevokeSharedProofResult, p as ShareProofRequest, o as SharedProof, S as SubmitProveJobResult, t as VerificationHistoryEntry, V as VerificationMode, s as VerificationResult, r as VerifyJobStatus, m as ZkTlsAttestation, k as ZkTlsExtractor, n as ZkTlsSession, Z as ZkTlsSessionStatus, l as ZkTlsWitness } from '../types-BcPssdQk.cjs';
3
3
  export { DisclosureSpec, OutputClaimSpec, PolicyId, PolicyMetadata, PublicPolicySpec, SubjectSpec, ValiditySpec } from '@bind-protocol/policy-spec';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- export { B as BindClient, d as deriveCircuitId } from '../client-CadOSqx6.js';
2
- export { A as ActivateCircuitResponse, B as BindClientOptions, l as BindCredential, i as Circuit, C as CircuitStatus, h as CircuitValidationStatus, t as CreateSessionResponse, s as GetAttestationResponse, k as GetCircuitResponse, G as GetProveJobResponse, u as GetSessionResponse, D as GetSharedProofResponse, O as GetVerificationHistoryOptions, Q as GetVerificationHistoryResponse, r as ListAttestationsResponse, j as ListCircuitsResponse, q as ListExtractorsResponse, L as ListProveJobsOptions, g as ListProveJobsResponse, y as ListSharedProofsOptions, z as ListSharedProofsResponse, c as ProofDownloadUrls, d as ProveJob, a as ProveJobInputs, b as ProveJobOutputs, P as ProveJobStatus, e as ProveJobSummary, R as RevokeSharedProofResponse, w as ShareProofRequest, x as ShareProofResponse, v as SharedProof, S as SubmitProveJobRequest, f as SubmitProveJobResponse, N as VerificationHistoryEntry, V as VerificationMode, I as VerificationResult, F as VerifyJobQueuedResponse, E as VerifyJobStatus, H as VerifyJobStatusResponse, J as VerifySharedProofResponse, K as VerifyUploadedProofRequest, M as VerifyUploadedProofResponse, o as ZkTlsAttestation, m as ZkTlsExtractor, p as ZkTlsSession, Z as ZkTlsSessionStatus, n as ZkTlsWitness } from '../types-Cz9q5U3r.js';
1
+ export { B as BindClient, d as deriveCircuitId } from '../client-CpJ87Xe0.js';
2
+ export { A as ActivateCircuitResult, B as BindClientOptions, j as BindCredential, i as Circuit, C as CircuitStatus, h as CircuitValidationStatus, G as GetVerificationHistoryOptions, L as ListProveJobsOptions, q as ListSharedProofsOptions, P as Pagination, a as PollOptions, e as ProofDownloadUrls, f as ProveJob, c as ProveJobInputs, d as ProveJobOutputs, b as ProveJobStatus, g as ProveJobSummary, R as RevokeSharedProofResult, p as ShareProofRequest, o as SharedProof, S as SubmitProveJobResult, t as VerificationHistoryEntry, V as VerificationMode, s as VerificationResult, r as VerifyJobStatus, m as ZkTlsAttestation, k as ZkTlsExtractor, n as ZkTlsSession, Z as ZkTlsSessionStatus, l as ZkTlsWitness } from '../types-BcPssdQk.js';
3
3
  export { DisclosureSpec, OutputClaimSpec, PolicyId, PolicyMetadata, PublicPolicySpec, SubjectSpec, ValiditySpec } from '@bind-protocol/policy-spec';
4
4
 
5
5
  /**
@@ -96,33 +96,42 @@ var BindClient = class {
96
96
  * @throws {InsufficientCreditsError} If there aren't enough credits
97
97
  */
98
98
  async submitProveJob(circuitId, inputs, options) {
99
- const response = await this.fetch("/api/prove", {
100
- method: "POST",
101
- body: JSON.stringify({
102
- circuitId,
103
- inputs,
104
- verificationMode: options?.verificationMode
105
- })
106
- });
107
- const result = await response.json();
108
- if (!result.success && result.requiredCredits !== void 0 && result.availableCredits !== void 0) {
109
- throw new InsufficientCreditsError(result.requiredCredits, result.availableCredits);
99
+ try {
100
+ return await this.fetchJson("/api/prove", {
101
+ method: "POST",
102
+ body: JSON.stringify({
103
+ circuitId,
104
+ inputs,
105
+ verificationMode: options?.verificationMode
106
+ })
107
+ });
108
+ } catch (err) {
109
+ if (err instanceof ApiError && err.response) {
110
+ const body = err.response;
111
+ if (body.requiredCredits !== void 0 && body.availableCredits !== void 0) {
112
+ throw new InsufficientCreditsError(
113
+ body.requiredCredits,
114
+ body.availableCredits
115
+ );
116
+ }
117
+ }
118
+ throw err;
110
119
  }
111
- return result;
112
120
  }
113
121
  /**
114
122
  * Get the status and results of a prove job
115
123
  * @param jobId - The unique job identifier
116
124
  * @returns The job details including status and outputs
125
+ * @throws {ApiError} If the API request fails
117
126
  */
118
127
  async getProveJob(jobId) {
119
- const response = await this.fetch(`/api/prove/${encodeURIComponent(jobId)}`);
120
- return response.json();
128
+ return this.fetchJson(`/api/prove/${encodeURIComponent(jobId)}`);
121
129
  }
122
130
  /**
123
131
  * List prove jobs for the authenticated organization
124
132
  * @param options - Optional filters for status, limit, and offset
125
133
  * @returns Paginated list of prove jobs
134
+ * @throws {ApiError} If the API request fails
126
135
  */
127
136
  async listProveJobs(options = {}) {
128
137
  const params = new URLSearchParams();
@@ -131,8 +140,7 @@ var BindClient = class {
131
140
  if (options.offset !== void 0) params.set("offset", options.offset.toString());
132
141
  const queryString = params.toString();
133
142
  const path = queryString ? `/api/prove?${queryString}` : "/api/prove";
134
- const response = await this.fetch(path);
135
- return response.json();
143
+ return this.fetchJson(path);
136
144
  }
137
145
  /**
138
146
  * Poll for prove job completion
@@ -140,21 +148,14 @@ var BindClient = class {
140
148
  * @param options - Polling options
141
149
  * @returns The completed or failed job
142
150
  * @throws {TimeoutError} If the job doesn't complete within the timeout
151
+ * @throws {ApiError} If the API request fails
143
152
  */
144
153
  async waitForProveJob(jobId, options = {}) {
145
154
  const intervalMs = options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
146
155
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
147
156
  const startTime = Date.now();
148
157
  while (Date.now() - startTime < timeoutMs) {
149
- const result = await this.getProveJob(jobId);
150
- if (!result.success || !result.data) {
151
- throw new ApiError(
152
- result.error || "Failed to get prove job",
153
- 500,
154
- result
155
- );
156
- }
157
- const job = result.data;
158
+ const job = await this.getProveJob(jobId);
158
159
  if (options.onProgress) {
159
160
  options.onProgress(job);
160
161
  }
@@ -174,41 +175,28 @@ var BindClient = class {
174
175
  /**
175
176
  * List all available public policies
176
177
  * @returns Array of public policy specifications
178
+ * @throws {ApiError} If the API request fails
177
179
  */
178
180
  async listPolicies() {
179
- const response = await fetch(`${this.baseUrl}/api/policies`, {
180
- method: "GET"
181
- });
182
- if (!response.ok) {
183
- throw new ApiError(
184
- `Failed to fetch policies: ${response.statusText}`,
185
- response.status
186
- );
187
- }
188
- const json = await response.json();
189
- return json.data ?? json;
181
+ return this.fetchJson("/api/policies");
190
182
  }
191
183
  /**
192
184
  * Get a specific policy by ID
193
185
  * @param policyId - The unique policy identifier
194
186
  * @returns The public policy specification, or null if not found
187
+ * @throws {ApiError} If the API request fails (except 404)
195
188
  */
196
189
  async getPolicy(policyId) {
197
- const response = await fetch(
198
- `${this.baseUrl}/api/policies/${encodeURIComponent(policyId)}`,
199
- { method: "GET" }
200
- );
201
- if (response.status === 404) {
202
- return null;
203
- }
204
- if (!response.ok) {
205
- throw new ApiError(
206
- `Failed to fetch policy: ${response.statusText}`,
207
- response.status
190
+ try {
191
+ return await this.fetchJson(
192
+ `/api/policies/${encodeURIComponent(policyId)}`
208
193
  );
194
+ } catch (err) {
195
+ if (err instanceof ApiError && err.status === 404) {
196
+ return null;
197
+ }
198
+ throw err;
209
199
  }
210
- const json = await response.json();
211
- return json.data ?? json;
212
200
  }
213
201
  // ==========================================================================
214
202
  // zkTLS Methods
@@ -216,49 +204,49 @@ var BindClient = class {
216
204
  /**
217
205
  * List available zkTLS extractors (data sources)
218
206
  * @returns Array of available extractors
207
+ * @throws {ApiError} If the API request fails
219
208
  */
220
209
  async listExtractors() {
221
- const response = await this.fetch("/api/zktls/extractors");
222
- return response.json();
210
+ return this.fetchJson("/api/zktls/extractors");
223
211
  }
224
212
  /**
225
213
  * List zkTLS attestations for the authenticated organization
226
214
  * @returns Array of attestations
215
+ * @throws {ApiError} If the API request fails
227
216
  */
228
217
  async listAttestations() {
229
- const response = await this.fetch("/api/zktls/attestations");
230
- return response.json();
218
+ return this.fetchJson("/api/zktls/attestations");
231
219
  }
232
220
  /**
233
221
  * Get a specific attestation by ID
234
222
  * @param attestationId - The attestation UUID
235
- * @returns The attestation or null if not found
223
+ * @returns The attestation details
224
+ * @throws {ApiError} If the API request fails
236
225
  */
237
226
  async getAttestation(attestationId) {
238
- const response = await this.fetch(`/api/zktls/attestations/${encodeURIComponent(attestationId)}`);
239
- return response.json();
227
+ return this.fetchJson(`/api/zktls/attestations/${encodeURIComponent(attestationId)}`);
240
228
  }
241
229
  /**
242
230
  * Create a new zkTLS session for data attestation
243
231
  * @param extractorId - The extractor to use (e.g., "coinbase")
244
232
  * @param callbackUrl - URL to redirect to after authentication
245
233
  * @returns Session ID and auth URL to redirect user to
234
+ * @throws {ApiError} If the API request fails
246
235
  */
247
236
  async createZkTlsSession(extractorId, callbackUrl) {
248
- const response = await this.fetch("/api/zktls/sessions", {
237
+ return this.fetchJson("/api/zktls/sessions", {
249
238
  method: "POST",
250
239
  body: JSON.stringify({ extractor: extractorId, callbackUrl })
251
240
  });
252
- return response.json();
253
241
  }
254
242
  /**
255
243
  * Get the status of a zkTLS session
256
244
  * @param sessionId - The session UUID
257
245
  * @returns Session status and attestation if completed
246
+ * @throws {ApiError} If the API request fails
258
247
  */
259
248
  async getZkTlsSession(sessionId) {
260
- const response = await this.fetch(`/api/zktls/sessions/${encodeURIComponent(sessionId)}`);
261
- return response.json();
249
+ return this.fetchJson(`/api/zktls/sessions/${encodeURIComponent(sessionId)}`);
262
250
  }
263
251
  /**
264
252
  * Wait for a zkTLS session to complete
@@ -268,21 +256,14 @@ var BindClient = class {
268
256
  * @throws {ZkTlsSessionExpiredError} If session expires
269
257
  * @throws {ZkTlsSessionFailedError} If session fails
270
258
  * @throws {TimeoutError} If timeout is reached
259
+ * @throws {ApiError} If the API request fails
271
260
  */
272
261
  async waitForZkTlsSession(sessionId, options = {}) {
273
262
  const intervalMs = options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
274
263
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
275
264
  const startTime = Date.now();
276
265
  while (Date.now() - startTime < timeoutMs) {
277
- const result = await this.getZkTlsSession(sessionId);
278
- if (!result.success || !result.data) {
279
- throw new ApiError(
280
- result.error || "Failed to get zkTLS session",
281
- 500,
282
- result
283
- );
284
- }
285
- const session = result.data;
266
+ const session = await this.getZkTlsSession(sessionId);
286
267
  if (options.onProgress) {
287
268
  options.onProgress(session);
288
269
  }
@@ -309,6 +290,7 @@ var BindClient = class {
309
290
  * List available circuits
310
291
  * @param options - Optional filters
311
292
  * @returns Array of circuits
293
+ * @throws {ApiError} If the API request fails
312
294
  */
313
295
  async listCircuits(options = {}) {
314
296
  const params = new URLSearchParams();
@@ -316,28 +298,27 @@ var BindClient = class {
316
298
  if (options.policyId) params.set("policyId", options.policyId);
317
299
  const queryString = params.toString();
318
300
  const path = queryString ? `/api/circuits?${queryString}` : "/api/circuits";
319
- const response = await this.fetch(path);
320
- return response.json();
301
+ return this.fetchJson(path);
321
302
  }
322
303
  /**
323
304
  * Get a specific circuit by ID
324
305
  * @param circuitId - The circuit identifier
325
- * @returns The circuit details or null if not found
306
+ * @returns The circuit details
307
+ * @throws {ApiError} If the API request fails
326
308
  */
327
309
  async getCircuit(circuitId) {
328
- const response = await this.fetch(`/api/circuits/${encodeURIComponent(circuitId)}`);
329
- return response.json();
310
+ return this.fetchJson(`/api/circuits/${encodeURIComponent(circuitId)}`);
330
311
  }
331
312
  /**
332
313
  * Activate a circuit (requires validation to have passed)
333
314
  * @param circuitId - The circuit identifier to activate
334
315
  * @returns The activation result
316
+ * @throws {ApiError} If the API request fails
335
317
  */
336
318
  async activateCircuit(circuitId) {
337
- const response = await this.fetch(`/api/circuits/${encodeURIComponent(circuitId)}/activate`, {
319
+ return this.fetchJson(`/api/circuits/${encodeURIComponent(circuitId)}/activate`, {
338
320
  method: "POST"
339
321
  });
340
- return response.json();
341
322
  }
342
323
  // ==========================================================================
343
324
  // Shared Proof Methods
@@ -346,18 +327,19 @@ var BindClient = class {
346
327
  * Share a completed proof with a verifier organization
347
328
  * @param request - Share proof request with proveJobId and verifierOrgId
348
329
  * @returns The created shared proof
330
+ * @throws {ApiError} If the API request fails
349
331
  */
350
332
  async shareProof(request) {
351
- const response = await this.fetch("/api/shared-proofs", {
333
+ return this.fetchJson("/api/shared-proofs", {
352
334
  method: "POST",
353
335
  body: JSON.stringify(request)
354
336
  });
355
- return response.json();
356
337
  }
357
338
  /**
358
339
  * List shared proofs (outgoing or incoming)
359
340
  * @param options - Filter by direction, pagination, and inclusion options
360
341
  * @returns Paginated list of shared proofs
342
+ * @throws {ApiError} If the API request fails
361
343
  */
362
344
  async listSharedProofs(options = {}) {
363
345
  const params = new URLSearchParams();
@@ -368,28 +350,27 @@ var BindClient = class {
368
350
  if (options.includeRevoked) params.set("includeRevoked", "true");
369
351
  const queryString = params.toString();
370
352
  const path = queryString ? `/api/shared-proofs?${queryString}` : "/api/shared-proofs";
371
- const response = await this.fetch(path);
372
- return response.json();
353
+ return this.fetchJson(path);
373
354
  }
374
355
  /**
375
356
  * Get a specific shared proof by ID
376
357
  * @param sharedProofId - The shared proof ID
377
358
  * @returns The shared proof details
359
+ * @throws {ApiError} If the API request fails
378
360
  */
379
361
  async getSharedProof(sharedProofId) {
380
- const response = await this.fetch(`/api/shared-proofs/${encodeURIComponent(sharedProofId)}`);
381
- return response.json();
362
+ return this.fetchJson(`/api/shared-proofs/${encodeURIComponent(sharedProofId)}`);
382
363
  }
383
364
  /**
384
365
  * Revoke a shared proof. Only the sharing organization can revoke.
385
366
  * @param sharedProofId - The shared proof ID to revoke
386
367
  * @returns The revocation result
368
+ * @throws {ApiError} If the API request fails
387
369
  */
388
370
  async revokeSharedProof(sharedProofId) {
389
- const response = await this.fetch(`/api/shared-proofs/${encodeURIComponent(sharedProofId)}`, {
371
+ return this.fetchJson(`/api/shared-proofs/${encodeURIComponent(sharedProofId)}`, {
390
372
  method: "DELETE"
391
373
  });
392
- return response.json();
393
374
  }
394
375
  // ==========================================================================
395
376
  // Verification Methods
@@ -403,83 +384,70 @@ var BindClient = class {
403
384
  * @param sharedProofId - The shared proof ID to verify
404
385
  * @param options - Optional polling configuration
405
386
  * @returns The verification result
387
+ * @throws {ApiError} If the API request fails
388
+ * @throws {TimeoutError} If verification doesn't complete within the timeout
406
389
  */
407
390
  async verifySharedProof(sharedProofId, options) {
408
- const pollIntervalMs = options?.pollIntervalMs ?? 1e3;
409
- const maxWaitMs = options?.maxWaitMs ?? 12e4;
410
- const queueResponse = await this.fetch(`/api/verify/shared/${encodeURIComponent(sharedProofId)}`, {
391
+ const intervalMs = options?.intervalMs ?? 1e3;
392
+ const timeoutMs = options?.timeoutMs ?? 12e4;
393
+ const queueResult = await this.fetchJson(`/api/verify/shared/${encodeURIComponent(sharedProofId)}`, {
411
394
  method: "POST"
412
395
  });
413
- const queueResult = await queueResponse.json();
414
- if (!queueResult.success || !queueResult.data?.jobId) {
415
- return {
416
- success: false,
417
- error: queueResult.error ?? "Failed to queue verification job"
418
- };
419
- }
420
- const jobId = queueResult.data.jobId;
396
+ const jobId = queueResult.jobId;
421
397
  const startTime = Date.now();
422
- while (Date.now() - startTime < maxWaitMs) {
398
+ while (Date.now() - startTime < timeoutMs) {
423
399
  const statusResult = await this.getVerifyJobStatus(jobId);
424
- if (!statusResult.success) {
400
+ if (statusResult.status === "completed" || statusResult.status === "failed") {
425
401
  return {
426
- success: false,
427
- error: statusResult.error ?? "Failed to get verification status"
402
+ isValid: statusResult.isValid ?? false,
403
+ error: statusResult.error,
404
+ verificationTimeMs: statusResult.verificationTimeMs ?? 0,
405
+ creditsCharged: statusResult.creditsCharged ?? queueResult.creditsCharged,
406
+ verificationResultId: statusResult.verificationResultId ?? jobId,
407
+ publicInputs: statusResult.publicInputs
428
408
  };
429
409
  }
430
- const status = statusResult.data?.status;
431
- if (status === "completed" || status === "failed") {
432
- return {
433
- success: true,
434
- data: {
435
- isValid: statusResult.data?.isValid ?? false,
436
- error: statusResult.data?.error,
437
- verificationTimeMs: statusResult.data?.verificationTimeMs ?? 0,
438
- creditsCharged: statusResult.data?.creditsCharged ?? queueResult.data.creditsCharged,
439
- verificationResultId: statusResult.data?.verificationResultId ?? jobId
440
- }
441
- };
442
- }
443
- await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
410
+ await this.sleep(intervalMs);
444
411
  }
445
- return {
446
- success: false,
447
- error: `Verification timed out after ${maxWaitMs}ms. Job ID: ${jobId}`
448
- };
412
+ throw new TimeoutError(
413
+ `Verification timed out after ${timeoutMs}ms. Job ID: ${jobId}`,
414
+ timeoutMs
415
+ );
449
416
  }
450
417
  /**
451
418
  * Get the status of a verification job
452
419
  * @param jobId - The verification job ID
453
- * @returns The job status
420
+ * @returns The job status data
421
+ * @throws {ApiError} If the API request fails
454
422
  */
455
423
  async getVerifyJobStatus(jobId) {
456
- const response = await this.fetch(`/api/verify/jobs/${encodeURIComponent(jobId)}`);
457
- return response.json();
424
+ return this.fetchJson(`/api/verify/jobs/${encodeURIComponent(jobId)}`);
458
425
  }
459
426
  /**
460
427
  * Verify an uploaded proof
461
428
  * @param proofBuffer - The proof binary as ArrayBuffer, Uint8Array, or Buffer
462
429
  * @param vkBuffer - The verification key binary as ArrayBuffer, Uint8Array, or Buffer
463
430
  * @returns The verification result
431
+ * @throws {ApiError} If the API request fails
464
432
  */
465
433
  async verifyUploadedProof(proofBuffer, vkBuffer) {
466
434
  const proofBytes = proofBuffer instanceof Uint8Array ? proofBuffer : new Uint8Array(proofBuffer);
467
435
  const vkBytes = vkBuffer instanceof Uint8Array ? vkBuffer : new Uint8Array(vkBuffer);
468
436
  const proofBase64 = typeof Buffer !== "undefined" ? Buffer.from(proofBytes).toString("base64") : btoa(String.fromCharCode(...proofBytes));
469
437
  const vkBase64 = typeof Buffer !== "undefined" ? Buffer.from(vkBytes).toString("base64") : btoa(String.fromCharCode(...vkBytes));
470
- const response = await this.fetch("/api/verify/upload", {
438
+ return this.fetchJson("/api/verify/upload", {
471
439
  method: "POST",
472
440
  body: JSON.stringify({
473
441
  proof: proofBase64,
474
442
  vk: vkBase64
475
443
  })
476
444
  });
477
- return response.json();
478
445
  }
479
446
  /**
480
447
  * Get verification history for the authenticated organization
481
448
  * @param options - Pagination options
482
449
  * @returns Paginated list of verification results
450
+ * @throws {ApiError} If the API request fails
483
451
  */
484
452
  async getVerificationHistory(options = {}) {
485
453
  const params = new URLSearchParams();
@@ -487,8 +455,7 @@ var BindClient = class {
487
455
  if (options.offset !== void 0) params.set("offset", options.offset.toString());
488
456
  const queryString = params.toString();
489
457
  const path = queryString ? `/api/verify/history?${queryString}` : "/api/verify/history";
490
- const response = await this.fetch(path);
491
- return response.json();
458
+ return this.fetchJson(path);
492
459
  }
493
460
  // ==========================================================================
494
461
  // Private Helpers
@@ -504,8 +471,24 @@ var BindClient = class {
504
471
  if (response.status === 401) {
505
472
  throw new AuthenticationError();
506
473
  }
474
+ if (!response.ok) {
475
+ const body = await response.json().catch(() => ({}));
476
+ throw new ApiError(
477
+ body.error || `HTTP ${response.status}: ${response.statusText}`,
478
+ response.status,
479
+ body
480
+ );
481
+ }
507
482
  return response;
508
483
  }
484
+ async fetchJson(path, init) {
485
+ const response = await this.fetch(path, init);
486
+ const json = await response.json();
487
+ if (json.success === false) {
488
+ throw new ApiError(json.error || "Request failed", response.status, json);
489
+ }
490
+ return json.data ?? json;
491
+ }
509
492
  sleep(ms) {
510
493
  return new Promise((resolve) => setTimeout(resolve, ms));
511
494
  }