@entros/pulse-sdk 1.5.2 → 2.0.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.
- package/README.md +3 -3
- package/dist/index.d.mts +61 -38
- package/dist/index.d.ts +61 -38
- package/dist/index.js +818 -47
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +818 -47
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@entros/pulse-sdk)
|
|
4
4
|
[](https://www.npmjs.com/package/@entros/pulse-sdk)
|
|
5
5
|
|
|
6
|
-
Client-side SDK for the Entros Protocol. Captures behavioral biometrics (voice, motion, touch), extracts
|
|
6
|
+
Client-side SDK for the Entros Protocol. Captures behavioral biometrics (voice, motion, touch), extracts a 314-dimensional statistical feature vector (v2 expansion: MFCCs, LPC coefficients, formant trajectories, voice quality, pitch contour shape, IMU FFT-band tremor, cross-axis covariance, touch curvature, gap distribution, path efficiency — see `docs/master/BLUEPRINT-feature-pipeline-v2.md`), generates a Groth16 zero-knowledge proof, and submits for on-chain verification on Solana. Raw biometric data stays on-device — only derived features and the proof are transmitted.
|
|
7
7
|
|
|
8
8
|
> **Looking for a drop-in?** Most integrators want [`@entros/verify`](https://github.com/entros-protocol/entros-verify) — a popup-pattern React component that wraps this SDK and ships verification in five lines of JSX. Use this package directly when you need to own the verification UX (custom capture canvas, branded loading states, mobile-native).
|
|
9
9
|
|
|
@@ -32,7 +32,7 @@ if (result.success) {
|
|
|
32
32
|
|
|
33
33
|
### Walletless (liveness-check tier)
|
|
34
34
|
|
|
35
|
-
For
|
|
35
|
+
For liveness checking without wallet onboarding. The integrator optionally funds verifications via the relayer API. Submits proofs to chain through the relayer; **does not issue SAS attestations** — for SAS attestations bound to a verified wallet, use the wallet-connected path above.
|
|
36
36
|
|
|
37
37
|
```typescript
|
|
38
38
|
import { PulseSDK } from '@entros/pulse-sdk';
|
|
@@ -50,7 +50,7 @@ const result = await pulse.verify(touchElement);
|
|
|
50
50
|
## Pipeline
|
|
51
51
|
|
|
52
52
|
1. **Capture**: Audio (16kHz), IMU (accelerometer + gyroscope), touch (pressure + area) — event-driven, caller controls duration
|
|
53
|
-
2. **Extract**:
|
|
53
|
+
2. **Extract**: 314 features — speaker block (176): legacy F0 / jitter / shimmer / HNR / formant ratios / LTAS / amplitude (44) plus v2 additions: MFCCs + delta-MFCCs (78), LPC coefficient stats (24), formant absolute trajectories + bandwidths (16), voice quality CPP/tilt/H1-H2/sub-bands (9), pitch contour DCT (5). Motion block (81): legacy jerk + jounce per IMU axis (54) plus v2 additions: cross-axis covariance (6), FFT band energy on accel axes (12), physiological tremor peak (2), direction-reversal stats (3), motion-magnitude autocorrelation (4). Touch block (57): legacy velocity + pressure dynamics (36) plus v2 additions: pressure derivative (4), contact aspect ratio + area derivative (4), trajectory curvature (3), velocity autocorrelation (3), inter-touch gap distribution (4), path efficiency + per-stroke length (3).
|
|
54
54
|
3. **Validate**: Feature summaries sent to Entros validation server for server-side analysis
|
|
55
55
|
4. **Hash**: SimHash → 256-bit Temporal Fingerprint → Poseidon commitment
|
|
56
56
|
5. **Prove**: Groth16 proof that new fingerprint is within Hamming distance of previous
|
package/dist/index.d.mts
CHANGED
|
@@ -134,8 +134,8 @@ interface VerificationResult {
|
|
|
134
134
|
* Server-side safe-reveal (validator → executor → SDK):
|
|
135
135
|
* - `variance_floor`, `entropy_bounds`, `temporal_coupling_low`,
|
|
136
136
|
* `phrase_content_mismatch`
|
|
137
|
-
* Surfaced for the soft-reject + retry UX
|
|
138
|
-
*
|
|
137
|
+
* Surfaced for the soft-reject + retry UX so the UI can render a
|
|
138
|
+
* per-category hint.
|
|
139
139
|
*
|
|
140
140
|
* Client-side (SDK-emitted):
|
|
141
141
|
* - `validation_unavailable` — the relayer's `/validate-features`
|
|
@@ -356,21 +356,21 @@ declare function fuseFeatures(audio: number[], motion: number[], touch: number[]
|
|
|
356
356
|
* amplitude statistics (5)
|
|
357
357
|
*/
|
|
358
358
|
|
|
359
|
-
declare const SPEAKER_FEATURE_COUNT
|
|
359
|
+
declare const SPEAKER_FEATURE_COUNT: number;
|
|
360
360
|
/**
|
|
361
361
|
* Extract speaker-dependent audio features.
|
|
362
362
|
*
|
|
363
|
-
* Captures physiological vocal characteristics
|
|
364
|
-
*
|
|
365
|
-
*
|
|
363
|
+
* Captures physiological vocal characteristics that are stable across
|
|
364
|
+
* different utterances from the same speaker. Content-independent by
|
|
365
|
+
* design — different phrases produce similar feature values.
|
|
366
366
|
*
|
|
367
367
|
* Returns 44 values.
|
|
368
368
|
*/
|
|
369
369
|
/**
|
|
370
370
|
* Extracts 44 speaker features AND the raw F0 contour.
|
|
371
|
-
* The F0 contour is surfaced so
|
|
372
|
-
*
|
|
373
|
-
*
|
|
371
|
+
* The F0 contour is surfaced so server-side analysis can pair it with
|
|
372
|
+
* the motion time-series. Feature vector shape and semantics are
|
|
373
|
+
* unchanged.
|
|
374
374
|
*/
|
|
375
375
|
declare function extractSpeakerFeaturesDetailed(audio: AudioCapture): Promise<{
|
|
376
376
|
features: number[];
|
|
@@ -379,33 +379,56 @@ declare function extractSpeakerFeaturesDetailed(audio: AudioCapture): Promise<{
|
|
|
379
379
|
/**
|
|
380
380
|
* Extracts 44 speaker features. Backward-compatible wrapper that discards
|
|
381
381
|
* the F0 contour; use `extractSpeakerFeaturesDetailed` when the contour is
|
|
382
|
-
* needed (e.g. for
|
|
382
|
+
* needed (e.g. for server-side analysis).
|
|
383
383
|
*/
|
|
384
384
|
declare function extractSpeakerFeatures(audio: AudioCapture): Promise<number[]>;
|
|
385
385
|
|
|
386
386
|
/**
|
|
387
387
|
* Compute per-sample acceleration magnitude |a| = √(ax² + ay² + az²) and
|
|
388
|
-
* linearly resample to a target frame count.
|
|
389
|
-
*
|
|
390
|
-
* the same frame count
|
|
388
|
+
* linearly resample to a target frame count. Surfaced for server-side
|
|
389
|
+
* analysis paired against the F0 contour; the two time-series must share
|
|
390
|
+
* the same frame count when consumed downstream.
|
|
391
391
|
*
|
|
392
392
|
* Returns an empty array if motion data is absent or too short.
|
|
393
393
|
*/
|
|
394
394
|
declare function extractAccelerationMagnitude(samples: MotionSample[], targetFrameCount: number): number[];
|
|
395
395
|
/**
|
|
396
396
|
* Extract kinematic features from motion (IMU) data.
|
|
397
|
-
* Computes jerk (3rd derivative) and jounce (4th derivative) of acceleration,
|
|
398
|
-
* then condenses each axis into statistics.
|
|
399
397
|
*
|
|
400
|
-
*
|
|
398
|
+
* Layout (`MOTION_FEATURE_COUNT = 81`):
|
|
399
|
+
* `[0..48)` legacy: 6 axes × (jerk stats 4 + jounce stats 4)
|
|
400
|
+
* `[48..54)` legacy: jitter variance per axis (6)
|
|
401
|
+
* `[54..60)` v2: cross-axis covariance (6 selected pairs)
|
|
402
|
+
* `[60..72)` v2: FFT band energy in {0-2, 2-6, 6-12, 12-30} Hz × {ax, ay, az}
|
|
403
|
+
* `[72..74)` v2: physiological tremor peak frequency + amplitude (4-12 Hz)
|
|
404
|
+
* `[74..76)` v2: direction-reversal rate per axis: mean, variance across {ax, ay, az}
|
|
405
|
+
* `[76]` v2: mean angular velocity (|gyro| over the capture)
|
|
406
|
+
* `[77..81)` v2: motion-magnitude autocorrelation at lags {1, 5, 10, 25}
|
|
407
|
+
*
|
|
408
|
+
* @privacyGuarantee Operates on already-on-device IMU samples and emits
|
|
409
|
+
* statistical / spectral aggregates (variances, covariances, band sums,
|
|
410
|
+
* autocorrelation scalars). The full sample stream is never transmitted.
|
|
401
411
|
*/
|
|
402
412
|
declare function extractMotionFeatures(samples: MotionSample[]): number[];
|
|
403
413
|
/**
|
|
404
414
|
* Extract kinematic features from touch data.
|
|
405
|
-
* Computes velocity and acceleration of touch coordinates,
|
|
406
|
-
* plus pressure and area statistics.
|
|
407
415
|
*
|
|
408
|
-
*
|
|
416
|
+
* Layout (`TOUCH_FEATURE_COUNT = 57`):
|
|
417
|
+
* `[0..32)` legacy: velocity / accel / pressure / area / jerk stats (32)
|
|
418
|
+
* `[32..36)` legacy: jitter variance for {vx, vy, pressure, area} (4)
|
|
419
|
+
* `[36..40)` v2: pressure first-derivative stats (mean, var, skew, kurt)
|
|
420
|
+
* `[40..42)` v2: contact aspect-ratio stats (mean, var)
|
|
421
|
+
* `[42..44)` v2: contact-area first-derivative stats (mean, var)
|
|
422
|
+
* `[44..47)` v2: trajectory curvature stats (mean, var, skew)
|
|
423
|
+
* `[47..50)` v2: velocity autocorrelation at lags {1, 3, 5}
|
|
424
|
+
* `[50..54)` v2: inter-touch gap duration stats (mean, var, skew, kurt)
|
|
425
|
+
* `[54]` v2: path efficiency (straight-line / total path length)
|
|
426
|
+
* `[55..57)` v2: per-stroke total path length: mean, variance
|
|
427
|
+
*
|
|
428
|
+
* @privacyGuarantee Operates on already-on-device touch samples and emits
|
|
429
|
+
* statistical aggregates only. The full coordinate stream is never
|
|
430
|
+
* transmitted; downstream phase-content (e.g. typed text) is not
|
|
431
|
+
* recoverable from the per-stroke summaries.
|
|
409
432
|
*/
|
|
410
433
|
declare function extractTouchFeatures(samples: TouchSample[]): number[];
|
|
411
434
|
/**
|
|
@@ -413,7 +436,10 @@ declare function extractTouchFeatures(samples: TouchSample[]): number[];
|
|
|
413
436
|
* Captures behavioral patterns from mouse/pointer movement that are user-specific:
|
|
414
437
|
* path curvature, speed patterns, micro-corrections, pause behavior.
|
|
415
438
|
*
|
|
416
|
-
* Returns:
|
|
439
|
+
* Returns: `MOUSE_DYNAMICS_FEATURE_COUNT` (= `MOTION_FEATURE_COUNT`) values.
|
|
440
|
+
* The first 54 entries are the legacy mouse-dynamics signal; the trailing
|
|
441
|
+
* v2-block slots stay zero on desktop so the per-modality bit-influence
|
|
442
|
+
* share matches a mobile IMU capture under the new pipeline.
|
|
417
443
|
*/
|
|
418
444
|
declare function extractMouseDynamics(samples: TouchSample[]): number[];
|
|
419
445
|
|
|
@@ -513,9 +539,8 @@ declare function submitViaWallet(proof: SolanaProof, commitment: Uint8Array, opt
|
|
|
513
539
|
* and sets a 7-day cooldown before the next reset.
|
|
514
540
|
*
|
|
515
541
|
* Transaction shape: single instruction (no challenge / verify_proof /
|
|
516
|
-
* ZK proof required). Humanness evidence comes from the
|
|
517
|
-
*
|
|
518
|
-
* update).
|
|
542
|
+
* ZK proof required). Humanness evidence comes from the validation
|
|
543
|
+
* pipeline invoked at the /attest step (same as mint and update).
|
|
519
544
|
*/
|
|
520
545
|
declare function submitResetViaWallet(commitment: Uint8Array, options: {
|
|
521
546
|
wallet: any;
|
|
@@ -659,8 +684,8 @@ declare function loadVerificationData(): Promise<StoredVerificationData | null>;
|
|
|
659
684
|
* FALLBACK challenge-phrase generator. Used only when the executor's
|
|
660
685
|
* `/challenge` endpoint is unreachable; the authoritative phrase comes from
|
|
661
686
|
* the server (5 real words drawn from a curated English-word dictionary). On
|
|
662
|
-
* this fallback path, validation skips
|
|
663
|
-
*
|
|
687
|
+
* this fallback path, validation skips the phrase verification step —
|
|
688
|
+
* other server-side checks still run.
|
|
664
689
|
*
|
|
665
690
|
* Output is 5-6 syllable pairs, forming nonsensical but speakable words.
|
|
666
691
|
* Uses crypto.getRandomValues for unpredictable challenge generation.
|
|
@@ -711,16 +736,14 @@ declare function generateLissajousSequence(count?: number): {
|
|
|
711
736
|
*
|
|
712
737
|
* The executor's `/challenge` endpoint returns a fresh nonce + 5-word phrase
|
|
713
738
|
* bound to the wallet for a short TTL (default 60s). The phrase is drawn from
|
|
714
|
-
* a curated English-word dictionary
|
|
715
|
-
* `entros-validation/src/word_dict.rs`); shown to the user as the voice challenge
|
|
739
|
+
* a curated English-word dictionary, shown to the user as the voice challenge
|
|
716
740
|
* and looked up server-side at `/validate-features` to verify the audio
|
|
717
|
-
* matches the issued phrase
|
|
741
|
+
* matches the issued phrase.
|
|
718
742
|
*
|
|
719
|
-
* Server-issued phrases are the only safe design
|
|
720
|
-
*
|
|
721
|
-
*
|
|
722
|
-
*
|
|
723
|
-
* client cannot substitute it.
|
|
743
|
+
* Server-issued phrases are the only safe design here: if the client generated
|
|
744
|
+
* the phrase and sent it to the server alongside the audio, an attacker would
|
|
745
|
+
* submit their own phrase matching whatever content they captured. With server
|
|
746
|
+
* issuance, the phrase is bound to the nonce and the client cannot substitute it.
|
|
724
747
|
*/
|
|
725
748
|
/**
|
|
726
749
|
* Server-issued challenge artifacts. Returned by `fetchChallenge`.
|
|
@@ -745,13 +768,13 @@ declare function fetchChallenge(executorUrl: string, walletAddress: string, apiK
|
|
|
745
768
|
|
|
746
769
|
/**
|
|
747
770
|
* Encode captured Float32 audio samples as base64 int16 PCM for transmission
|
|
748
|
-
* to the validation service
|
|
771
|
+
* to the validation service.
|
|
749
772
|
*
|
|
750
773
|
* Audio is captured as `Float32Array` with values in `[-1.0, 1.0]` by the
|
|
751
|
-
* Pulse SDK (`sensor/audio.ts`). The validation service
|
|
752
|
-
*
|
|
753
|
-
*
|
|
754
|
-
*
|
|
774
|
+
* Pulse SDK (`sensor/audio.ts`). The validation service decodes the base64
|
|
775
|
+
* payload and feeds the audio into server-side transcription. int16 is the
|
|
776
|
+
* standard compact representation: 2 bytes per sample vs 4 for f32, halving
|
|
777
|
+
* wire size without perceptible quality loss for 16kHz speech.
|
|
755
778
|
*
|
|
756
779
|
* Byte layout: little-endian int16 samples, contiguous, no header.
|
|
757
780
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -134,8 +134,8 @@ interface VerificationResult {
|
|
|
134
134
|
* Server-side safe-reveal (validator → executor → SDK):
|
|
135
135
|
* - `variance_floor`, `entropy_bounds`, `temporal_coupling_low`,
|
|
136
136
|
* `phrase_content_mismatch`
|
|
137
|
-
* Surfaced for the soft-reject + retry UX
|
|
138
|
-
*
|
|
137
|
+
* Surfaced for the soft-reject + retry UX so the UI can render a
|
|
138
|
+
* per-category hint.
|
|
139
139
|
*
|
|
140
140
|
* Client-side (SDK-emitted):
|
|
141
141
|
* - `validation_unavailable` — the relayer's `/validate-features`
|
|
@@ -356,21 +356,21 @@ declare function fuseFeatures(audio: number[], motion: number[], touch: number[]
|
|
|
356
356
|
* amplitude statistics (5)
|
|
357
357
|
*/
|
|
358
358
|
|
|
359
|
-
declare const SPEAKER_FEATURE_COUNT
|
|
359
|
+
declare const SPEAKER_FEATURE_COUNT: number;
|
|
360
360
|
/**
|
|
361
361
|
* Extract speaker-dependent audio features.
|
|
362
362
|
*
|
|
363
|
-
* Captures physiological vocal characteristics
|
|
364
|
-
*
|
|
365
|
-
*
|
|
363
|
+
* Captures physiological vocal characteristics that are stable across
|
|
364
|
+
* different utterances from the same speaker. Content-independent by
|
|
365
|
+
* design — different phrases produce similar feature values.
|
|
366
366
|
*
|
|
367
367
|
* Returns 44 values.
|
|
368
368
|
*/
|
|
369
369
|
/**
|
|
370
370
|
* Extracts 44 speaker features AND the raw F0 contour.
|
|
371
|
-
* The F0 contour is surfaced so
|
|
372
|
-
*
|
|
373
|
-
*
|
|
371
|
+
* The F0 contour is surfaced so server-side analysis can pair it with
|
|
372
|
+
* the motion time-series. Feature vector shape and semantics are
|
|
373
|
+
* unchanged.
|
|
374
374
|
*/
|
|
375
375
|
declare function extractSpeakerFeaturesDetailed(audio: AudioCapture): Promise<{
|
|
376
376
|
features: number[];
|
|
@@ -379,33 +379,56 @@ declare function extractSpeakerFeaturesDetailed(audio: AudioCapture): Promise<{
|
|
|
379
379
|
/**
|
|
380
380
|
* Extracts 44 speaker features. Backward-compatible wrapper that discards
|
|
381
381
|
* the F0 contour; use `extractSpeakerFeaturesDetailed` when the contour is
|
|
382
|
-
* needed (e.g. for
|
|
382
|
+
* needed (e.g. for server-side analysis).
|
|
383
383
|
*/
|
|
384
384
|
declare function extractSpeakerFeatures(audio: AudioCapture): Promise<number[]>;
|
|
385
385
|
|
|
386
386
|
/**
|
|
387
387
|
* Compute per-sample acceleration magnitude |a| = √(ax² + ay² + az²) and
|
|
388
|
-
* linearly resample to a target frame count.
|
|
389
|
-
*
|
|
390
|
-
* the same frame count
|
|
388
|
+
* linearly resample to a target frame count. Surfaced for server-side
|
|
389
|
+
* analysis paired against the F0 contour; the two time-series must share
|
|
390
|
+
* the same frame count when consumed downstream.
|
|
391
391
|
*
|
|
392
392
|
* Returns an empty array if motion data is absent or too short.
|
|
393
393
|
*/
|
|
394
394
|
declare function extractAccelerationMagnitude(samples: MotionSample[], targetFrameCount: number): number[];
|
|
395
395
|
/**
|
|
396
396
|
* Extract kinematic features from motion (IMU) data.
|
|
397
|
-
* Computes jerk (3rd derivative) and jounce (4th derivative) of acceleration,
|
|
398
|
-
* then condenses each axis into statistics.
|
|
399
397
|
*
|
|
400
|
-
*
|
|
398
|
+
* Layout (`MOTION_FEATURE_COUNT = 81`):
|
|
399
|
+
* `[0..48)` legacy: 6 axes × (jerk stats 4 + jounce stats 4)
|
|
400
|
+
* `[48..54)` legacy: jitter variance per axis (6)
|
|
401
|
+
* `[54..60)` v2: cross-axis covariance (6 selected pairs)
|
|
402
|
+
* `[60..72)` v2: FFT band energy in {0-2, 2-6, 6-12, 12-30} Hz × {ax, ay, az}
|
|
403
|
+
* `[72..74)` v2: physiological tremor peak frequency + amplitude (4-12 Hz)
|
|
404
|
+
* `[74..76)` v2: direction-reversal rate per axis: mean, variance across {ax, ay, az}
|
|
405
|
+
* `[76]` v2: mean angular velocity (|gyro| over the capture)
|
|
406
|
+
* `[77..81)` v2: motion-magnitude autocorrelation at lags {1, 5, 10, 25}
|
|
407
|
+
*
|
|
408
|
+
* @privacyGuarantee Operates on already-on-device IMU samples and emits
|
|
409
|
+
* statistical / spectral aggregates (variances, covariances, band sums,
|
|
410
|
+
* autocorrelation scalars). The full sample stream is never transmitted.
|
|
401
411
|
*/
|
|
402
412
|
declare function extractMotionFeatures(samples: MotionSample[]): number[];
|
|
403
413
|
/**
|
|
404
414
|
* Extract kinematic features from touch data.
|
|
405
|
-
* Computes velocity and acceleration of touch coordinates,
|
|
406
|
-
* plus pressure and area statistics.
|
|
407
415
|
*
|
|
408
|
-
*
|
|
416
|
+
* Layout (`TOUCH_FEATURE_COUNT = 57`):
|
|
417
|
+
* `[0..32)` legacy: velocity / accel / pressure / area / jerk stats (32)
|
|
418
|
+
* `[32..36)` legacy: jitter variance for {vx, vy, pressure, area} (4)
|
|
419
|
+
* `[36..40)` v2: pressure first-derivative stats (mean, var, skew, kurt)
|
|
420
|
+
* `[40..42)` v2: contact aspect-ratio stats (mean, var)
|
|
421
|
+
* `[42..44)` v2: contact-area first-derivative stats (mean, var)
|
|
422
|
+
* `[44..47)` v2: trajectory curvature stats (mean, var, skew)
|
|
423
|
+
* `[47..50)` v2: velocity autocorrelation at lags {1, 3, 5}
|
|
424
|
+
* `[50..54)` v2: inter-touch gap duration stats (mean, var, skew, kurt)
|
|
425
|
+
* `[54]` v2: path efficiency (straight-line / total path length)
|
|
426
|
+
* `[55..57)` v2: per-stroke total path length: mean, variance
|
|
427
|
+
*
|
|
428
|
+
* @privacyGuarantee Operates on already-on-device touch samples and emits
|
|
429
|
+
* statistical aggregates only. The full coordinate stream is never
|
|
430
|
+
* transmitted; downstream phase-content (e.g. typed text) is not
|
|
431
|
+
* recoverable from the per-stroke summaries.
|
|
409
432
|
*/
|
|
410
433
|
declare function extractTouchFeatures(samples: TouchSample[]): number[];
|
|
411
434
|
/**
|
|
@@ -413,7 +436,10 @@ declare function extractTouchFeatures(samples: TouchSample[]): number[];
|
|
|
413
436
|
* Captures behavioral patterns from mouse/pointer movement that are user-specific:
|
|
414
437
|
* path curvature, speed patterns, micro-corrections, pause behavior.
|
|
415
438
|
*
|
|
416
|
-
* Returns:
|
|
439
|
+
* Returns: `MOUSE_DYNAMICS_FEATURE_COUNT` (= `MOTION_FEATURE_COUNT`) values.
|
|
440
|
+
* The first 54 entries are the legacy mouse-dynamics signal; the trailing
|
|
441
|
+
* v2-block slots stay zero on desktop so the per-modality bit-influence
|
|
442
|
+
* share matches a mobile IMU capture under the new pipeline.
|
|
417
443
|
*/
|
|
418
444
|
declare function extractMouseDynamics(samples: TouchSample[]): number[];
|
|
419
445
|
|
|
@@ -513,9 +539,8 @@ declare function submitViaWallet(proof: SolanaProof, commitment: Uint8Array, opt
|
|
|
513
539
|
* and sets a 7-day cooldown before the next reset.
|
|
514
540
|
*
|
|
515
541
|
* Transaction shape: single instruction (no challenge / verify_proof /
|
|
516
|
-
* ZK proof required). Humanness evidence comes from the
|
|
517
|
-
*
|
|
518
|
-
* update).
|
|
542
|
+
* ZK proof required). Humanness evidence comes from the validation
|
|
543
|
+
* pipeline invoked at the /attest step (same as mint and update).
|
|
519
544
|
*/
|
|
520
545
|
declare function submitResetViaWallet(commitment: Uint8Array, options: {
|
|
521
546
|
wallet: any;
|
|
@@ -659,8 +684,8 @@ declare function loadVerificationData(): Promise<StoredVerificationData | null>;
|
|
|
659
684
|
* FALLBACK challenge-phrase generator. Used only when the executor's
|
|
660
685
|
* `/challenge` endpoint is unreachable; the authoritative phrase comes from
|
|
661
686
|
* the server (5 real words drawn from a curated English-word dictionary). On
|
|
662
|
-
* this fallback path, validation skips
|
|
663
|
-
*
|
|
687
|
+
* this fallback path, validation skips the phrase verification step —
|
|
688
|
+
* other server-side checks still run.
|
|
664
689
|
*
|
|
665
690
|
* Output is 5-6 syllable pairs, forming nonsensical but speakable words.
|
|
666
691
|
* Uses crypto.getRandomValues for unpredictable challenge generation.
|
|
@@ -711,16 +736,14 @@ declare function generateLissajousSequence(count?: number): {
|
|
|
711
736
|
*
|
|
712
737
|
* The executor's `/challenge` endpoint returns a fresh nonce + 5-word phrase
|
|
713
738
|
* bound to the wallet for a short TTL (default 60s). The phrase is drawn from
|
|
714
|
-
* a curated English-word dictionary
|
|
715
|
-
* `entros-validation/src/word_dict.rs`); shown to the user as the voice challenge
|
|
739
|
+
* a curated English-word dictionary, shown to the user as the voice challenge
|
|
716
740
|
* and looked up server-side at `/validate-features` to verify the audio
|
|
717
|
-
* matches the issued phrase
|
|
741
|
+
* matches the issued phrase.
|
|
718
742
|
*
|
|
719
|
-
* Server-issued phrases are the only safe design
|
|
720
|
-
*
|
|
721
|
-
*
|
|
722
|
-
*
|
|
723
|
-
* client cannot substitute it.
|
|
743
|
+
* Server-issued phrases are the only safe design here: if the client generated
|
|
744
|
+
* the phrase and sent it to the server alongside the audio, an attacker would
|
|
745
|
+
* submit their own phrase matching whatever content they captured. With server
|
|
746
|
+
* issuance, the phrase is bound to the nonce and the client cannot substitute it.
|
|
724
747
|
*/
|
|
725
748
|
/**
|
|
726
749
|
* Server-issued challenge artifacts. Returned by `fetchChallenge`.
|
|
@@ -745,13 +768,13 @@ declare function fetchChallenge(executorUrl: string, walletAddress: string, apiK
|
|
|
745
768
|
|
|
746
769
|
/**
|
|
747
770
|
* Encode captured Float32 audio samples as base64 int16 PCM for transmission
|
|
748
|
-
* to the validation service
|
|
771
|
+
* to the validation service.
|
|
749
772
|
*
|
|
750
773
|
* Audio is captured as `Float32Array` with values in `[-1.0, 1.0]` by the
|
|
751
|
-
* Pulse SDK (`sensor/audio.ts`). The validation service
|
|
752
|
-
*
|
|
753
|
-
*
|
|
754
|
-
*
|
|
774
|
+
* Pulse SDK (`sensor/audio.ts`). The validation service decodes the base64
|
|
775
|
+
* payload and feeds the audio into server-side transcription. int16 is the
|
|
776
|
+
* standard compact representation: 2 bytes per sample vs 4 for f32, halving
|
|
777
|
+
* wire size without perceptible quality loss for 16kHz speech.
|
|
755
778
|
*
|
|
756
779
|
* Byte layout: little-endian int16 samples, contiguous, no header.
|
|
757
780
|
*/
|