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