@iam-protocol/pulse-sdk 0.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/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/index.d.mts +376 -0
- package/dist/index.d.ts +376 -0
- package/dist/index.js +14316 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +14238 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +51 -0
- package/src/challenge/lissajous.ts +56 -0
- package/src/challenge/phrase.ts +29 -0
- package/src/config.ts +40 -0
- package/src/extraction/kinematic.ts +101 -0
- package/src/extraction/mfcc.ts +93 -0
- package/src/extraction/statistics.ts +59 -0
- package/src/extraction/types.ts +17 -0
- package/src/hashing/poseidon.ts +92 -0
- package/src/hashing/simhash.ts +87 -0
- package/src/hashing/types.ts +16 -0
- package/src/identity/anchor.ts +75 -0
- package/src/identity/types.ts +18 -0
- package/src/index.ts +43 -0
- package/src/proof/prover.ts +87 -0
- package/src/proof/serializer.ts +79 -0
- package/src/proof/types.ts +31 -0
- package/src/pulse.ts +397 -0
- package/src/sensor/audio.ts +94 -0
- package/src/sensor/motion.ts +83 -0
- package/src/sensor/touch.ts +65 -0
- package/src/sensor/types.ts +55 -0
- package/src/submit/relayer.ts +58 -0
- package/src/submit/types.ts +15 -0
- package/src/submit/wallet.ts +167 -0
- package/src/types.d.ts +14 -0
- package/test/integration.test.ts +102 -0
- package/test/poseidon.test.ts +81 -0
- package/test/serializer.test.ts +86 -0
- package/test/simhash.test.ts +57 -0
- package/test/statistics.test.ts +51 -0
- package/tsconfig.json +21 -0
- package/tsup.config.ts +10 -0
- package/vitest.config.ts +8 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 IAM Protocol
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# @iam-protocol/pulse-sdk
|
|
2
|
+
|
|
3
|
+
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
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @iam-protocol/pulse-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { PulseSDK } from '@iam-protocol/pulse-sdk';
|
|
15
|
+
|
|
16
|
+
const pulse = new PulseSDK({
|
|
17
|
+
cluster: 'devnet',
|
|
18
|
+
relayerUrl: 'https://api.iam-human.io/relay', // walletless mode
|
|
19
|
+
wasmUrl: '/circuits/iam_hamming.wasm',
|
|
20
|
+
zkeyUrl: '/circuits/iam_hamming_final.zkey',
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Verify (captures sensors, generates proof, submits)
|
|
24
|
+
const result = await pulse.verify(touchElement);
|
|
25
|
+
|
|
26
|
+
if (result.success) {
|
|
27
|
+
console.log('Verified:', result.txSignature);
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Wallet-connected mode
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { PulseSDK } from '@iam-protocol/pulse-sdk';
|
|
35
|
+
|
|
36
|
+
const pulse = new PulseSDK({ cluster: 'devnet' });
|
|
37
|
+
const result = await pulse.verify(touchElement, walletAdapter, connection);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Pipeline
|
|
41
|
+
|
|
42
|
+
1. **Capture**: Audio (16kHz), IMU (accelerometer + gyroscope), touch (pressure + area) — event-driven, caller controls duration
|
|
43
|
+
2. **Extract**: MFCC (voice), jerk/jounce (motion), velocity/pressure (touch)
|
|
44
|
+
3. **Hash**: SimHash → 256-bit Temporal Fingerprint → Poseidon commitment
|
|
45
|
+
4. **Prove**: Groth16 proof that new fingerprint is within Hamming distance of previous
|
|
46
|
+
5. **Submit**: On-chain verification via wallet or relayer
|
|
47
|
+
|
|
48
|
+
## Development
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install
|
|
52
|
+
npm test # 31 vitest tests
|
|
53
|
+
npm run build # ESM + CJS output
|
|
54
|
+
npm run typecheck # TypeScript strict mode
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## License
|
|
58
|
+
|
|
59
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
declare const FINGERPRINT_BITS = 256;
|
|
2
|
+
declare const DEFAULT_THRESHOLD = 30;
|
|
3
|
+
declare const MIN_CAPTURE_MS = 2000;
|
|
4
|
+
declare const MAX_CAPTURE_MS = 60000;
|
|
5
|
+
declare const DEFAULT_CAPTURE_MS = 7000;
|
|
6
|
+
declare const PROGRAM_IDS: {
|
|
7
|
+
readonly iamAnchor: "GZYwTp2ozeuRA5Gof9vs4ya961aANcJBdUzB7LN6q4b2";
|
|
8
|
+
readonly iamVerifier: "4F97jNoxQzT2qRbkWpW3ztC3Nz2TtKj3rnKG8ExgnrfV";
|
|
9
|
+
readonly iamRegistry: "6VBs3zr9KrfFPGd6j7aGBPQWwZa5tajVfA7HN6MMV9VW";
|
|
10
|
+
};
|
|
11
|
+
interface PulseConfig {
|
|
12
|
+
cluster: "devnet" | "mainnet-beta" | "localnet";
|
|
13
|
+
rpcEndpoint?: string;
|
|
14
|
+
relayerUrl?: string;
|
|
15
|
+
zkeyUrl?: string;
|
|
16
|
+
wasmUrl?: string;
|
|
17
|
+
threshold?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Raw audio samples captured during the Pulse challenge */
|
|
21
|
+
interface AudioCapture {
|
|
22
|
+
samples: Float32Array;
|
|
23
|
+
sampleRate: number;
|
|
24
|
+
duration: number;
|
|
25
|
+
}
|
|
26
|
+
/** Single IMU reading */
|
|
27
|
+
interface MotionSample {
|
|
28
|
+
timestamp: number;
|
|
29
|
+
ax: number;
|
|
30
|
+
ay: number;
|
|
31
|
+
az: number;
|
|
32
|
+
gx: number;
|
|
33
|
+
gy: number;
|
|
34
|
+
gz: number;
|
|
35
|
+
}
|
|
36
|
+
/** Single touch reading */
|
|
37
|
+
interface TouchSample {
|
|
38
|
+
timestamp: number;
|
|
39
|
+
x: number;
|
|
40
|
+
y: number;
|
|
41
|
+
pressure: number;
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
}
|
|
45
|
+
/** Options for event-driven sensor capture */
|
|
46
|
+
interface CaptureOptions {
|
|
47
|
+
/** AbortSignal to stop capture. If omitted, captures for maxDurationMs. */
|
|
48
|
+
signal?: AbortSignal;
|
|
49
|
+
/** Minimum capture duration in ms. Capture continues until this even if signal fires early. Default: 2000 */
|
|
50
|
+
minDurationMs?: number;
|
|
51
|
+
/** Maximum capture duration in ms. Auto-stops if signal hasn't fired. Default: 60000 */
|
|
52
|
+
maxDurationMs?: number;
|
|
53
|
+
}
|
|
54
|
+
/** Stage of a capture session */
|
|
55
|
+
type CaptureStage = "audio" | "motion" | "touch";
|
|
56
|
+
/** State of an individual capture stage */
|
|
57
|
+
type StageState = "idle" | "capturing" | "captured" | "skipped";
|
|
58
|
+
/** Combined sensor data from a Pulse capture session */
|
|
59
|
+
interface SensorData {
|
|
60
|
+
audio: AudioCapture | null;
|
|
61
|
+
motion: MotionSample[];
|
|
62
|
+
touch: TouchSample[];
|
|
63
|
+
modalities: {
|
|
64
|
+
audio: boolean;
|
|
65
|
+
motion: boolean;
|
|
66
|
+
touch: boolean;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Result of a verification submission */
|
|
71
|
+
interface SubmissionResult {
|
|
72
|
+
success: boolean;
|
|
73
|
+
txSignature?: string;
|
|
74
|
+
error?: string;
|
|
75
|
+
}
|
|
76
|
+
/** Result of a full Pulse verification */
|
|
77
|
+
interface VerificationResult {
|
|
78
|
+
success: boolean;
|
|
79
|
+
commitment: Uint8Array;
|
|
80
|
+
txSignature?: string;
|
|
81
|
+
isFirstVerification: boolean;
|
|
82
|
+
error?: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
type ResolvedConfig = Required<Pick<PulseConfig, "cluster" | "threshold">> & PulseConfig;
|
|
86
|
+
/**
|
|
87
|
+
* PulseSession — event-driven staged capture session.
|
|
88
|
+
*
|
|
89
|
+
* Gives the caller control over when each sensor stage starts and stops.
|
|
90
|
+
* After all stages complete, call complete() to run the processing pipeline.
|
|
91
|
+
*
|
|
92
|
+
* Usage:
|
|
93
|
+
* const session = pulse.createSession(touchElement);
|
|
94
|
+
* await session.startAudio();
|
|
95
|
+
* // ... user speaks ...
|
|
96
|
+
* await session.stopAudio();
|
|
97
|
+
* await session.startMotion();
|
|
98
|
+
* // ... user holds device ...
|
|
99
|
+
* await session.stopMotion();
|
|
100
|
+
* await session.startTouch();
|
|
101
|
+
* // ... user traces curve ...
|
|
102
|
+
* await session.stopTouch();
|
|
103
|
+
* const result = await session.complete(wallet, connection);
|
|
104
|
+
*/
|
|
105
|
+
declare class PulseSession {
|
|
106
|
+
private config;
|
|
107
|
+
private touchElement;
|
|
108
|
+
private audioStageState;
|
|
109
|
+
private motionStageState;
|
|
110
|
+
private touchStageState;
|
|
111
|
+
private audioController;
|
|
112
|
+
private motionController;
|
|
113
|
+
private touchController;
|
|
114
|
+
private audioPromise;
|
|
115
|
+
private motionPromise;
|
|
116
|
+
private touchPromise;
|
|
117
|
+
private audioData;
|
|
118
|
+
private motionData;
|
|
119
|
+
private touchData;
|
|
120
|
+
constructor(config: ResolvedConfig, touchElement?: HTMLElement);
|
|
121
|
+
startAudio(): Promise<void>;
|
|
122
|
+
stopAudio(): Promise<AudioCapture | null>;
|
|
123
|
+
skipAudio(): void;
|
|
124
|
+
startMotion(): Promise<void>;
|
|
125
|
+
stopMotion(): Promise<MotionSample[]>;
|
|
126
|
+
skipMotion(): void;
|
|
127
|
+
startTouch(): Promise<void>;
|
|
128
|
+
stopTouch(): Promise<TouchSample[]>;
|
|
129
|
+
skipTouch(): void;
|
|
130
|
+
complete(wallet?: any, connection?: any): Promise<VerificationResult>;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* PulseSDK — main entry point for IAM Protocol verification.
|
|
134
|
+
*
|
|
135
|
+
* Two usage modes:
|
|
136
|
+
* 1. Simple (backward-compatible): pulse.verify(touchElement) — captures all sensors
|
|
137
|
+
* for DEFAULT_CAPTURE_MS in parallel, then processes.
|
|
138
|
+
* 2. Staged (event-driven): pulse.createSession(touchElement) — caller controls
|
|
139
|
+
* when each sensor stage starts and stops.
|
|
140
|
+
*/
|
|
141
|
+
declare class PulseSDK {
|
|
142
|
+
private config;
|
|
143
|
+
constructor(config: PulseConfig);
|
|
144
|
+
/**
|
|
145
|
+
* Create a staged capture session for event-driven control.
|
|
146
|
+
*/
|
|
147
|
+
createSession(touchElement?: HTMLElement): PulseSession;
|
|
148
|
+
/**
|
|
149
|
+
* Run a full verification with automatic timed capture (backward-compatible).
|
|
150
|
+
* Captures all sensors in parallel for DEFAULT_CAPTURE_MS, then processes.
|
|
151
|
+
*/
|
|
152
|
+
verify(touchElement?: HTMLElement, wallet?: any, connection?: any): Promise<VerificationResult>;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** 256-bit Temporal Fingerprint as an array of 0/1 values */
|
|
156
|
+
type TemporalFingerprint = number[];
|
|
157
|
+
/** Temporal-Biometric Hash: commitment + data needed for re-verification */
|
|
158
|
+
interface TBH {
|
|
159
|
+
fingerprint: TemporalFingerprint;
|
|
160
|
+
salt: bigint;
|
|
161
|
+
commitment: bigint;
|
|
162
|
+
commitmentBytes: Uint8Array;
|
|
163
|
+
}
|
|
164
|
+
/** Packed field elements from bit packing (2 × 128-bit) */
|
|
165
|
+
interface PackedFingerprint {
|
|
166
|
+
lo: bigint;
|
|
167
|
+
hi: bigint;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Compute a 256-bit SimHash fingerprint from a feature vector.
|
|
172
|
+
* Uses deterministic random hyperplanes seeded from the protocol constant.
|
|
173
|
+
* Similar feature vectors produce fingerprints with low Hamming distance.
|
|
174
|
+
*/
|
|
175
|
+
declare function simhash(features: number[]): TemporalFingerprint;
|
|
176
|
+
/**
|
|
177
|
+
* Compute Hamming distance between two fingerprints.
|
|
178
|
+
*/
|
|
179
|
+
declare function hammingDistance(a: TemporalFingerprint, b: TemporalFingerprint): number;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Pack 256-bit fingerprint into two 128-bit field elements.
|
|
183
|
+
* Little-endian bit ordering within each chunk (matches circuit's Bits2Num).
|
|
184
|
+
*/
|
|
185
|
+
declare function packBits(fingerprint: TemporalFingerprint): PackedFingerprint;
|
|
186
|
+
/**
|
|
187
|
+
* Compute Poseidon commitment: Poseidon(pack_lo, pack_hi, salt).
|
|
188
|
+
* Matches the circuit's CommitmentCheck template exactly.
|
|
189
|
+
*/
|
|
190
|
+
declare function computeCommitment(fingerprint: TemporalFingerprint, salt: bigint): Promise<bigint>;
|
|
191
|
+
/**
|
|
192
|
+
* Generate a random salt within the BN254 scalar field.
|
|
193
|
+
*/
|
|
194
|
+
declare function generateSalt(): bigint;
|
|
195
|
+
/**
|
|
196
|
+
* Convert a BigInt to a 32-byte big-endian Uint8Array.
|
|
197
|
+
*/
|
|
198
|
+
declare function bigintToBytes32(n: bigint): Uint8Array;
|
|
199
|
+
/**
|
|
200
|
+
* Generate a complete TBH from a fingerprint.
|
|
201
|
+
*/
|
|
202
|
+
declare function generateTBH(fingerprint: TemporalFingerprint, salt?: bigint): Promise<TBH>;
|
|
203
|
+
|
|
204
|
+
/** Statistical summary of a time series */
|
|
205
|
+
interface StatsSummary {
|
|
206
|
+
mean: number;
|
|
207
|
+
variance: number;
|
|
208
|
+
skewness: number;
|
|
209
|
+
kurtosis: number;
|
|
210
|
+
}
|
|
211
|
+
/** Feature vector from all sensor modalities */
|
|
212
|
+
interface FeatureVector {
|
|
213
|
+
audio: number[];
|
|
214
|
+
motion: number[];
|
|
215
|
+
touch: number[];
|
|
216
|
+
}
|
|
217
|
+
/** Concatenated feature vector for SimHash input */
|
|
218
|
+
type FusedFeatureVector = number[];
|
|
219
|
+
|
|
220
|
+
declare function mean(values: number[]): number;
|
|
221
|
+
declare function variance(values: number[], mu?: number): number;
|
|
222
|
+
declare function skewness(values: number[]): number;
|
|
223
|
+
declare function kurtosis(values: number[]): number;
|
|
224
|
+
declare function condense(values: number[]): StatsSummary;
|
|
225
|
+
declare function fuseFeatures(audio: number[], motion: number[], touch: number[]): number[];
|
|
226
|
+
|
|
227
|
+
/** Serialized proof ready for on-chain submission */
|
|
228
|
+
interface SolanaProof {
|
|
229
|
+
proofBytes: Uint8Array;
|
|
230
|
+
publicInputs: Uint8Array[];
|
|
231
|
+
}
|
|
232
|
+
/** Raw snarkjs proof output */
|
|
233
|
+
interface RawProof {
|
|
234
|
+
pi_a: string[];
|
|
235
|
+
pi_b: string[][];
|
|
236
|
+
pi_c: string[];
|
|
237
|
+
protocol: string;
|
|
238
|
+
curve: string;
|
|
239
|
+
}
|
|
240
|
+
/** Circuit input for proof generation */
|
|
241
|
+
interface CircuitInput {
|
|
242
|
+
ft_new: number[];
|
|
243
|
+
ft_prev: number[];
|
|
244
|
+
salt_new: string;
|
|
245
|
+
salt_prev: string;
|
|
246
|
+
commitment_new: string;
|
|
247
|
+
commitment_prev: string;
|
|
248
|
+
threshold: string;
|
|
249
|
+
}
|
|
250
|
+
/** Proof generation result */
|
|
251
|
+
interface ProofResult {
|
|
252
|
+
proof: RawProof;
|
|
253
|
+
publicSignals: string[];
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Convert a decimal string to a 32-byte big-endian Uint8Array.
|
|
258
|
+
*/
|
|
259
|
+
declare function toBigEndian32(decStr: string): Uint8Array;
|
|
260
|
+
/**
|
|
261
|
+
* Serialize an snarkjs proof into the 256-byte format groth16-solana expects.
|
|
262
|
+
*
|
|
263
|
+
* proof_a: 64 bytes (x + negated y)
|
|
264
|
+
* proof_b: 128 bytes (G2 with reversed coordinate ordering: c1 before c0)
|
|
265
|
+
* proof_c: 64 bytes (x + y)
|
|
266
|
+
*/
|
|
267
|
+
declare function serializeProof(proof: RawProof, publicSignals: string[]): SolanaProof;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Prepare circuit input from current and previous TBH data.
|
|
271
|
+
*/
|
|
272
|
+
declare function prepareCircuitInput(current: TBH, previous: TBH, threshold?: number): CircuitInput;
|
|
273
|
+
/**
|
|
274
|
+
* Generate a Groth16 proof for the Hamming distance circuit.
|
|
275
|
+
*
|
|
276
|
+
* @param input - Circuit input (fingerprints, salts, commitments, threshold)
|
|
277
|
+
* @param wasmPath - Path or URL to iam_hamming.wasm
|
|
278
|
+
* @param zkeyPath - Path or URL to iam_hamming_final.zkey
|
|
279
|
+
*/
|
|
280
|
+
declare function generateProof(input: CircuitInput, wasmPath: string, zkeyPath: string): Promise<ProofResult>;
|
|
281
|
+
/**
|
|
282
|
+
* Generate a proof and serialize it for Solana submission.
|
|
283
|
+
*/
|
|
284
|
+
declare function generateSolanaProof(current: TBH, previous: TBH, wasmPath: string, zkeyPath: string, threshold?: number): Promise<SolanaProof>;
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Submit a proof on-chain via a connected wallet (wallet-connected mode).
|
|
288
|
+
* Uses Anchor SDK to construct and send the transaction.
|
|
289
|
+
*
|
|
290
|
+
* Flow: create_challenge → verify_proof → update_anchor (or mint_anchor for first time)
|
|
291
|
+
*/
|
|
292
|
+
declare function submitViaWallet(proof: SolanaProof, commitment: Uint8Array, options: {
|
|
293
|
+
wallet: any;
|
|
294
|
+
connection: any;
|
|
295
|
+
isFirstVerification: boolean;
|
|
296
|
+
trustScore?: number;
|
|
297
|
+
}): Promise<SubmissionResult>;
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Submit a proof via the IAM relayer API (walletless mode).
|
|
301
|
+
* The relayer submits the on-chain transaction using the integrator's funded account.
|
|
302
|
+
* The user needs no wallet, no SOL, no crypto knowledge.
|
|
303
|
+
*
|
|
304
|
+
* In Phase 3, the relayer endpoint is configurable (stub until executor-node in Phase 4).
|
|
305
|
+
*/
|
|
306
|
+
declare function submitViaRelayer(proof: SolanaProof, commitment: Uint8Array, options: {
|
|
307
|
+
relayerUrl: string;
|
|
308
|
+
apiKey?: string;
|
|
309
|
+
isFirstVerification: boolean;
|
|
310
|
+
}): Promise<SubmissionResult>;
|
|
311
|
+
|
|
312
|
+
/** On-chain identity state (mirrors the Anchor program's IdentityState) */
|
|
313
|
+
interface IdentityState {
|
|
314
|
+
owner: string;
|
|
315
|
+
creationTimestamp: number;
|
|
316
|
+
lastVerificationTimestamp: number;
|
|
317
|
+
verificationCount: number;
|
|
318
|
+
trustScore: number;
|
|
319
|
+
currentCommitment: Uint8Array;
|
|
320
|
+
mint: string;
|
|
321
|
+
}
|
|
322
|
+
/** Local storage of previous verification data (needed for re-verification) */
|
|
323
|
+
interface StoredVerificationData {
|
|
324
|
+
fingerprint: number[];
|
|
325
|
+
salt: string;
|
|
326
|
+
commitment: string;
|
|
327
|
+
timestamp: number;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Fetch identity state from the on-chain IdentityState PDA.
|
|
332
|
+
*/
|
|
333
|
+
declare function fetchIdentityState(walletPubkey: string, connection: any): Promise<IdentityState | null>;
|
|
334
|
+
/**
|
|
335
|
+
* Store verification data locally for re-verification.
|
|
336
|
+
* Uses localStorage (browser) or in-memory fallback (Node.js).
|
|
337
|
+
*/
|
|
338
|
+
declare function storeVerificationData(data: StoredVerificationData): void;
|
|
339
|
+
/**
|
|
340
|
+
* Load previously stored verification data.
|
|
341
|
+
*/
|
|
342
|
+
declare function loadVerificationData(): StoredVerificationData | null;
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Generate a random phonetically-balanced phrase for the voice challenge.
|
|
346
|
+
* Each phrase is 5-6 syllable pairs, forming nonsensical but speakable words.
|
|
347
|
+
*/
|
|
348
|
+
declare function generatePhrase(wordCount?: number): string;
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Generate Lissajous curve points for the touch tracing challenge.
|
|
352
|
+
* The user traces this shape on screen while speaking the phrase.
|
|
353
|
+
*
|
|
354
|
+
* x(t) = A * sin(a*t + delta)
|
|
355
|
+
* y(t) = B * sin(b*t)
|
|
356
|
+
*/
|
|
357
|
+
interface LissajousParams {
|
|
358
|
+
a: number;
|
|
359
|
+
b: number;
|
|
360
|
+
delta: number;
|
|
361
|
+
points: number;
|
|
362
|
+
}
|
|
363
|
+
interface Point2D {
|
|
364
|
+
x: number;
|
|
365
|
+
y: number;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Generate random Lissajous parameters for a challenge.
|
|
369
|
+
*/
|
|
370
|
+
declare function randomLissajousParams(): LissajousParams;
|
|
371
|
+
/**
|
|
372
|
+
* Generate Lissajous curve points normalized to [0, 1] range.
|
|
373
|
+
*/
|
|
374
|
+
declare function generateLissajousPoints(params: LissajousParams): Point2D[];
|
|
375
|
+
|
|
376
|
+
export { type AudioCapture, type CaptureOptions, type CaptureStage, type CircuitInput, DEFAULT_CAPTURE_MS, DEFAULT_THRESHOLD, FINGERPRINT_BITS, type FeatureVector, type FusedFeatureVector, type IdentityState, type LissajousParams, MAX_CAPTURE_MS, MIN_CAPTURE_MS, type MotionSample, PROGRAM_IDS, type PackedFingerprint, type Point2D, type ProofResult, type PulseConfig, PulseSDK, PulseSession, type SensorData, type SolanaProof, type StageState, type StatsSummary, type StoredVerificationData, type SubmissionResult, type TBH, type TemporalFingerprint, type TouchSample, type VerificationResult, bigintToBytes32, computeCommitment, condense, fetchIdentityState, fuseFeatures, generateLissajousPoints, generatePhrase, generateProof, generateSalt, generateSolanaProof, generateTBH, hammingDistance, kurtosis, loadVerificationData, mean, packBits, prepareCircuitInput, randomLissajousParams, serializeProof, simhash, skewness, storeVerificationData, submitViaRelayer, submitViaWallet, toBigEndian32, variance };
|