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