@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
package/dist/index.js CHANGED
@@ -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,84 +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) {
425
- return {
426
- success: false,
427
- error: statusResult.error ?? "Failed to get verification status"
428
- };
429
- }
430
- const status = statusResult.data?.status;
431
- if (status === "completed" || status === "failed") {
400
+ if (statusResult.status === "completed" || statusResult.status === "failed") {
432
401
  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
- publicInputs: statusResult.data?.publicInputs
441
- }
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
442
408
  };
443
409
  }
444
- await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
410
+ await this.sleep(intervalMs);
445
411
  }
446
- return {
447
- success: false,
448
- error: `Verification timed out after ${maxWaitMs}ms. Job ID: ${jobId}`
449
- };
412
+ throw new TimeoutError(
413
+ `Verification timed out after ${timeoutMs}ms. Job ID: ${jobId}`,
414
+ timeoutMs
415
+ );
450
416
  }
451
417
  /**
452
418
  * Get the status of a verification job
453
419
  * @param jobId - The verification job ID
454
- * @returns The job status
420
+ * @returns The job status data
421
+ * @throws {ApiError} If the API request fails
455
422
  */
456
423
  async getVerifyJobStatus(jobId) {
457
- const response = await this.fetch(`/api/verify/jobs/${encodeURIComponent(jobId)}`);
458
- return response.json();
424
+ return this.fetchJson(`/api/verify/jobs/${encodeURIComponent(jobId)}`);
459
425
  }
460
426
  /**
461
427
  * Verify an uploaded proof
462
428
  * @param proofBuffer - The proof binary as ArrayBuffer, Uint8Array, or Buffer
463
429
  * @param vkBuffer - The verification key binary as ArrayBuffer, Uint8Array, or Buffer
464
430
  * @returns The verification result
431
+ * @throws {ApiError} If the API request fails
465
432
  */
466
433
  async verifyUploadedProof(proofBuffer, vkBuffer) {
467
434
  const proofBytes = proofBuffer instanceof Uint8Array ? proofBuffer : new Uint8Array(proofBuffer);
468
435
  const vkBytes = vkBuffer instanceof Uint8Array ? vkBuffer : new Uint8Array(vkBuffer);
469
436
  const proofBase64 = typeof Buffer !== "undefined" ? Buffer.from(proofBytes).toString("base64") : btoa(String.fromCharCode(...proofBytes));
470
437
  const vkBase64 = typeof Buffer !== "undefined" ? Buffer.from(vkBytes).toString("base64") : btoa(String.fromCharCode(...vkBytes));
471
- const response = await this.fetch("/api/verify/upload", {
438
+ return this.fetchJson("/api/verify/upload", {
472
439
  method: "POST",
473
440
  body: JSON.stringify({
474
441
  proof: proofBase64,
475
442
  vk: vkBase64
476
443
  })
477
444
  });
478
- return response.json();
479
445
  }
480
446
  /**
481
447
  * Get verification history for the authenticated organization
482
448
  * @param options - Pagination options
483
449
  * @returns Paginated list of verification results
450
+ * @throws {ApiError} If the API request fails
484
451
  */
485
452
  async getVerificationHistory(options = {}) {
486
453
  const params = new URLSearchParams();
@@ -488,8 +455,7 @@ var BindClient = class {
488
455
  if (options.offset !== void 0) params.set("offset", options.offset.toString());
489
456
  const queryString = params.toString();
490
457
  const path = queryString ? `/api/verify/history?${queryString}` : "/api/verify/history";
491
- const response = await this.fetch(path);
492
- return response.json();
458
+ return this.fetchJson(path);
493
459
  }
494
460
  // ==========================================================================
495
461
  // Private Helpers
@@ -505,8 +471,24 @@ var BindClient = class {
505
471
  if (response.status === 401) {
506
472
  throw new AuthenticationError();
507
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
+ }
508
482
  return response;
509
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
+ }
510
492
  sleep(ms) {
511
493
  return new Promise((resolve) => setTimeout(resolve, ms));
512
494
  }
@@ -644,11 +626,7 @@ var ZkTlsAdapter = class {
644
626
  * Client should redirect user to this URL
645
627
  */
646
628
  async createSession(callbackUrl) {
647
- const result = await this.client.createZkTlsSession(this.extractorId, callbackUrl);
648
- if (!result.success || !result.data) {
649
- throw new Error(result.error || "Failed to create zkTLS session");
650
- }
651
- return result.data;
629
+ return this.client.createZkTlsSession(this.extractorId, callbackUrl);
652
630
  }
653
631
  /**
654
632
  * Wait for session completion and return attestation
@@ -659,7 +637,7 @@ var ZkTlsAdapter = class {
659
637
  throw new Error("Session completed but no attestation found");
660
638
  }
661
639
  const extractors = await this.client.listExtractors();
662
- const extractor = extractors.data?.find((e) => e.id === this.extractorId);
640
+ const extractor = extractors.find((e) => e.id === this.extractorId);
663
641
  if (!extractor) {
664
642
  throw new Error(`Extractor not found: ${this.extractorId}`);
665
643
  }
@@ -672,17 +650,14 @@ var ZkTlsAdapter = class {
672
650
  // Protected helpers
673
651
  // ===========================================================================
674
652
  async fetchExistingAttestation(attestationId) {
675
- const result = await this.client.getAttestation(attestationId);
676
- if (!result.success || !result.data) {
677
- throw new Error(result.error || "Attestation not found");
678
- }
653
+ const attestation = await this.client.getAttestation(attestationId);
679
654
  const extractors = await this.client.listExtractors();
680
- const extractor = extractors.data?.find((e) => e.id === result.data.extractor);
655
+ const extractor = extractors.find((e) => e.id === attestation.extractor);
681
656
  if (!extractor) {
682
- throw new Error(`Extractor not found: ${result.data.extractor}`);
657
+ throw new Error(`Extractor not found: ${attestation.extractor}`);
683
658
  }
684
659
  return {
685
- attestation: result.data,
660
+ attestation,
686
661
  extractor
687
662
  };
688
663
  }