@entros/pulse-sdk 1.0.1 → 1.1.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/dist/index.mjs CHANGED
@@ -25,7 +25,7 @@ var PROGRAM_IDS = {
25
25
  var AGENT_REGISTRY_CONFIG = {
26
26
  programIdDevnet: "8oo4J9tBB3Hna1jRQ3rWvJjojqM5DYTDJo5cejUuJy3C",
27
27
  programIdMainnet: "8oo4dC4JvBLwy5tGgiH3WwK4B9PWxL9Z4XjA2jzkQMbQ",
28
- metadataKey: "iam:human-operator"
28
+ metadataKey: "entros:human-operator"
29
29
  };
30
30
  var SAS_CONFIG = {
31
31
  programId: "22zoJMtdu4tQc2PzL74ZUT7FrwgB1Udec8DdW4yw4BdG",
@@ -2315,6 +2315,116 @@ var PulseSession = class {
2315
2315
  );
2316
2316
  this.touchStageState = "skipped";
2317
2317
  }
2318
+ // --- Test hooks (internal builds only) ---
2319
+ /**
2320
+ * @internal Test-only. Primes the session with pre-captured sensor data,
2321
+ * bypassing browser capture APIs. Throws unless built with IAM_INTERNAL_TEST=1.
2322
+ * Stripped from the published .d.ts so npm consumers never see it. Used by the
2323
+ * red team harness to drive the real verification pipeline (extraction →
2324
+ * SimHash → TBH → proof → submit) against synthetic sensor data — never
2325
+ * available to npm consumers.
2326
+ */
2327
+ __injectSensorData(data) {
2328
+ if (true) {
2329
+ throw new Error(
2330
+ "PulseSession.__injectSensorData is only available in internal test builds. Set IAM_INTERNAL_TEST=1 when building pulse-sdk from source."
2331
+ );
2332
+ }
2333
+ const conflicts = [];
2334
+ if (this.audioStageState === "capturing") conflicts.push("audio");
2335
+ if (this.motionStageState === "capturing") conflicts.push("motion");
2336
+ if (this.touchStageState === "capturing") conflicts.push("touch");
2337
+ if (conflicts.length > 0) {
2338
+ throw new Error(
2339
+ `__injectSensorData: cannot inject while stages are capturing: ${conflicts.join(", ")}. Create a fresh session via sdk.createSession() and inject before any startAudio/startMotion/startTouch call.`
2340
+ );
2341
+ }
2342
+ if (!data.audio || data.audio.samples.length < MIN_AUDIO_SAMPLES) {
2343
+ throw new Error(
2344
+ `__injectSensorData: audio required, minimum ${MIN_AUDIO_SAMPLES} samples (got ${data.audio?.samples.length ?? 0}).`
2345
+ );
2346
+ }
2347
+ if (data.motion.length < MIN_MOTION_SAMPLES) {
2348
+ throw new Error(
2349
+ `__injectSensorData: motion required, minimum ${MIN_MOTION_SAMPLES} samples (got ${data.motion.length}).`
2350
+ );
2351
+ }
2352
+ if (data.touch.length < MIN_TOUCH_SAMPLES) {
2353
+ throw new Error(
2354
+ `__injectSensorData: touch required, minimum ${MIN_TOUCH_SAMPLES} samples (got ${data.touch.length}).`
2355
+ );
2356
+ }
2357
+ this.audioData = data.audio;
2358
+ this.motionData = data.motion;
2359
+ this.touchData = data.touch;
2360
+ this.audioStageState = "captured";
2361
+ this.motionStageState = "captured";
2362
+ this.touchStageState = "captured";
2363
+ }
2364
+ /**
2365
+ * @internal
2366
+ *
2367
+ * Run the validation step of the verify pipeline only: feature extraction
2368
+ * + `/validate-features` POST. Returns the validation outcome without ever
2369
+ * touching the on-chain submission path. Mirrors the production user
2370
+ * flow's pre-payment gate — the validation server runs without requiring
2371
+ * the wallet to have SOL, just like a real user gets a validation result
2372
+ * before being prompted to sign the on-chain mint.
2373
+ *
2374
+ * Note: this is a strict subset of `complete()`. It skips the data-quality
2375
+ * gates and re-verification check that `processSensorData` performs. The
2376
+ * validation server still runs its full pipeline (Tier 1 + Tier 2 +
2377
+ * phrase binding); only the client-side pre-flight checks differ.
2378
+ *
2379
+ * Use case: red team campaigns measuring server-side validation at scale
2380
+ * without per-attempt SOL funding. Build-time gated identically to
2381
+ * `__injectSensorData`; throws in production builds.
2382
+ */
2383
+ async __validateOnly(walletAddress) {
2384
+ if (true) {
2385
+ throw new Error(
2386
+ "PulseSession.__validateOnly is only available in internal test builds. Set IAM_INTERNAL_TEST=1 when building pulse-sdk from source."
2387
+ );
2388
+ }
2389
+ if (typeof walletAddress !== "string" || walletAddress.length === 0) {
2390
+ throw new Error(
2391
+ "__validateOnly requires a non-empty walletAddress string (used as wallet_id in the /validate-features payload)."
2392
+ );
2393
+ }
2394
+ const active = [];
2395
+ if (this.audioStageState === "capturing") active.push("audio");
2396
+ if (this.motionStageState === "capturing") active.push("motion");
2397
+ if (this.touchStageState === "capturing") active.push("touch");
2398
+ if (active.length > 0) {
2399
+ throw new Error(
2400
+ `Cannot validate: stages still capturing: ${active.join(", ")}`
2401
+ );
2402
+ }
2403
+ if (!this.audioData || this.motionData.length === 0 || this.touchData.length === 0) {
2404
+ throw new Error(
2405
+ "__validateOnly requires sensor data first \u2014 call __injectSensorData() before this."
2406
+ );
2407
+ }
2408
+ const sensorData = {
2409
+ audio: this.audioData,
2410
+ motion: this.motionData,
2411
+ touch: this.touchData,
2412
+ modalities: {
2413
+ audio: true,
2414
+ motion: true,
2415
+ touch: true
2416
+ }
2417
+ };
2418
+ const extraction = await extractFingerprintAndValidate(
2419
+ sensorData,
2420
+ this.config,
2421
+ walletAddress
2422
+ );
2423
+ if (!extraction.ok) {
2424
+ return { validated: false, error: extraction.error };
2425
+ }
2426
+ return { validated: true };
2427
+ }
2318
2428
  // --- Complete ---
2319
2429
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Solana types are optional peer deps
2320
2430
  async complete(wallet, connection, onProgress) {
@@ -2989,7 +3099,10 @@ export {
2989
3099
  DEFAULT_THRESHOLD,
2990
3100
  FINGERPRINT_BITS,
2991
3101
  MAX_CAPTURE_MS,
3102
+ MIN_AUDIO_SAMPLES,
2992
3103
  MIN_CAPTURE_MS,
3104
+ MIN_MOTION_SAMPLES,
3105
+ MIN_TOUCH_SAMPLES,
2993
3106
  PROGRAM_IDS,
2994
3107
  PulseSDK,
2995
3108
  PulseSession,