@iam-protocol/pulse-sdk 0.2.1 → 0.2.2

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/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # @iam-protocol/pulse-sdk
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@iam-protocol/pulse-sdk.svg)](https://www.npmjs.com/package/@iam-protocol/pulse-sdk)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@iam-protocol/pulse-sdk.svg)](https://www.npmjs.com/package/@iam-protocol/pulse-sdk)
5
+
3
6
  Client-side SDK for the IAM Protocol. Captures behavioral biometrics (voice, motion, touch), generates a Temporal-Biometric Hash, produces a Groth16 zero-knowledge proof, and submits it for on-chain verification on Solana.
4
7
 
5
8
  ## Install
package/dist/index.d.mts CHANGED
@@ -51,6 +51,8 @@ interface CaptureOptions {
51
51
  minDurationMs?: number;
52
52
  /** Maximum capture duration in ms. Auto-stops if signal hasn't fired. Default: 60000 */
53
53
  maxDurationMs?: number;
54
+ /** Called with RMS audio level (0-1) on each buffer during audio capture (~4x per second). */
55
+ onAudioLevel?: (rms: number) => void;
54
56
  }
55
57
  /** Stage of a capture session */
56
58
  type CaptureStage = "audio" | "motion" | "touch";
@@ -119,7 +121,7 @@ declare class PulseSession {
119
121
  private motionData;
120
122
  private touchData;
121
123
  constructor(config: ResolvedConfig, touchElement?: HTMLElement);
122
- startAudio(): Promise<void>;
124
+ startAudio(onAudioLevel?: (rms: number) => void): Promise<void>;
123
125
  stopAudio(): Promise<AudioCapture | null>;
124
126
  skipAudio(): void;
125
127
  startMotion(): Promise<void>;
package/dist/index.d.ts CHANGED
@@ -51,6 +51,8 @@ interface CaptureOptions {
51
51
  minDurationMs?: number;
52
52
  /** Maximum capture duration in ms. Auto-stops if signal hasn't fired. Default: 60000 */
53
53
  maxDurationMs?: number;
54
+ /** Called with RMS audio level (0-1) on each buffer during audio capture (~4x per second). */
55
+ onAudioLevel?: (rms: number) => void;
54
56
  }
55
57
  /** Stage of a capture session */
56
58
  type CaptureStage = "audio" | "motion" | "touch";
@@ -119,7 +121,7 @@ declare class PulseSession {
119
121
  private motionData;
120
122
  private touchData;
121
123
  constructor(config: ResolvedConfig, touchElement?: HTMLElement);
122
- startAudio(): Promise<void>;
124
+ startAudio(onAudioLevel?: (rms: number) => void): Promise<void>;
123
125
  stopAudio(): Promise<AudioCapture | null>;
124
126
  skipAudio(): void;
125
127
  startMotion(): Promise<void>;
package/dist/index.js CHANGED
@@ -13049,7 +13049,8 @@ async function captureAudio(options = {}) {
13049
13049
  const {
13050
13050
  signal,
13051
13051
  minDurationMs = MIN_CAPTURE_MS,
13052
- maxDurationMs = MAX_CAPTURE_MS
13052
+ maxDurationMs = MAX_CAPTURE_MS,
13053
+ onAudioLevel
13053
13054
  } = options;
13054
13055
  const stream = await navigator.mediaDevices.getUserMedia({
13055
13056
  audio: {
@@ -13069,7 +13070,13 @@ async function captureAudio(options = {}) {
13069
13070
  const bufferSize = 4096;
13070
13071
  const processor = ctx.createScriptProcessor(bufferSize, 1, 1);
13071
13072
  processor.onaudioprocess = (e2) => {
13072
- chunks.push(new Float32Array(e2.inputBuffer.getChannelData(0)));
13073
+ const data = e2.inputBuffer.getChannelData(0);
13074
+ chunks.push(new Float32Array(data));
13075
+ if (onAudioLevel) {
13076
+ let sum = 0;
13077
+ for (let i = 0; i < data.length; i++) sum += data[i] * data[i];
13078
+ onAudioLevel(Math.sqrt(sum / data.length));
13079
+ }
13073
13080
  };
13074
13081
  source.connect(processor);
13075
13082
  processor.connect(ctx.destination);
@@ -13939,13 +13946,14 @@ var PulseSession = class {
13939
13946
  this.touchElement = touchElement;
13940
13947
  }
13941
13948
  // --- Audio ---
13942
- async startAudio() {
13949
+ async startAudio(onAudioLevel) {
13943
13950
  if (this.audioStageState !== "idle")
13944
13951
  throw new Error("Audio capture already started");
13945
13952
  this.audioStageState = "capturing";
13946
13953
  this.audioController = new AbortController();
13947
13954
  this.audioPromise = captureAudio({
13948
- signal: this.audioController.signal
13955
+ signal: this.audioController.signal,
13956
+ onAudioLevel
13949
13957
  }).catch(() => null);
13950
13958
  }
13951
13959
  async stopAudio() {