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