@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/dist/index.cjs CHANGED
@@ -100,33 +100,42 @@ var BindClient = class {
100
100
  * @throws {InsufficientCreditsError} If there aren't enough credits
101
101
  */
102
102
  async submitProveJob(circuitId, inputs, options) {
103
- const response = await this.fetch("/api/prove", {
104
- method: "POST",
105
- body: JSON.stringify({
106
- circuitId,
107
- inputs,
108
- verificationMode: options?.verificationMode
109
- })
110
- });
111
- const result = await response.json();
112
- if (!result.success && result.requiredCredits !== void 0 && result.availableCredits !== void 0) {
113
- throw new InsufficientCreditsError(result.requiredCredits, result.availableCredits);
103
+ try {
104
+ return await this.fetchJson("/api/prove", {
105
+ method: "POST",
106
+ body: JSON.stringify({
107
+ circuitId,
108
+ inputs,
109
+ verificationMode: options?.verificationMode
110
+ })
111
+ });
112
+ } catch (err) {
113
+ if (err instanceof ApiError && err.response) {
114
+ const body = err.response;
115
+ if (body.requiredCredits !== void 0 && body.availableCredits !== void 0) {
116
+ throw new InsufficientCreditsError(
117
+ body.requiredCredits,
118
+ body.availableCredits
119
+ );
120
+ }
121
+ }
122
+ throw err;
114
123
  }
115
- return result;
116
124
  }
117
125
  /**
118
126
  * Get the status and results of a prove job
119
127
  * @param jobId - The unique job identifier
120
128
  * @returns The job details including status and outputs
129
+ * @throws {ApiError} If the API request fails
121
130
  */
122
131
  async getProveJob(jobId) {
123
- const response = await this.fetch(`/api/prove/${encodeURIComponent(jobId)}`);
124
- return response.json();
132
+ return this.fetchJson(`/api/prove/${encodeURIComponent(jobId)}`);
125
133
  }
126
134
  /**
127
135
  * List prove jobs for the authenticated organization
128
136
  * @param options - Optional filters for status, limit, and offset
129
137
  * @returns Paginated list of prove jobs
138
+ * @throws {ApiError} If the API request fails
130
139
  */
131
140
  async listProveJobs(options = {}) {
132
141
  const params = new URLSearchParams();
@@ -135,8 +144,7 @@ var BindClient = class {
135
144
  if (options.offset !== void 0) params.set("offset", options.offset.toString());
136
145
  const queryString = params.toString();
137
146
  const path = queryString ? `/api/prove?${queryString}` : "/api/prove";
138
- const response = await this.fetch(path);
139
- return response.json();
147
+ return this.fetchJson(path);
140
148
  }
141
149
  /**
142
150
  * Poll for prove job completion
@@ -144,21 +152,14 @@ var BindClient = class {
144
152
  * @param options - Polling options
145
153
  * @returns The completed or failed job
146
154
  * @throws {TimeoutError} If the job doesn't complete within the timeout
155
+ * @throws {ApiError} If the API request fails
147
156
  */
148
157
  async waitForProveJob(jobId, options = {}) {
149
158
  const intervalMs = options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
150
159
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
151
160
  const startTime = Date.now();
152
161
  while (Date.now() - startTime < timeoutMs) {
153
- const result = await this.getProveJob(jobId);
154
- if (!result.success || !result.data) {
155
- throw new ApiError(
156
- result.error || "Failed to get prove job",
157
- 500,
158
- result
159
- );
160
- }
161
- const job = result.data;
162
+ const job = await this.getProveJob(jobId);
162
163
  if (options.onProgress) {
163
164
  options.onProgress(job);
164
165
  }
@@ -178,41 +179,28 @@ var BindClient = class {
178
179
  /**
179
180
  * List all available public policies
180
181
  * @returns Array of public policy specifications
182
+ * @throws {ApiError} If the API request fails
181
183
  */
182
184
  async listPolicies() {
183
- const response = await fetch(`${this.baseUrl}/api/policies`, {
184
- method: "GET"
185
- });
186
- if (!response.ok) {
187
- throw new ApiError(
188
- `Failed to fetch policies: ${response.statusText}`,
189
- response.status
190
- );
191
- }
192
- const json = await response.json();
193
- return json.data ?? json;
185
+ return this.fetchJson("/api/policies");
194
186
  }
195
187
  /**
196
188
  * Get a specific policy by ID
197
189
  * @param policyId - The unique policy identifier
198
190
  * @returns The public policy specification, or null if not found
191
+ * @throws {ApiError} If the API request fails (except 404)
199
192
  */
200
193
  async getPolicy(policyId) {
201
- const response = await fetch(
202
- `${this.baseUrl}/api/policies/${encodeURIComponent(policyId)}`,
203
- { method: "GET" }
204
- );
205
- if (response.status === 404) {
206
- return null;
207
- }
208
- if (!response.ok) {
209
- throw new ApiError(
210
- `Failed to fetch policy: ${response.statusText}`,
211
- response.status
194
+ try {
195
+ return await this.fetchJson(
196
+ `/api/policies/${encodeURIComponent(policyId)}`
212
197
  );
198
+ } catch (err) {
199
+ if (err instanceof ApiError && err.status === 404) {
200
+ return null;
201
+ }
202
+ throw err;
213
203
  }
214
- const json = await response.json();
215
- return json.data ?? json;
216
204
  }
217
205
  // ==========================================================================
218
206
  // zkTLS Methods
@@ -220,49 +208,49 @@ var BindClient = class {
220
208
  /**
221
209
  * List available zkTLS extractors (data sources)
222
210
  * @returns Array of available extractors
211
+ * @throws {ApiError} If the API request fails
223
212
  */
224
213
  async listExtractors() {
225
- const response = await this.fetch("/api/zktls/extractors");
226
- return response.json();
214
+ return this.fetchJson("/api/zktls/extractors");
227
215
  }
228
216
  /**
229
217
  * List zkTLS attestations for the authenticated organization
230
218
  * @returns Array of attestations
219
+ * @throws {ApiError} If the API request fails
231
220
  */
232
221
  async listAttestations() {
233
- const response = await this.fetch("/api/zktls/attestations");
234
- return response.json();
222
+ return this.fetchJson("/api/zktls/attestations");
235
223
  }
236
224
  /**
237
225
  * Get a specific attestation by ID
238
226
  * @param attestationId - The attestation UUID
239
- * @returns The attestation or null if not found
227
+ * @returns The attestation details
228
+ * @throws {ApiError} If the API request fails
240
229
  */
241
230
  async getAttestation(attestationId) {
242
- const response = await this.fetch(`/api/zktls/attestations/${encodeURIComponent(attestationId)}`);
243
- return response.json();
231
+ return this.fetchJson(`/api/zktls/attestations/${encodeURIComponent(attestationId)}`);
244
232
  }
245
233
  /**
246
234
  * Create a new zkTLS session for data attestation
247
235
  * @param extractorId - The extractor to use (e.g., "coinbase")
248
236
  * @param callbackUrl - URL to redirect to after authentication
249
237
  * @returns Session ID and auth URL to redirect user to
238
+ * @throws {ApiError} If the API request fails
250
239
  */
251
240
  async createZkTlsSession(extractorId, callbackUrl) {
252
- const response = await this.fetch("/api/zktls/sessions", {
241
+ return this.fetchJson("/api/zktls/sessions", {
253
242
  method: "POST",
254
243
  body: JSON.stringify({ extractor: extractorId, callbackUrl })
255
244
  });
256
- return response.json();
257
245
  }
258
246
  /**
259
247
  * Get the status of a zkTLS session
260
248
  * @param sessionId - The session UUID
261
249
  * @returns Session status and attestation if completed
250
+ * @throws {ApiError} If the API request fails
262
251
  */
263
252
  async getZkTlsSession(sessionId) {
264
- const response = await this.fetch(`/api/zktls/sessions/${encodeURIComponent(sessionId)}`);
265
- return response.json();
253
+ return this.fetchJson(`/api/zktls/sessions/${encodeURIComponent(sessionId)}`);
266
254
  }
267
255
  /**
268
256
  * Wait for a zkTLS session to complete
@@ -272,21 +260,14 @@ var BindClient = class {
272
260
  * @throws {ZkTlsSessionExpiredError} If session expires
273
261
  * @throws {ZkTlsSessionFailedError} If session fails
274
262
  * @throws {TimeoutError} If timeout is reached
263
+ * @throws {ApiError} If the API request fails
275
264
  */
276
265
  async waitForZkTlsSession(sessionId, options = {}) {
277
266
  const intervalMs = options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
278
267
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
279
268
  const startTime = Date.now();
280
269
  while (Date.now() - startTime < timeoutMs) {
281
- const result = await this.getZkTlsSession(sessionId);
282
- if (!result.success || !result.data) {
283
- throw new ApiError(
284
- result.error || "Failed to get zkTLS session",
285
- 500,
286
- result
287
- );
288
- }
289
- const session = result.data;
270
+ const session = await this.getZkTlsSession(sessionId);
290
271
  if (options.onProgress) {
291
272
  options.onProgress(session);
292
273
  }
@@ -313,6 +294,7 @@ var BindClient = class {
313
294
  * List available circuits
314
295
  * @param options - Optional filters
315
296
  * @returns Array of circuits
297
+ * @throws {ApiError} If the API request fails
316
298
  */
317
299
  async listCircuits(options = {}) {
318
300
  const params = new URLSearchParams();
@@ -320,28 +302,27 @@ var BindClient = class {
320
302
  if (options.policyId) params.set("policyId", options.policyId);
321
303
  const queryString = params.toString();
322
304
  const path = queryString ? `/api/circuits?${queryString}` : "/api/circuits";
323
- const response = await this.fetch(path);
324
- return response.json();
305
+ return this.fetchJson(path);
325
306
  }
326
307
  /**
327
308
  * Get a specific circuit by ID
328
309
  * @param circuitId - The circuit identifier
329
- * @returns The circuit details or null if not found
310
+ * @returns The circuit details
311
+ * @throws {ApiError} If the API request fails
330
312
  */
331
313
  async getCircuit(circuitId) {
332
- const response = await this.fetch(`/api/circuits/${encodeURIComponent(circuitId)}`);
333
- return response.json();
314
+ return this.fetchJson(`/api/circuits/${encodeURIComponent(circuitId)}`);
334
315
  }
335
316
  /**
336
317
  * Activate a circuit (requires validation to have passed)
337
318
  * @param circuitId - The circuit identifier to activate
338
319
  * @returns The activation result
320
+ * @throws {ApiError} If the API request fails
339
321
  */
340
322
  async activateCircuit(circuitId) {
341
- const response = await this.fetch(`/api/circuits/${encodeURIComponent(circuitId)}/activate`, {
323
+ return this.fetchJson(`/api/circuits/${encodeURIComponent(circuitId)}/activate`, {
342
324
  method: "POST"
343
325
  });
344
- return response.json();
345
326
  }
346
327
  // ==========================================================================
347
328
  // Shared Proof Methods
@@ -350,18 +331,19 @@ var BindClient = class {
350
331
  * Share a completed proof with a verifier organization
351
332
  * @param request - Share proof request with proveJobId and verifierOrgId
352
333
  * @returns The created shared proof
334
+ * @throws {ApiError} If the API request fails
353
335
  */
354
336
  async shareProof(request) {
355
- const response = await this.fetch("/api/shared-proofs", {
337
+ return this.fetchJson("/api/shared-proofs", {
356
338
  method: "POST",
357
339
  body: JSON.stringify(request)
358
340
  });
359
- return response.json();
360
341
  }
361
342
  /**
362
343
  * List shared proofs (outgoing or incoming)
363
344
  * @param options - Filter by direction, pagination, and inclusion options
364
345
  * @returns Paginated list of shared proofs
346
+ * @throws {ApiError} If the API request fails
365
347
  */
366
348
  async listSharedProofs(options = {}) {
367
349
  const params = new URLSearchParams();
@@ -372,28 +354,27 @@ var BindClient = class {
372
354
  if (options.includeRevoked) params.set("includeRevoked", "true");
373
355
  const queryString = params.toString();
374
356
  const path = queryString ? `/api/shared-proofs?${queryString}` : "/api/shared-proofs";
375
- const response = await this.fetch(path);
376
- return response.json();
357
+ return this.fetchJson(path);
377
358
  }
378
359
  /**
379
360
  * Get a specific shared proof by ID
380
361
  * @param sharedProofId - The shared proof ID
381
362
  * @returns The shared proof details
363
+ * @throws {ApiError} If the API request fails
382
364
  */
383
365
  async getSharedProof(sharedProofId) {
384
- const response = await this.fetch(`/api/shared-proofs/${encodeURIComponent(sharedProofId)}`);
385
- return response.json();
366
+ return this.fetchJson(`/api/shared-proofs/${encodeURIComponent(sharedProofId)}`);
386
367
  }
387
368
  /**
388
369
  * Revoke a shared proof. Only the sharing organization can revoke.
389
370
  * @param sharedProofId - The shared proof ID to revoke
390
371
  * @returns The revocation result
372
+ * @throws {ApiError} If the API request fails
391
373
  */
392
374
  async revokeSharedProof(sharedProofId) {
393
- const response = await this.fetch(`/api/shared-proofs/${encodeURIComponent(sharedProofId)}`, {
375
+ return this.fetchJson(`/api/shared-proofs/${encodeURIComponent(sharedProofId)}`, {
394
376
  method: "DELETE"
395
377
  });
396
- return response.json();
397
378
  }
398
379
  // ==========================================================================
399
380
  // Verification Methods
@@ -407,83 +388,70 @@ var BindClient = class {
407
388
  * @param sharedProofId - The shared proof ID to verify
408
389
  * @param options - Optional polling configuration
409
390
  * @returns The verification result
391
+ * @throws {ApiError} If the API request fails
392
+ * @throws {TimeoutError} If verification doesn't complete within the timeout
410
393
  */
411
394
  async verifySharedProof(sharedProofId, options) {
412
- const pollIntervalMs = options?.pollIntervalMs ?? 1e3;
413
- const maxWaitMs = options?.maxWaitMs ?? 12e4;
414
- const queueResponse = await this.fetch(`/api/verify/shared/${encodeURIComponent(sharedProofId)}`, {
395
+ const intervalMs = options?.intervalMs ?? 1e3;
396
+ const timeoutMs = options?.timeoutMs ?? 12e4;
397
+ const queueResult = await this.fetchJson(`/api/verify/shared/${encodeURIComponent(sharedProofId)}`, {
415
398
  method: "POST"
416
399
  });
417
- const queueResult = await queueResponse.json();
418
- if (!queueResult.success || !queueResult.data?.jobId) {
419
- return {
420
- success: false,
421
- error: queueResult.error ?? "Failed to queue verification job"
422
- };
423
- }
424
- const jobId = queueResult.data.jobId;
400
+ const jobId = queueResult.jobId;
425
401
  const startTime = Date.now();
426
- while (Date.now() - startTime < maxWaitMs) {
402
+ while (Date.now() - startTime < timeoutMs) {
427
403
  const statusResult = await this.getVerifyJobStatus(jobId);
428
- if (!statusResult.success) {
429
- return {
430
- success: false,
431
- error: statusResult.error ?? "Failed to get verification status"
432
- };
433
- }
434
- const status = statusResult.data?.status;
435
- if (status === "completed" || status === "failed") {
404
+ if (statusResult.status === "completed" || statusResult.status === "failed") {
436
405
  return {
437
- success: true,
438
- data: {
439
- isValid: statusResult.data?.isValid ?? false,
440
- error: statusResult.data?.error,
441
- verificationTimeMs: statusResult.data?.verificationTimeMs ?? 0,
442
- creditsCharged: statusResult.data?.creditsCharged ?? queueResult.data.creditsCharged,
443
- verificationResultId: statusResult.data?.verificationResultId ?? jobId
444
- }
406
+ isValid: statusResult.isValid ?? false,
407
+ error: statusResult.error,
408
+ verificationTimeMs: statusResult.verificationTimeMs ?? 0,
409
+ creditsCharged: statusResult.creditsCharged ?? queueResult.creditsCharged,
410
+ verificationResultId: statusResult.verificationResultId ?? jobId,
411
+ publicInputs: statusResult.publicInputs
445
412
  };
446
413
  }
447
- await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
414
+ await this.sleep(intervalMs);
448
415
  }
449
- return {
450
- success: false,
451
- error: `Verification timed out after ${maxWaitMs}ms. Job ID: ${jobId}`
452
- };
416
+ throw new TimeoutError(
417
+ `Verification timed out after ${timeoutMs}ms. Job ID: ${jobId}`,
418
+ timeoutMs
419
+ );
453
420
  }
454
421
  /**
455
422
  * Get the status of a verification job
456
423
  * @param jobId - The verification job ID
457
- * @returns The job status
424
+ * @returns The job status data
425
+ * @throws {ApiError} If the API request fails
458
426
  */
459
427
  async getVerifyJobStatus(jobId) {
460
- const response = await this.fetch(`/api/verify/jobs/${encodeURIComponent(jobId)}`);
461
- return response.json();
428
+ return this.fetchJson(`/api/verify/jobs/${encodeURIComponent(jobId)}`);
462
429
  }
463
430
  /**
464
431
  * Verify an uploaded proof
465
432
  * @param proofBuffer - The proof binary as ArrayBuffer, Uint8Array, or Buffer
466
433
  * @param vkBuffer - The verification key binary as ArrayBuffer, Uint8Array, or Buffer
467
434
  * @returns The verification result
435
+ * @throws {ApiError} If the API request fails
468
436
  */
469
437
  async verifyUploadedProof(proofBuffer, vkBuffer) {
470
438
  const proofBytes = proofBuffer instanceof Uint8Array ? proofBuffer : new Uint8Array(proofBuffer);
471
439
  const vkBytes = vkBuffer instanceof Uint8Array ? vkBuffer : new Uint8Array(vkBuffer);
472
440
  const proofBase64 = typeof Buffer !== "undefined" ? Buffer.from(proofBytes).toString("base64") : btoa(String.fromCharCode(...proofBytes));
473
441
  const vkBase64 = typeof Buffer !== "undefined" ? Buffer.from(vkBytes).toString("base64") : btoa(String.fromCharCode(...vkBytes));
474
- const response = await this.fetch("/api/verify/upload", {
442
+ return this.fetchJson("/api/verify/upload", {
475
443
  method: "POST",
476
444
  body: JSON.stringify({
477
445
  proof: proofBase64,
478
446
  vk: vkBase64
479
447
  })
480
448
  });
481
- return response.json();
482
449
  }
483
450
  /**
484
451
  * Get verification history for the authenticated organization
485
452
  * @param options - Pagination options
486
453
  * @returns Paginated list of verification results
454
+ * @throws {ApiError} If the API request fails
487
455
  */
488
456
  async getVerificationHistory(options = {}) {
489
457
  const params = new URLSearchParams();
@@ -491,8 +459,7 @@ var BindClient = class {
491
459
  if (options.offset !== void 0) params.set("offset", options.offset.toString());
492
460
  const queryString = params.toString();
493
461
  const path = queryString ? `/api/verify/history?${queryString}` : "/api/verify/history";
494
- const response = await this.fetch(path);
495
- return response.json();
462
+ return this.fetchJson(path);
496
463
  }
497
464
  // ==========================================================================
498
465
  // Private Helpers
@@ -508,8 +475,24 @@ var BindClient = class {
508
475
  if (response.status === 401) {
509
476
  throw new AuthenticationError();
510
477
  }
478
+ if (!response.ok) {
479
+ const body = await response.json().catch(() => ({}));
480
+ throw new ApiError(
481
+ body.error || `HTTP ${response.status}: ${response.statusText}`,
482
+ response.status,
483
+ body
484
+ );
485
+ }
511
486
  return response;
512
487
  }
488
+ async fetchJson(path, init) {
489
+ const response = await this.fetch(path, init);
490
+ const json = await response.json();
491
+ if (json.success === false) {
492
+ throw new ApiError(json.error || "Request failed", response.status, json);
493
+ }
494
+ return json.data ?? json;
495
+ }
513
496
  sleep(ms) {
514
497
  return new Promise((resolve) => setTimeout(resolve, ms));
515
498
  }
@@ -647,11 +630,7 @@ var ZkTlsAdapter = class {
647
630
  * Client should redirect user to this URL
648
631
  */
649
632
  async createSession(callbackUrl) {
650
- const result = await this.client.createZkTlsSession(this.extractorId, callbackUrl);
651
- if (!result.success || !result.data) {
652
- throw new Error(result.error || "Failed to create zkTLS session");
653
- }
654
- return result.data;
633
+ return this.client.createZkTlsSession(this.extractorId, callbackUrl);
655
634
  }
656
635
  /**
657
636
  * Wait for session completion and return attestation
@@ -662,7 +641,7 @@ var ZkTlsAdapter = class {
662
641
  throw new Error("Session completed but no attestation found");
663
642
  }
664
643
  const extractors = await this.client.listExtractors();
665
- const extractor = extractors.data?.find((e) => e.id === this.extractorId);
644
+ const extractor = extractors.find((e) => e.id === this.extractorId);
666
645
  if (!extractor) {
667
646
  throw new Error(`Extractor not found: ${this.extractorId}`);
668
647
  }
@@ -675,17 +654,14 @@ var ZkTlsAdapter = class {
675
654
  // Protected helpers
676
655
  // ===========================================================================
677
656
  async fetchExistingAttestation(attestationId) {
678
- const result = await this.client.getAttestation(attestationId);
679
- if (!result.success || !result.data) {
680
- throw new Error(result.error || "Attestation not found");
681
- }
657
+ const attestation = await this.client.getAttestation(attestationId);
682
658
  const extractors = await this.client.listExtractors();
683
- const extractor = extractors.data?.find((e) => e.id === result.data.extractor);
659
+ const extractor = extractors.find((e) => e.id === attestation.extractor);
684
660
  if (!extractor) {
685
- throw new Error(`Extractor not found: ${result.data.extractor}`);
661
+ throw new Error(`Extractor not found: ${attestation.extractor}`);
686
662
  }
687
663
  return {
688
- attestation: result.data,
664
+ attestation,
689
665
  extractor
690
666
  };
691
667
  }