@iam-protocol/pulse-sdk 0.3.5 → 0.3.6

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iam-protocol/pulse-sdk",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "description": "Client-side SDK for IAM Protocol — sensor capture, TBH generation, ZK proof construction",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
package/src/pulse.ts CHANGED
@@ -92,6 +92,19 @@ async function processSensorData(
92
92
  };
93
93
  }
94
94
 
95
+ // Re-verification requires audio + at least one other modality.
96
+ // Audio-only fingerprints lack inter-session variance from motion/touch,
97
+ // producing identical SimHash results that fail the min_distance constraint.
98
+ const hasPreviousData = loadVerificationData() !== null;
99
+ if (hasPreviousData && !hasMotion && !hasTouch) {
100
+ return {
101
+ success: false,
102
+ commitment: new Uint8Array(32),
103
+ isFirstVerification: false,
104
+ error: "Insufficient sensor data for re-verification. Please trace the curve and allow motion access.",
105
+ };
106
+ }
107
+
95
108
  // Extract features
96
109
  const features = await extractFeatures(sensorData);
97
110
 
@@ -432,30 +445,30 @@ export class PulseSDK {
432
445
  const session = this.createSession(touchElement);
433
446
  const stopPromises: Promise<void>[] = [];
434
447
 
435
- // Audio
448
+ // Motion first — requires user gesture on iOS (gesture expires after getUserMedia)
436
449
  try {
437
- await session.startAudio();
450
+ await session.startMotion();
451
+ } catch {
452
+ /* unexpected error — motion already skipped or idle */
453
+ }
454
+ if (session.isMotionCapturing()) {
438
455
  stopPromises.push(
439
456
  new Promise<void>((r) => setTimeout(r, DEFAULT_CAPTURE_MS))
440
- .then(() => session.stopAudio())
457
+ .then(() => session.stopMotion())
441
458
  .then(() => {})
442
459
  );
443
- } catch (err: any) {
444
- throw new Error(`Audio capture failed: ${err?.message ?? "microphone unavailable"}`);
445
460
  }
446
461
 
447
- // MotionstartMotion auto-skips if permission denied (no throw)
462
+ // Audio second getUserMedia works without a gesture on secure origins
448
463
  try {
449
- await session.startMotion();
450
- } catch {
451
- /* unexpected error — motion already skipped or idle */
452
- }
453
- if (session.isMotionCapturing()) {
464
+ await session.startAudio();
454
465
  stopPromises.push(
455
466
  new Promise<void>((r) => setTimeout(r, DEFAULT_CAPTURE_MS))
456
- .then(() => session.stopMotion())
467
+ .then(() => session.stopAudio())
457
468
  .then(() => {})
458
469
  );
470
+ } catch (err: any) {
471
+ throw new Error(`Audio capture failed: ${err?.message ?? "microphone unavailable"}`);
459
472
  }
460
473
 
461
474
  // Touch