@bind-protocol/sdk 0.8.0 → 0.10.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 (40) hide show
  1. package/README.md +7 -11
  2. package/dist/{adapter-DBvPax2O.d.cts → adapter-BRj4bkLl.d.ts} +22 -8
  3. package/dist/{adapter-LeDOUfnn.d.ts → adapter-CNeHM6SQ.d.cts} +22 -8
  4. package/dist/adapters/dimo/index.cjs +26 -10
  5. package/dist/adapters/dimo/index.cjs.map +1 -1
  6. package/dist/adapters/dimo/index.d.cts +9 -3
  7. package/dist/adapters/dimo/index.d.ts +9 -3
  8. package/dist/adapters/dimo/index.js +26 -10
  9. package/dist/adapters/dimo/index.js.map +1 -1
  10. package/dist/adapters/index.cjs +139 -148
  11. package/dist/adapters/index.cjs.map +1 -1
  12. package/dist/adapters/index.d.cts +4 -4
  13. package/dist/adapters/index.d.ts +4 -4
  14. package/dist/adapters/index.js +139 -148
  15. package/dist/adapters/index.js.map +1 -1
  16. package/dist/adapters/zktls/index.cjs +113 -138
  17. package/dist/adapters/zktls/index.cjs.map +1 -1
  18. package/dist/adapters/zktls/index.d.cts +3 -3
  19. package/dist/adapters/zktls/index.d.ts +3 -3
  20. package/dist/adapters/zktls/index.js +113 -138
  21. package/dist/adapters/zktls/index.js.map +1 -1
  22. package/dist/{client-Dlp02kxb.d.cts → client-CfYXpFLk.d.cts} +70 -32
  23. package/dist/{client-BsloIjSG.d.ts → client-CpJ87Xe0.d.ts} +70 -32
  24. package/dist/core/index.cjs +107 -125
  25. package/dist/core/index.cjs.map +1 -1
  26. package/dist/core/index.d.cts +2 -2
  27. package/dist/core/index.d.ts +2 -2
  28. package/dist/core/index.js +107 -125
  29. package/dist/core/index.js.map +1 -1
  30. package/dist/index.cjs +139 -148
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +4 -4
  33. package/dist/index.d.ts +4 -4
  34. package/dist/index.js +139 -148
  35. package/dist/index.js.map +1 -1
  36. package/dist/{types-D5XJykY-.d.cts → types-BcPssdQk.d.cts} +30 -174
  37. package/dist/{types-D5XJykY-.d.ts → types-BcPssdQk.d.ts} +30 -174
  38. package/dist/{types-CXWgNPXN.d.ts → types-D7Q7ymPa.d.ts} +1 -1
  39. package/dist/{types-D-cTYE3o.d.cts → types-ywkMNwun.d.cts} +1 -1
  40. 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,84 +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) {
404
+ if (statusResult.status === "completed" || statusResult.status === "failed") {
429
405
  return {
430
- success: false,
431
- error: statusResult.error ?? "Failed to get verification status"
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
432
412
  };
433
413
  }
434
- const status = statusResult.data?.status;
435
- if (status === "completed" || status === "failed") {
436
- 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
- publicInputs: statusResult.data?.publicInputs
445
- }
446
- };
447
- }
448
- await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
414
+ await this.sleep(intervalMs);
449
415
  }
450
- return {
451
- success: false,
452
- error: `Verification timed out after ${maxWaitMs}ms. Job ID: ${jobId}`
453
- };
416
+ throw new TimeoutError(
417
+ `Verification timed out after ${timeoutMs}ms. Job ID: ${jobId}`,
418
+ timeoutMs
419
+ );
454
420
  }
455
421
  /**
456
422
  * Get the status of a verification job
457
423
  * @param jobId - The verification job ID
458
- * @returns The job status
424
+ * @returns The job status data
425
+ * @throws {ApiError} If the API request fails
459
426
  */
460
427
  async getVerifyJobStatus(jobId) {
461
- const response = await this.fetch(`/api/verify/jobs/${encodeURIComponent(jobId)}`);
462
- return response.json();
428
+ return this.fetchJson(`/api/verify/jobs/${encodeURIComponent(jobId)}`);
463
429
  }
464
430
  /**
465
431
  * Verify an uploaded proof
466
432
  * @param proofBuffer - The proof binary as ArrayBuffer, Uint8Array, or Buffer
467
433
  * @param vkBuffer - The verification key binary as ArrayBuffer, Uint8Array, or Buffer
468
434
  * @returns The verification result
435
+ * @throws {ApiError} If the API request fails
469
436
  */
470
437
  async verifyUploadedProof(proofBuffer, vkBuffer) {
471
438
  const proofBytes = proofBuffer instanceof Uint8Array ? proofBuffer : new Uint8Array(proofBuffer);
472
439
  const vkBytes = vkBuffer instanceof Uint8Array ? vkBuffer : new Uint8Array(vkBuffer);
473
440
  const proofBase64 = typeof Buffer !== "undefined" ? Buffer.from(proofBytes).toString("base64") : btoa(String.fromCharCode(...proofBytes));
474
441
  const vkBase64 = typeof Buffer !== "undefined" ? Buffer.from(vkBytes).toString("base64") : btoa(String.fromCharCode(...vkBytes));
475
- const response = await this.fetch("/api/verify/upload", {
442
+ return this.fetchJson("/api/verify/upload", {
476
443
  method: "POST",
477
444
  body: JSON.stringify({
478
445
  proof: proofBase64,
479
446
  vk: vkBase64
480
447
  })
481
448
  });
482
- return response.json();
483
449
  }
484
450
  /**
485
451
  * Get verification history for the authenticated organization
486
452
  * @param options - Pagination options
487
453
  * @returns Paginated list of verification results
454
+ * @throws {ApiError} If the API request fails
488
455
  */
489
456
  async getVerificationHistory(options = {}) {
490
457
  const params = new URLSearchParams();
@@ -492,8 +459,7 @@ var BindClient = class {
492
459
  if (options.offset !== void 0) params.set("offset", options.offset.toString());
493
460
  const queryString = params.toString();
494
461
  const path = queryString ? `/api/verify/history?${queryString}` : "/api/verify/history";
495
- const response = await this.fetch(path);
496
- return response.json();
462
+ return this.fetchJson(path);
497
463
  }
498
464
  // ==========================================================================
499
465
  // Private Helpers
@@ -509,8 +475,24 @@ var BindClient = class {
509
475
  if (response.status === 401) {
510
476
  throw new AuthenticationError();
511
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
+ }
512
486
  return response;
513
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
+ }
514
496
  sleep(ms) {
515
497
  return new Promise((resolve) => setTimeout(resolve, ms));
516
498
  }
@@ -525,12 +507,9 @@ function buildTelemetryQuery(vehicleTokenId, from, to) {
525
507
  from: ${from},
526
508
  to: ${to}
527
509
  ) {
528
- powertrainTransmissionTravelledDistance(agg: AVG)
529
- speed(agg: AVG)
530
- powertrainCombustionEngineSpeed(agg: AVG)
531
- obdEngineLoad(agg: AVG)
532
- obdDTCList(agg: UNIQUE)
533
- obdRunTime(agg: AVG)
510
+ powertrainTransmissionTravelledDistance(agg: SUM)
511
+ isIgnitionOn(agg: COUNT)
512
+ speed(agg: MAX)
534
513
  timestamp
535
514
  }
536
515
  }`;
@@ -557,7 +536,7 @@ ${signalLines}
557
536
 
558
537
  // src/adapters/dimo/adapter.ts
559
538
  var SUPPORTED_CIRCUITS = [
560
- "bind.mobility.riskband.v1"
539
+ "bind.dimo.riskband.v0_1_0"
561
540
  ];
562
541
  var DimoAdapter = class {
563
542
  id = "dimo";
@@ -590,7 +569,7 @@ var DimoAdapter = class {
590
569
  );
591
570
  }
592
571
  switch (circuitId) {
593
- case "bind.mobility.riskband.v1":
572
+ case "bind.dimo.riskband.v0_1_0":
594
573
  return this.toRiskBandInputs(data);
595
574
  default:
596
575
  throw new Error(`No input transformer for circuit: ${circuitId}`);
@@ -605,10 +584,29 @@ var DimoAdapter = class {
605
584
  // ===========================================================================
606
585
  // Private transformers
607
586
  // ===========================================================================
587
+ /**
588
+ * Aggregate hourly telemetry rows into the three circuit inputs
589
+ * required by bind.mobility.basicriskband:
590
+ *
591
+ * mileage_90d (u32) — SUM of powertrainTransmissionTravelledDistance
592
+ * data_points (u32) — COUNT of isIgnitionOn (sum of per-hour counts)
593
+ * speed_max (u16) — MAX of speed
594
+ */
608
595
  toRiskBandInputs(data) {
596
+ let mileageSum = 0;
597
+ let dataPointsSum = 0;
598
+ let speedMax = 0;
599
+ for (const row of data.signals) {
600
+ mileageSum += row.powertrainTransmissionTravelledDistance ?? 0;
601
+ dataPointsSum += row.isIgnitionOn ?? 0;
602
+ if ((row.speed ?? 0) > speedMax) {
603
+ speedMax = row.speed;
604
+ }
605
+ }
609
606
  return {
610
- signals: JSON.stringify(data.signals),
611
- timestamp: data.timestamp
607
+ mileage_90d: String(Math.round(mileageSum)),
608
+ data_points: String(Math.round(dataPointsSum)),
609
+ speed_max: String(Math.round(speedMax))
612
610
  };
613
611
  }
614
612
  };
@@ -648,11 +646,7 @@ var ZkTlsAdapter = class {
648
646
  * Client should redirect user to this URL
649
647
  */
650
648
  async createSession(callbackUrl) {
651
- const result = await this.client.createZkTlsSession(this.extractorId, callbackUrl);
652
- if (!result.success || !result.data) {
653
- throw new Error(result.error || "Failed to create zkTLS session");
654
- }
655
- return result.data;
649
+ return this.client.createZkTlsSession(this.extractorId, callbackUrl);
656
650
  }
657
651
  /**
658
652
  * Wait for session completion and return attestation
@@ -663,7 +657,7 @@ var ZkTlsAdapter = class {
663
657
  throw new Error("Session completed but no attestation found");
664
658
  }
665
659
  const extractors = await this.client.listExtractors();
666
- const extractor = extractors.data?.find((e) => e.id === this.extractorId);
660
+ const extractor = extractors.find((e) => e.id === this.extractorId);
667
661
  if (!extractor) {
668
662
  throw new Error(`Extractor not found: ${this.extractorId}`);
669
663
  }
@@ -676,17 +670,14 @@ var ZkTlsAdapter = class {
676
670
  // Protected helpers
677
671
  // ===========================================================================
678
672
  async fetchExistingAttestation(attestationId) {
679
- const result = await this.client.getAttestation(attestationId);
680
- if (!result.success || !result.data) {
681
- throw new Error(result.error || "Attestation not found");
682
- }
673
+ const attestation = await this.client.getAttestation(attestationId);
683
674
  const extractors = await this.client.listExtractors();
684
- const extractor = extractors.data?.find((e) => e.id === result.data.extractor);
675
+ const extractor = extractors.find((e) => e.id === attestation.extractor);
685
676
  if (!extractor) {
686
- throw new Error(`Extractor not found: ${result.data.extractor}`);
677
+ throw new Error(`Extractor not found: ${attestation.extractor}`);
687
678
  }
688
679
  return {
689
- attestation: result.data,
680
+ attestation,
690
681
  extractor
691
682
  };
692
683
  }