@entros/pulse-sdk 1.1.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/README.md +6 -0
- package/dist/index.d.mts +77 -2
- package/dist/index.d.ts +77 -2
- package/dist/index.js +194 -102
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +194 -102
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -63,6 +63,12 @@ npm run build # ESM + CJS output
|
|
|
63
63
|
npm run typecheck # TypeScript strict mode
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
## Migration history
|
|
67
|
+
|
|
68
|
+
Originally published as `@iam-protocol/pulse-sdk` (deprecated). Renamed during
|
|
69
|
+
the IAM → Entros Protocol rebrand on 2026-04-25; full commit history preserved
|
|
70
|
+
on the current repository at `github.com/entros-protocol/pulse-sdk`.
|
|
71
|
+
|
|
66
72
|
## License
|
|
67
73
|
|
|
68
74
|
MIT
|
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;
|
|
@@ -92,6 +128,29 @@ interface VerificationResult {
|
|
|
92
128
|
attestationTx?: string;
|
|
93
129
|
isFirstVerification: boolean;
|
|
94
130
|
error?: string;
|
|
131
|
+
/**
|
|
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.
|
|
146
|
+
*
|
|
147
|
+
* Absent on every other failure path (data-quality, on-chain submission,
|
|
148
|
+
* baseline missing, etc.) and on attack-signal rejections (TTS detection,
|
|
149
|
+
* Sybil match) and capture-shape bugs — the validator deliberately keeps
|
|
150
|
+
* those opaque to prevent adversarial probing. UI must not assume reason
|
|
151
|
+
* is present even when `success === false`.
|
|
152
|
+
*/
|
|
153
|
+
reason?: string;
|
|
95
154
|
}
|
|
96
155
|
|
|
97
156
|
type ResolvedConfig = Required<Pick<PulseConfig, "cluster" | "threshold">> & PulseConfig;
|
|
@@ -432,6 +491,15 @@ declare function submitViaWallet(proof: SolanaProof, commitment: Uint8Array, opt
|
|
|
432
491
|
isFirstVerification: boolean;
|
|
433
492
|
relayerUrl?: string;
|
|
434
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;
|
|
435
503
|
}): Promise<SubmissionResult>;
|
|
436
504
|
/**
|
|
437
505
|
* Submit a baseline reset on-chain via a connected wallet.
|
|
@@ -558,8 +626,15 @@ interface StoredVerificationData {
|
|
|
558
626
|
declare function fetchIdentityState(walletPubkey: string, connection: any): Promise<IdentityState | null>;
|
|
559
627
|
/**
|
|
560
628
|
* Store verification data locally for re-verification.
|
|
561
|
-
*
|
|
562
|
-
*
|
|
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.
|
|
563
638
|
*/
|
|
564
639
|
declare function storeVerificationData(data: StoredVerificationData): Promise<void>;
|
|
565
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;
|
|
@@ -92,6 +128,29 @@ interface VerificationResult {
|
|
|
92
128
|
attestationTx?: string;
|
|
93
129
|
isFirstVerification: boolean;
|
|
94
130
|
error?: string;
|
|
131
|
+
/**
|
|
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.
|
|
146
|
+
*
|
|
147
|
+
* Absent on every other failure path (data-quality, on-chain submission,
|
|
148
|
+
* baseline missing, etc.) and on attack-signal rejections (TTS detection,
|
|
149
|
+
* Sybil match) and capture-shape bugs — the validator deliberately keeps
|
|
150
|
+
* those opaque to prevent adversarial probing. UI must not assume reason
|
|
151
|
+
* is present even when `success === false`.
|
|
152
|
+
*/
|
|
153
|
+
reason?: string;
|
|
95
154
|
}
|
|
96
155
|
|
|
97
156
|
type ResolvedConfig = Required<Pick<PulseConfig, "cluster" | "threshold">> & PulseConfig;
|
|
@@ -432,6 +491,15 @@ declare function submitViaWallet(proof: SolanaProof, commitment: Uint8Array, opt
|
|
|
432
491
|
isFirstVerification: boolean;
|
|
433
492
|
relayerUrl?: string;
|
|
434
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;
|
|
435
503
|
}): Promise<SubmissionResult>;
|
|
436
504
|
/**
|
|
437
505
|
* Submit a baseline reset on-chain via a connected wallet.
|
|
@@ -558,8 +626,15 @@ interface StoredVerificationData {
|
|
|
558
626
|
declare function fetchIdentityState(walletPubkey: string, connection: any): Promise<IdentityState | null>;
|
|
559
627
|
/**
|
|
560
628
|
* Store verification data locally for re-verification.
|
|
561
|
-
*
|
|
562
|
-
*
|
|
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.
|
|
563
638
|
*/
|
|
564
639
|
declare function storeVerificationData(data: StoredVerificationData): Promise<void>;
|
|
565
640
|
/**
|