@entros/pulse-sdk 1.2.0 → 1.4.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.d.mts CHANGED
@@ -19,6 +19,22 @@ interface PulseConfig {
19
19
  threshold?: number;
20
20
  /** Enable console logging for diagnostics. Default: false. */
21
21
  debug?: boolean;
22
+ /**
23
+ * Optional callback invoked when the SDK detects that encrypted local
24
+ * storage is unavailable (e.g. iOS Safari private browsing, Brave
25
+ * shields, Firefox Total Cookie Protection). The host app can prompt
26
+ * the user and resolve to:
27
+ * - `true` → SDK stores verification data in plaintext localStorage.
28
+ * Convenient (baseline survives reload) but the
29
+ * 256-bit fingerprint + salt + commitment sit unencrypted.
30
+ * - `false` → SDK stores in-memory only. Data is lost on reload;
31
+ * user must re-enroll each session.
32
+ * If this callback is NOT provided, the SDK defaults to in-memory only —
33
+ * never silently writes plaintext to localStorage. This default is the
34
+ * safer choice; opt-in to plaintext via the callback when the host app
35
+ * has surfaced the privacy tradeoff to the user.
36
+ */
37
+ onPrivacyFallback?: () => Promise<boolean>;
22
38
  }
23
39
 
24
40
  /** Raw audio samples captured during the Pulse challenge */
@@ -84,6 +100,26 @@ interface SubmissionResult {
84
100
  attestationTx?: string;
85
101
  error?: string;
86
102
  }
103
+ /**
104
+ * Validator-signed receipt binding (wallet, commitment, validated_at) for the
105
+ * upcoming `mint_anchor` transaction (master-list #146 Phase 4). Returned in
106
+ * the `/validate-features` response when the request includes
107
+ * `commitment_new_hex` and the validator has a signing key configured.
108
+ *
109
+ * Wire fields are byte-identical to `entros_validation::SignedReceiptDto` and
110
+ * the executor's local mirror at `executor-node::validation::SignedReceiptDto`.
111
+ */
112
+ interface SignedReceiptDto {
113
+ /** Hex-encoded 32-byte Ed25519 public key of the validator. */
114
+ validator_pubkey_hex: string;
115
+ /**
116
+ * Hex-encoded 72-byte message:
117
+ * wallet_pubkey (32) || commitment_new (32) || validated_at i64 LE (8)
118
+ */
119
+ message_hex: string;
120
+ /** Hex-encoded 64-byte Ed25519 signature over `message_hex`. */
121
+ signature_hex: string;
122
+ }
87
123
  /** Result of a full Pulse verification */
88
124
  interface VerificationResult {
89
125
  success: boolean;
@@ -93,10 +129,20 @@ interface VerificationResult {
93
129
  isFirstVerification: boolean;
94
130
  error?: string;
95
131
  /**
96
- * Safe-to-reveal validator reason label when validation rejected one of
97
- * `variance_floor`, `entropy_bounds`, `temporal_coupling_low`,
98
- * `phrase_content_mismatch`. Surfaced for the soft-reject + retry UX
99
- * (master-list #94) so the UI can show a per-category hint.
132
+ * Reason label when verification fails. Two-source taxonomy:
133
+ *
134
+ * Server-side safe-reveal (validator executor SDK):
135
+ * - `variance_floor`, `entropy_bounds`, `temporal_coupling_low`,
136
+ * `phrase_content_mismatch`
137
+ * Surfaced for the soft-reject + retry UX (master-list #94) so the
138
+ * UI can render a per-category hint.
139
+ *
140
+ * Client-side (SDK-emitted):
141
+ * - `validation_unavailable` — the relayer's `/validate-features`
142
+ * endpoint was unreachable (network failure, timeout, abort).
143
+ * UI should treat as transient + offer retry. NOT a server-side
144
+ * ReasonCode; emitted directly by `extractFingerprintAndValidate`
145
+ * when the fetch promise rejects.
100
146
  *
101
147
  * Absent on every other failure path (data-quality, on-chain submission,
102
148
  * baseline missing, etc.) and on attack-signal rejections (TTS detection,
@@ -445,6 +491,15 @@ declare function submitViaWallet(proof: SolanaProof, commitment: Uint8Array, opt
445
491
  isFirstVerification: boolean;
446
492
  relayerUrl?: string;
447
493
  relayerApiKey?: string;
494
+ /**
495
+ * Validator-signed mint receipt (master-list #146 Phase 4). Consumed
496
+ * only on the first-verification path: when present, the SDK prepends
497
+ * an `Ed25519Program::verify` instruction so on-chain `mint_anchor`
498
+ * can confirm the commitment was endorsed by the configured validator.
499
+ * Re-verification ignores the field entirely — `update_anchor` enforces
500
+ * binding via the VerificationResult PDA instead.
501
+ */
502
+ signedReceipt?: SignedReceiptDto;
448
503
  }): Promise<SubmissionResult>;
449
504
  /**
450
505
  * Submit a baseline reset on-chain via a connected wallet.
@@ -571,8 +626,15 @@ interface StoredVerificationData {
571
626
  declare function fetchIdentityState(walletPubkey: string, connection: any): Promise<IdentityState | null>;
572
627
  /**
573
628
  * Store verification data locally for re-verification.
574
- * Encrypts with AES-256-GCM when Web Crypto is available.
575
- * Falls back to plaintext with a warning otherwise.
629
+ *
630
+ * Storage tiers (preferred first):
631
+ * 1. Encrypted localStorage envelope (Web Crypto available).
632
+ * 2. If crypto unavailable AND `onPrivacyFallback` callback registered
633
+ * AND the callback resolves true, plaintext localStorage. The host
634
+ * app is responsible for surfacing the privacy tradeoff to the user
635
+ * before approving the fallback.
636
+ * 3. Otherwise, in-memory only (lost on reload). Safer default —
637
+ * never silently writes plaintext to localStorage.
576
638
  */
577
639
  declare function storeVerificationData(data: StoredVerificationData): Promise<void>;
578
640
  /**
package/dist/index.d.ts CHANGED
@@ -19,6 +19,22 @@ interface PulseConfig {
19
19
  threshold?: number;
20
20
  /** Enable console logging for diagnostics. Default: false. */
21
21
  debug?: boolean;
22
+ /**
23
+ * Optional callback invoked when the SDK detects that encrypted local
24
+ * storage is unavailable (e.g. iOS Safari private browsing, Brave
25
+ * shields, Firefox Total Cookie Protection). The host app can prompt
26
+ * the user and resolve to:
27
+ * - `true` → SDK stores verification data in plaintext localStorage.
28
+ * Convenient (baseline survives reload) but the
29
+ * 256-bit fingerprint + salt + commitment sit unencrypted.
30
+ * - `false` → SDK stores in-memory only. Data is lost on reload;
31
+ * user must re-enroll each session.
32
+ * If this callback is NOT provided, the SDK defaults to in-memory only —
33
+ * never silently writes plaintext to localStorage. This default is the
34
+ * safer choice; opt-in to plaintext via the callback when the host app
35
+ * has surfaced the privacy tradeoff to the user.
36
+ */
37
+ onPrivacyFallback?: () => Promise<boolean>;
22
38
  }
23
39
 
24
40
  /** Raw audio samples captured during the Pulse challenge */
@@ -84,6 +100,26 @@ interface SubmissionResult {
84
100
  attestationTx?: string;
85
101
  error?: string;
86
102
  }
103
+ /**
104
+ * Validator-signed receipt binding (wallet, commitment, validated_at) for the
105
+ * upcoming `mint_anchor` transaction (master-list #146 Phase 4). Returned in
106
+ * the `/validate-features` response when the request includes
107
+ * `commitment_new_hex` and the validator has a signing key configured.
108
+ *
109
+ * Wire fields are byte-identical to `entros_validation::SignedReceiptDto` and
110
+ * the executor's local mirror at `executor-node::validation::SignedReceiptDto`.
111
+ */
112
+ interface SignedReceiptDto {
113
+ /** Hex-encoded 32-byte Ed25519 public key of the validator. */
114
+ validator_pubkey_hex: string;
115
+ /**
116
+ * Hex-encoded 72-byte message:
117
+ * wallet_pubkey (32) || commitment_new (32) || validated_at i64 LE (8)
118
+ */
119
+ message_hex: string;
120
+ /** Hex-encoded 64-byte Ed25519 signature over `message_hex`. */
121
+ signature_hex: string;
122
+ }
87
123
  /** Result of a full Pulse verification */
88
124
  interface VerificationResult {
89
125
  success: boolean;
@@ -93,10 +129,20 @@ interface VerificationResult {
93
129
  isFirstVerification: boolean;
94
130
  error?: string;
95
131
  /**
96
- * Safe-to-reveal validator reason label when validation rejected one of
97
- * `variance_floor`, `entropy_bounds`, `temporal_coupling_low`,
98
- * `phrase_content_mismatch`. Surfaced for the soft-reject + retry UX
99
- * (master-list #94) so the UI can show a per-category hint.
132
+ * Reason label when verification fails. Two-source taxonomy:
133
+ *
134
+ * Server-side safe-reveal (validator executor SDK):
135
+ * - `variance_floor`, `entropy_bounds`, `temporal_coupling_low`,
136
+ * `phrase_content_mismatch`
137
+ * Surfaced for the soft-reject + retry UX (master-list #94) so the
138
+ * UI can render a per-category hint.
139
+ *
140
+ * Client-side (SDK-emitted):
141
+ * - `validation_unavailable` — the relayer's `/validate-features`
142
+ * endpoint was unreachable (network failure, timeout, abort).
143
+ * UI should treat as transient + offer retry. NOT a server-side
144
+ * ReasonCode; emitted directly by `extractFingerprintAndValidate`
145
+ * when the fetch promise rejects.
100
146
  *
101
147
  * Absent on every other failure path (data-quality, on-chain submission,
102
148
  * baseline missing, etc.) and on attack-signal rejections (TTS detection,
@@ -445,6 +491,15 @@ declare function submitViaWallet(proof: SolanaProof, commitment: Uint8Array, opt
445
491
  isFirstVerification: boolean;
446
492
  relayerUrl?: string;
447
493
  relayerApiKey?: string;
494
+ /**
495
+ * Validator-signed mint receipt (master-list #146 Phase 4). Consumed
496
+ * only on the first-verification path: when present, the SDK prepends
497
+ * an `Ed25519Program::verify` instruction so on-chain `mint_anchor`
498
+ * can confirm the commitment was endorsed by the configured validator.
499
+ * Re-verification ignores the field entirely — `update_anchor` enforces
500
+ * binding via the VerificationResult PDA instead.
501
+ */
502
+ signedReceipt?: SignedReceiptDto;
448
503
  }): Promise<SubmissionResult>;
449
504
  /**
450
505
  * Submit a baseline reset on-chain via a connected wallet.
@@ -571,8 +626,15 @@ interface StoredVerificationData {
571
626
  declare function fetchIdentityState(walletPubkey: string, connection: any): Promise<IdentityState | null>;
572
627
  /**
573
628
  * Store verification data locally for re-verification.
574
- * Encrypts with AES-256-GCM when Web Crypto is available.
575
- * Falls back to plaintext with a warning otherwise.
629
+ *
630
+ * Storage tiers (preferred first):
631
+ * 1. Encrypted localStorage envelope (Web Crypto available).
632
+ * 2. If crypto unavailable AND `onPrivacyFallback` callback registered
633
+ * AND the callback resolves true, plaintext localStorage. The host
634
+ * app is responsible for surfacing the privacy tradeoff to the user
635
+ * before approving the fallback.
636
+ * 3. Otherwise, in-memory only (lost on reload). Safer default —
637
+ * never silently writes plaintext to localStorage.
576
638
  */
577
639
  declare function storeVerificationData(data: StoredVerificationData): Promise<void>;
578
640
  /**