@jupitermetalabs/face-zk-sdk 0.3.4 → 0.3.7
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 +46 -1
- package/assets/face-guidance/pose-guidance.js.txt +4 -2
- package/assets/liveness/liveness.js.txt +3 -0
- package/dist/FaceZkSdk.d.ts +69 -0
- package/dist/FaceZkSdk.js +136 -0
- package/dist/assets/face-guidance/pose-guidance.js.txt +4 -2
- package/dist/assets/liveness/liveness.js.txt +3 -0
- package/dist/assets/onnx/ort-min.d.ts +1 -0
- package/dist/assets/onnx/ort-min.js +11 -0
- package/dist/config/defaults.d.ts +51 -0
- package/dist/config/defaults.js +61 -0
- package/dist/config/types.d.ts +169 -0
- package/dist/config/types.js +17 -0
- package/dist/core/enrollment-core.d.ts +70 -0
- package/dist/core/enrollment-core.js +206 -0
- package/dist/core/idGenerator.d.ts +11 -0
- package/dist/core/idGenerator.js +32 -0
- package/dist/core/matching.d.ts +69 -0
- package/dist/core/matching.js +101 -0
- package/dist/core/types.d.ts +379 -0
- package/dist/core/types.js +37 -0
- package/dist/core/verification-core.d.ts +120 -0
- package/dist/core/verification-core.js +442 -0
- package/dist/core/zk-core.d.ts +69 -0
- package/dist/core/zk-core.js +244 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +51 -0
- package/dist/react-native/adapters/faceEmbeddingProvider.d.ts +38 -0
- package/dist/react-native/adapters/faceEmbeddingProvider.js +45 -0
- package/dist/react-native/adapters/imageDataProvider.d.ts +53 -0
- package/dist/react-native/adapters/imageDataProvider.js +134 -0
- package/dist/react-native/adapters/livenessProvider.d.ts +133 -0
- package/dist/react-native/adapters/livenessProvider.js +150 -0
- package/dist/react-native/adapters/zkProofEngine-webview.d.ts +73 -0
- package/dist/react-native/adapters/zkProofEngine-webview.js +135 -0
- package/dist/react-native/bundledRuntimeAssets.d.ts +39 -0
- package/dist/react-native/bundledRuntimeAssets.js +44 -0
- package/dist/react-native/components/FacePoseGuidanceWebView.d.ts +30 -0
- package/dist/react-native/components/FacePoseGuidanceWebView.js +530 -0
- package/dist/react-native/components/LivenessWebView.d.ts +39 -0
- package/dist/react-native/components/LivenessWebView.js +386 -0
- package/dist/react-native/components/OnnxRuntimeWebView.d.ts +58 -0
- package/dist/react-native/components/OnnxRuntimeWebView.js +518 -0
- package/dist/react-native/components/ZkProofWebView.d.ts +59 -0
- package/dist/react-native/components/ZkProofWebView.js +297 -0
- package/dist/react-native/dependencies.d.ts +144 -0
- package/dist/react-native/dependencies.js +130 -0
- package/dist/react-native/hooks/useOnnxLoader.d.ts +37 -0
- package/dist/react-native/hooks/useOnnxLoader.js +74 -0
- package/dist/react-native/hooks/useWasmLoader.d.ts +30 -0
- package/dist/react-native/hooks/useWasmLoader.js +158 -0
- package/dist/react-native/index.d.ts +61 -0
- package/dist/react-native/index.js +144 -0
- package/dist/react-native/services/FaceRecognition.d.ts +92 -0
- package/dist/react-native/services/FaceRecognition.js +674 -0
- package/dist/react-native/ui/FaceZkVerificationFlow.d.ts +97 -0
- package/dist/react-native/ui/FaceZkVerificationFlow.js +477 -0
- package/dist/react-native/ui/ReferenceEnrollmentFlow.d.ts +72 -0
- package/dist/react-native/ui/ReferenceEnrollmentFlow.js +369 -0
- package/dist/react-native/utils/faceAlignment.d.ts +37 -0
- package/dist/react-native/utils/faceAlignment.js +186 -0
- package/dist/react-native/utils/modelInitialisationChecks.d.ts +36 -0
- package/dist/react-native/utils/modelInitialisationChecks.js +128 -0
- package/dist/react-native/utils/resolveModelUri.d.ts +55 -0
- package/dist/react-native/utils/resolveModelUri.js +211 -0
- package/dist/react-native/utils/resolveRuntimeAsset.d.ts +25 -0
- package/dist/react-native/utils/resolveRuntimeAsset.js +94 -0
- package/dist/react-native/utils/resolveUiConfig.d.ts +41 -0
- package/dist/react-native/utils/resolveUiConfig.js +81 -0
- package/dist/storage/defaultStorageAdapter.d.ts +44 -0
- package/dist/storage/defaultStorageAdapter.js +344 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/face-zk.config.example.js +10 -3
- package/package.json +2 -2
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 JupiterMeta Labs
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Face+ZK SDK – Matching Core
|
|
18
|
+
*
|
|
19
|
+
* Pure matching functions for face embeddings.
|
|
20
|
+
* All functions are synchronous and have no side effects for easy testing.
|
|
21
|
+
*
|
|
22
|
+
* Based on: src/utils/mathUtils.ts
|
|
23
|
+
*/
|
|
24
|
+
import type { FloatVector, FaceMatchResult } from "./types";
|
|
25
|
+
/**
|
|
26
|
+
* Calculates the L2 squared distance between two vectors.
|
|
27
|
+
* More efficient for mobile devices as it skips square root operations and bounds checking.
|
|
28
|
+
*
|
|
29
|
+
* **Crypto/ZK Context:** The raw distance computed here provides UI feedback, but the actual cryptographic proof relies on the unaltered feature vectors.
|
|
30
|
+
*
|
|
31
|
+
* @param {FloatVector} a - First facial embedding vector.
|
|
32
|
+
* @param {FloatVector} b - Second facial embedding vector.
|
|
33
|
+
* @returns {number} The L2² distance. Lower is better. 0 = identical vectors.
|
|
34
|
+
* @throws {Error} Throws if vectors are empty or mismatched in length.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* const dist = l2SquaredDistance(liveEmbedding, refEmbedding);
|
|
38
|
+
* console.log(`Distance: ${dist}`);
|
|
39
|
+
*/
|
|
40
|
+
export declare function l2SquaredDistance(a: FloatVector, b: FloatVector): number;
|
|
41
|
+
/**
|
|
42
|
+
* Converts L2² distance to a human-readable percentage match score.
|
|
43
|
+
*
|
|
44
|
+
* Precondition: `l2Squared` is the scalar output of `l2SquaredDistance` applied to
|
|
45
|
+
* two normalized embeddings, which places it in [0, 4].
|
|
46
|
+
*
|
|
47
|
+
* @param {number} l2Squared - The L2 squared distance (scalar).
|
|
48
|
+
* @returns {number} Match percentage (0-100). Higher is better.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* const percentage = l2SquaredToPercentage(1.2);
|
|
52
|
+
* console.log(`Match: ${percentage}%`); // Extrapolates onto a 0-100 curve
|
|
53
|
+
*/
|
|
54
|
+
export declare function l2SquaredToPercentage(l2Squared: number): number;
|
|
55
|
+
/**
|
|
56
|
+
* Computes a face match result from two embeddings for informational use.
|
|
57
|
+
*
|
|
58
|
+
* **Important:** This function no longer returns a boolean pass/fail flag.
|
|
59
|
+
* Pass/fail is determined by the ZK engine (which explicitly owns the threshold), not by this function.
|
|
60
|
+
*
|
|
61
|
+
* @param {FloatVector} referenceEmbedding - Reference face embedding.
|
|
62
|
+
* @param {FloatVector} liveEmbedding - Live face embedding.
|
|
63
|
+
* @returns {FaceMatchResult} Match result containing raw distance and percentage.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* const result = computeFaceMatchResult(refEmbed, liveEmbed);
|
|
67
|
+
* console.log(`Match confidence: ${result.matchPercentage}%`);
|
|
68
|
+
*/
|
|
69
|
+
export declare function computeFaceMatchResult(referenceEmbedding: FloatVector, liveEmbedding: FloatVector): FaceMatchResult;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright 2026 JupiterMeta Labs
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.l2SquaredDistance = l2SquaredDistance;
|
|
19
|
+
exports.l2SquaredToPercentage = l2SquaredToPercentage;
|
|
20
|
+
exports.computeFaceMatchResult = computeFaceMatchResult;
|
|
21
|
+
/**
|
|
22
|
+
* Calculates the L2 squared distance between two vectors.
|
|
23
|
+
* More efficient for mobile devices as it skips square root operations and bounds checking.
|
|
24
|
+
*
|
|
25
|
+
* **Crypto/ZK Context:** The raw distance computed here provides UI feedback, but the actual cryptographic proof relies on the unaltered feature vectors.
|
|
26
|
+
*
|
|
27
|
+
* @param {FloatVector} a - First facial embedding vector.
|
|
28
|
+
* @param {FloatVector} b - Second facial embedding vector.
|
|
29
|
+
* @returns {number} The L2² distance. Lower is better. 0 = identical vectors.
|
|
30
|
+
* @throws {Error} Throws if vectors are empty or mismatched in length.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const dist = l2SquaredDistance(liveEmbedding, refEmbedding);
|
|
34
|
+
* console.log(`Distance: ${dist}`);
|
|
35
|
+
*/
|
|
36
|
+
function l2SquaredDistance(a, b) {
|
|
37
|
+
if (a.length === 0 || b.length === 0) {
|
|
38
|
+
throw new Error("l2SquaredDistance: embeddings cannot be empty");
|
|
39
|
+
}
|
|
40
|
+
if (a.length !== b.length) {
|
|
41
|
+
throw new Error(`l2SquaredDistance: embedding length mismatch (${a.length} vs ${b.length})`);
|
|
42
|
+
}
|
|
43
|
+
let sumSquared = 0;
|
|
44
|
+
const len = a.length;
|
|
45
|
+
// Unrolled loop for better performance (process 4 at a time)
|
|
46
|
+
let i = 0;
|
|
47
|
+
for (; i < len - 3; i += 4) {
|
|
48
|
+
const d0 = a[i] - b[i];
|
|
49
|
+
const d1 = a[i + 1] - b[i + 1];
|
|
50
|
+
const d2 = a[i + 2] - b[i + 2];
|
|
51
|
+
const d3 = a[i + 3] - b[i + 3];
|
|
52
|
+
sumSquared += d0 * d0 + d1 * d1 + d2 * d2 + d3 * d3;
|
|
53
|
+
}
|
|
54
|
+
// Handle remaining elements
|
|
55
|
+
for (; i < len; i++) {
|
|
56
|
+
const diff = a[i] - b[i];
|
|
57
|
+
sumSquared += diff * diff;
|
|
58
|
+
}
|
|
59
|
+
return sumSquared;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Converts L2² distance to a human-readable percentage match score.
|
|
63
|
+
*
|
|
64
|
+
* Precondition: `l2Squared` is the scalar output of `l2SquaredDistance` applied to
|
|
65
|
+
* two normalized embeddings, which places it in [0, 4].
|
|
66
|
+
*
|
|
67
|
+
* @param {number} l2Squared - The L2 squared distance (scalar).
|
|
68
|
+
* @returns {number} Match percentage (0-100). Higher is better.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* const percentage = l2SquaredToPercentage(1.2);
|
|
72
|
+
* console.log(`Match: ${percentage}%`); // Extrapolates onto a 0-100 curve
|
|
73
|
+
*/
|
|
74
|
+
function l2SquaredToPercentage(l2Squared) {
|
|
75
|
+
// For normalized vectors L2² ∈ [0, 4]; 0 = identical, 4 = maximally different.
|
|
76
|
+
// ((2 - d) / 2) × 100 maps that range linearly to 100%…0%.
|
|
77
|
+
const matchPercentage = ((2.0 - l2Squared) / 2.0) * 100;
|
|
78
|
+
return Math.max(0, Math.min(100, matchPercentage)); // Clamp to 0-100
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Computes a face match result from two embeddings for informational use.
|
|
82
|
+
*
|
|
83
|
+
* **Important:** This function no longer returns a boolean pass/fail flag.
|
|
84
|
+
* Pass/fail is determined by the ZK engine (which explicitly owns the threshold), not by this function.
|
|
85
|
+
*
|
|
86
|
+
* @param {FloatVector} referenceEmbedding - Reference face embedding.
|
|
87
|
+
* @param {FloatVector} liveEmbedding - Live face embedding.
|
|
88
|
+
* @returns {FaceMatchResult} Match result containing raw distance and percentage.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* const result = computeFaceMatchResult(refEmbed, liveEmbed);
|
|
92
|
+
* console.log(`Match confidence: ${result.matchPercentage}%`);
|
|
93
|
+
*/
|
|
94
|
+
function computeFaceMatchResult(referenceEmbedding, liveEmbedding) {
|
|
95
|
+
const distance = l2SquaredDistance(referenceEmbedding, liveEmbedding);
|
|
96
|
+
const matchPercentage = l2SquaredToPercentage(distance);
|
|
97
|
+
return {
|
|
98
|
+
distance,
|
|
99
|
+
matchPercentage,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 JupiterMeta Labs
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Face+ZK SDK – Core Type Definitions (Local-Only)
|
|
18
|
+
*
|
|
19
|
+
* This file defines the TypeScript data models for the local-only Face+ZK SDK.
|
|
20
|
+
* It is the source of truth for the SDK's API surface.
|
|
21
|
+
*
|
|
22
|
+
* Based on: docs/sdk-plan/face-zk-sdk-types-and-entrypoints.md
|
|
23
|
+
*/
|
|
24
|
+
/** Face embedding vector (e.g., 512-dimensional) */
|
|
25
|
+
export type FloatVector = number[];
|
|
26
|
+
/** Head pose estimate (angles in degrees) */
|
|
27
|
+
export type Pose = {
|
|
28
|
+
yaw: number;
|
|
29
|
+
pitch: number;
|
|
30
|
+
roll: number;
|
|
31
|
+
};
|
|
32
|
+
/** Supported liveness check types */
|
|
33
|
+
export type LivenessCheckId = "motion" | "blink" | "pose_variation" | "depth_or_3d" | "spoof_texture" | "other";
|
|
34
|
+
/** Opaque identifier for a reference template */
|
|
35
|
+
export type ReferenceId = string;
|
|
36
|
+
/**
|
|
37
|
+
* Reference template created during enrollment.
|
|
38
|
+
* Contains the face embedding and pose from the reference image.
|
|
39
|
+
*/
|
|
40
|
+
export interface ReferenceTemplate {
|
|
41
|
+
/** SDK-generated opaque ID; caller may also store their own mapping (userId → referenceId). */
|
|
42
|
+
referenceId: ReferenceId;
|
|
43
|
+
/** Face embedding derived from the reference image. */
|
|
44
|
+
embedding: FloatVector;
|
|
45
|
+
/** Head pose estimate at enrollment time. Required. */
|
|
46
|
+
pose: Pose;
|
|
47
|
+
/**
|
|
48
|
+
* Caller-defined metadata, stored in memory or via the storage adapter.
|
|
49
|
+
* Must NOT include raw PII or image bytes by default.
|
|
50
|
+
*/
|
|
51
|
+
metadata?: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* When the caller wants to provide their own reference (e.g., embeddings computed elsewhere),
|
|
55
|
+
* they can supply this shape instead of letting the SDK compute from an image URI.
|
|
56
|
+
*/
|
|
57
|
+
export interface ReferenceTemplateInput {
|
|
58
|
+
referenceId?: ReferenceId;
|
|
59
|
+
embedding: FloatVector;
|
|
60
|
+
pose: Pose;
|
|
61
|
+
metadata?: Record<string, unknown>;
|
|
62
|
+
}
|
|
63
|
+
/** Metadata about a captured live image */
|
|
64
|
+
export interface LiveImageInfo {
|
|
65
|
+
/** URI of the final chosen live frame (e.g., camera capture). */
|
|
66
|
+
imageUri?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Optional base64-encoded image string for callers that need it.
|
|
69
|
+
* SDK should not persist this unless a storage adapter is explicitly configured to do so.
|
|
70
|
+
*/
|
|
71
|
+
imageBase64?: string;
|
|
72
|
+
/** Approximate size in kilobytes (if base64 is available). */
|
|
73
|
+
sizeKb?: number;
|
|
74
|
+
/** Optional quality score (0–1, higher = better). */
|
|
75
|
+
qualityScore?: number;
|
|
76
|
+
}
|
|
77
|
+
/** Result of live capture including embedding and pose */
|
|
78
|
+
export interface LiveCaptureResult {
|
|
79
|
+
/** Embedding computed from the final live frame. */
|
|
80
|
+
embedding: FloatVector;
|
|
81
|
+
/** Pose estimate at capture time. */
|
|
82
|
+
pose?: Pose;
|
|
83
|
+
/** Image metadata for the captured frame. */
|
|
84
|
+
image?: LiveImageInfo;
|
|
85
|
+
/** Detected gender if model is configured */
|
|
86
|
+
gender?: "Male" | "Female" | "Unknown";
|
|
87
|
+
/** Estimated age if model is configured */
|
|
88
|
+
age?: number;
|
|
89
|
+
/**
|
|
90
|
+
* Raw MediaPipe FaceMesh landmarks at capture time (468 points + iris if refineLandmarks=true).
|
|
91
|
+
* Each point is normalized to [0,1] relative to the video frame.
|
|
92
|
+
* Useful for research and model improvement — not required for SDK operation.
|
|
93
|
+
*/
|
|
94
|
+
faceMeshLandmarks?: Array<{
|
|
95
|
+
x: number;
|
|
96
|
+
y: number;
|
|
97
|
+
z: number;
|
|
98
|
+
}>;
|
|
99
|
+
}
|
|
100
|
+
/** Result of a single liveness check */
|
|
101
|
+
export interface LivenessCheckResult {
|
|
102
|
+
id: LivenessCheckId;
|
|
103
|
+
passed: boolean;
|
|
104
|
+
score?: number;
|
|
105
|
+
reason?: string;
|
|
106
|
+
}
|
|
107
|
+
/** Overall liveness result */
|
|
108
|
+
export interface LivenessResult {
|
|
109
|
+
/** Overall outcome across all checks. */
|
|
110
|
+
passed: boolean;
|
|
111
|
+
/** Optional aggregate score. */
|
|
112
|
+
score?: number;
|
|
113
|
+
/** Per-check details. */
|
|
114
|
+
checks?: LivenessCheckResult[];
|
|
115
|
+
}
|
|
116
|
+
/** Face matching result comparing reference and live embeddings */
|
|
117
|
+
export interface FaceMatchResult {
|
|
118
|
+
/** Raw L2-squared distance between reference and live embeddings. */
|
|
119
|
+
distance: number;
|
|
120
|
+
/** Derived match percentage (0–100, higher = better match). */
|
|
121
|
+
matchPercentage: number;
|
|
122
|
+
}
|
|
123
|
+
/** Zero-knowledge proof summary */
|
|
124
|
+
export interface ZkProofSummary {
|
|
125
|
+
/** Full proof string as returned by the ZK engine. */
|
|
126
|
+
proof: string;
|
|
127
|
+
/** Public inputs passed to the verifier. */
|
|
128
|
+
publicInputs: string[];
|
|
129
|
+
/** Hash of the proof, suitable for commitments or indexing. */
|
|
130
|
+
hash: string;
|
|
131
|
+
/** Result of local verification. */
|
|
132
|
+
verified: boolean;
|
|
133
|
+
/** Optional metadata. */
|
|
134
|
+
timestamp?: number;
|
|
135
|
+
sizeBytes?: number;
|
|
136
|
+
}
|
|
137
|
+
/** SDK error codes */
|
|
138
|
+
export type SdkErrorCode = "NO_FACE" | "MULTIPLE_FACES" | "LOW_MATCH" | "SYSTEM_ERROR" | "ZK_ERROR" | "NO_REFERENCE" | "LIVENESS_FAILED" | "CANCELLED";
|
|
139
|
+
/** Structured error information */
|
|
140
|
+
export interface SdkError {
|
|
141
|
+
code: SdkErrorCode;
|
|
142
|
+
message: string;
|
|
143
|
+
/**
|
|
144
|
+
* Rich structured details for debugging:
|
|
145
|
+
* - internal stage name (e.g., "embedding", "match", "zk_proof")
|
|
146
|
+
* - raw distances/scores
|
|
147
|
+
* - underlying exception message (sanitized)
|
|
148
|
+
*/
|
|
149
|
+
details?: Record<string, unknown>;
|
|
150
|
+
}
|
|
151
|
+
/** Type guard to check if an unknown value is an SdkError */
|
|
152
|
+
export declare function isSdkError(error: unknown): error is SdkError;
|
|
153
|
+
/** Complete verification outcome */
|
|
154
|
+
export interface VerificationOutcome {
|
|
155
|
+
/** Overall result: true only if all enabled checks (match, liveness, ZK if required) pass. */
|
|
156
|
+
success: boolean;
|
|
157
|
+
/**
|
|
158
|
+
* Primary score for UX surfaces.
|
|
159
|
+
* Contract: matchPercentage in the range 0–100 (higher is better).
|
|
160
|
+
*/
|
|
161
|
+
score: number;
|
|
162
|
+
/** Detailed face match metrics. */
|
|
163
|
+
match?: FaceMatchResult;
|
|
164
|
+
/** Liveness/anti-spoof result (if enabled). */
|
|
165
|
+
liveness?: LivenessResult;
|
|
166
|
+
/** Reference and live capture details (embeddings + pose, no reference image bytes). */
|
|
167
|
+
reference?: Pick<ReferenceTemplate, "referenceId" | "embedding" | "pose" | "metadata">;
|
|
168
|
+
live?: LiveCaptureResult;
|
|
169
|
+
/** Optional ZK proof summary (when proof is generated). */
|
|
170
|
+
zkProof?: ZkProofSummary;
|
|
171
|
+
/** Present when the flow ends in a failure state or partial success. */
|
|
172
|
+
error?: SdkError;
|
|
173
|
+
}
|
|
174
|
+
/** Liveness configuration */
|
|
175
|
+
export interface LivenessConfig {
|
|
176
|
+
/** Enable or disable liveness/anti-spoof checks in this flow. */
|
|
177
|
+
enabled: boolean;
|
|
178
|
+
}
|
|
179
|
+
/** Zero-knowledge proof engine interface */
|
|
180
|
+
export interface ZkProofEngine {
|
|
181
|
+
generateProof(referenceEmbedding: FloatVector, liveEmbedding: FloatVector, nonce: number): Promise<{
|
|
182
|
+
proof: string;
|
|
183
|
+
publicInputs: string[];
|
|
184
|
+
}>;
|
|
185
|
+
verifyProof(proof: string, publicInputs: string[]): Promise<boolean>;
|
|
186
|
+
getProofHash(proof: string): Promise<string>;
|
|
187
|
+
}
|
|
188
|
+
/** ZK configuration */
|
|
189
|
+
export interface ZkConfig {
|
|
190
|
+
/** Whether ZK is allowed in this environment (SDK-level capability). */
|
|
191
|
+
enabled: boolean;
|
|
192
|
+
/**
|
|
193
|
+
* If true, verification is only considered a full SUCCESS when a ZK proof
|
|
194
|
+
* is successfully generated and verified.
|
|
195
|
+
*/
|
|
196
|
+
requiredForSuccess?: boolean;
|
|
197
|
+
/** Concrete engine implementation (e.g., RN WebView/Plonky3 bridge). */
|
|
198
|
+
engine: ZkProofEngine;
|
|
199
|
+
}
|
|
200
|
+
/** Reference storage record */
|
|
201
|
+
export interface ReferenceStorageRecord {
|
|
202
|
+
template: ReferenceTemplate;
|
|
203
|
+
}
|
|
204
|
+
/** Proof storage record */
|
|
205
|
+
export interface ProofStorageRecord {
|
|
206
|
+
referenceId: ReferenceId;
|
|
207
|
+
liveEmbeddingHash?: string;
|
|
208
|
+
zkProof: ZkProofSummary;
|
|
209
|
+
}
|
|
210
|
+
/** Storage adapter interface for persisting references and proofs */
|
|
211
|
+
export interface StorageAdapter {
|
|
212
|
+
saveReference(template: ReferenceTemplate): Promise<ReferenceId>;
|
|
213
|
+
loadReference(referenceId: ReferenceId): Promise<ReferenceTemplate | null>;
|
|
214
|
+
deleteReference(referenceId: ReferenceId): Promise<void>;
|
|
215
|
+
saveProof?(record: ProofStorageRecord): Promise<string>;
|
|
216
|
+
loadProof?(proofId: string): Promise<ProofStorageRecord | null>;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Logging/telemetry remains local; callers decide what to do with it.
|
|
220
|
+
*/
|
|
221
|
+
export interface SdkLogger {
|
|
222
|
+
onLog?(event: {
|
|
223
|
+
level: "debug" | "info" | "warn" | "error";
|
|
224
|
+
message: string;
|
|
225
|
+
context?: Record<string, any>;
|
|
226
|
+
}): void;
|
|
227
|
+
}
|
|
228
|
+
/** Global runtime configuration — controls liveness, ZK, storage, and logging for all SDK operations. */
|
|
229
|
+
export interface FaceZkRuntimeConfig extends SdkLogger {
|
|
230
|
+
liveness?: LivenessConfig;
|
|
231
|
+
zk?: ZkConfig;
|
|
232
|
+
storage?: StorageAdapter;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Per-call override; shallow-partial of FaceZkRuntimeConfig.
|
|
236
|
+
*/
|
|
237
|
+
export interface VerificationOptions {
|
|
238
|
+
liveness?: Partial<LivenessConfig>;
|
|
239
|
+
zk?: Partial<Pick<ZkConfig, "requiredForSuccess">>;
|
|
240
|
+
/**
|
|
241
|
+
* Optional: include additional image data in LiveCaptureResult.
|
|
242
|
+
* Only computed when explicitly requested (base64 is expensive).
|
|
243
|
+
*/
|
|
244
|
+
includeImageData?: {
|
|
245
|
+
base64?: boolean;
|
|
246
|
+
sizeKb?: boolean;
|
|
247
|
+
/** Optional image quality score (0–1, higher = better). */
|
|
248
|
+
qualityScore?: number;
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/** Options for enrollment (reference creation) */
|
|
252
|
+
export interface EnrollmentOptions {
|
|
253
|
+
/** Optional metadata for the reference template (e.g., userId, tag). */
|
|
254
|
+
metadata?: Record<string, unknown>;
|
|
255
|
+
/** If true, SDK will save via storage adapter and return the persisted template. */
|
|
256
|
+
persist?: boolean;
|
|
257
|
+
}
|
|
258
|
+
/** Options for ZK-only proof generation */
|
|
259
|
+
export interface ZkProofOptions {
|
|
260
|
+
nonce?: number;
|
|
261
|
+
}
|
|
262
|
+
/** Verification flow stages for UI state management */
|
|
263
|
+
export type VerificationStage = "IDLE" | "REFERENCE_LOADING" | "LIVENESS" | "CAPTURING" | "EMBEDDING" | "MATCHING" | "ZK_PROOF" | "DONE";
|
|
264
|
+
/**
|
|
265
|
+
* Color theme for SDK UI components.
|
|
266
|
+
* All colors are CSS/React Native color strings (hex, rgb, rgba, named).
|
|
267
|
+
*/
|
|
268
|
+
export interface FaceZkTheme {
|
|
269
|
+
colors: {
|
|
270
|
+
/** Primary accent color — buttons, spinners, success icons. Default: #4CAF50 */
|
|
271
|
+
primary: string;
|
|
272
|
+
/** Screen / modal background. Default: #000000 */
|
|
273
|
+
background: string;
|
|
274
|
+
/** Overlay and surface background (e.g., cancel button). Default: rgba(255,255,255,0.1) */
|
|
275
|
+
surface: string;
|
|
276
|
+
/** Primary text color. Default: #ffffff */
|
|
277
|
+
text: string;
|
|
278
|
+
/** Secondary / muted text color. Default: #aaaaaa */
|
|
279
|
+
textMuted: string;
|
|
280
|
+
/** Error state color — error icons, error titles. Default: #F44336 */
|
|
281
|
+
error: string;
|
|
282
|
+
};
|
|
283
|
+
/** Border radius for buttons and cards. Default: 8 */
|
|
284
|
+
borderRadius?: number;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Copy overrides for all user-facing strings in SDK flows.
|
|
288
|
+
* Any string left undefined falls back to the SDK default.
|
|
289
|
+
*/
|
|
290
|
+
export interface FaceZkStrings {
|
|
291
|
+
loadingInitializing?: string;
|
|
292
|
+
loadingModels?: string;
|
|
293
|
+
loadingCapturing?: string;
|
|
294
|
+
loadingProcessing?: string;
|
|
295
|
+
loadingEmbedding?: string;
|
|
296
|
+
loadingMatching?: string;
|
|
297
|
+
loadingZkProof?: string;
|
|
298
|
+
verificationSuccessTitle?: string;
|
|
299
|
+
verificationSuccessSubtitle?: string;
|
|
300
|
+
enrollmentSuccessTitle?: string;
|
|
301
|
+
enrollmentSuccessSubtitle?: string;
|
|
302
|
+
verificationErrorTitle?: string;
|
|
303
|
+
enrollmentErrorTitle?: string;
|
|
304
|
+
cancelButton?: string;
|
|
305
|
+
retryButton?: string;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* UI configuration for customizing SDK React Native flow components.
|
|
309
|
+
*
|
|
310
|
+
* Three layers of customization:
|
|
311
|
+
*
|
|
312
|
+
* 1. `theme` — change colors and border radius (brand colors, dark/light mode)
|
|
313
|
+
* 2. `strings` — override any piece of copy (localization, custom messaging)
|
|
314
|
+
* 3. render props — completely replace a state's UI with your own React component
|
|
315
|
+
*
|
|
316
|
+
* @example — brand colors only
|
|
317
|
+
* ```tsx
|
|
318
|
+
* <FaceZkVerificationFlow
|
|
319
|
+
* uiConfig={{
|
|
320
|
+
* theme: { colors: { primary: '#6200EE', background: '#1a1a2e' } },
|
|
321
|
+
* }}
|
|
322
|
+
* />
|
|
323
|
+
* ```
|
|
324
|
+
*
|
|
325
|
+
* @example — copy overrides (localization)
|
|
326
|
+
* ```tsx
|
|
327
|
+
* <FaceZkVerificationFlow
|
|
328
|
+
* uiConfig={{
|
|
329
|
+
* strings: {
|
|
330
|
+
* loadingModels: 'Cargando modelos...',
|
|
331
|
+
* verificationSuccessTitle: '¡Verificado!',
|
|
332
|
+
* cancelButton: 'Cancelar',
|
|
333
|
+
* },
|
|
334
|
+
* }}
|
|
335
|
+
* />
|
|
336
|
+
* ```
|
|
337
|
+
*
|
|
338
|
+
* @example — fully custom success screen
|
|
339
|
+
* ```tsx
|
|
340
|
+
* <FaceZkVerificationFlow
|
|
341
|
+
* uiConfig={{
|
|
342
|
+
* renderSuccess: (outcome) => (
|
|
343
|
+
* <MyBrandedSuccessScreen score={outcome.score} zkHash={outcome.zkProof?.hash} />
|
|
344
|
+
* ),
|
|
345
|
+
* }}
|
|
346
|
+
* />
|
|
347
|
+
* ```
|
|
348
|
+
*/
|
|
349
|
+
export interface UiConfig {
|
|
350
|
+
/** Brand color overrides. Only specify what you want to change. */
|
|
351
|
+
theme?: Partial<FaceZkTheme> & {
|
|
352
|
+
colors?: Partial<FaceZkTheme["colors"]>;
|
|
353
|
+
};
|
|
354
|
+
/** Copy/string overrides. Only specify what you want to change. */
|
|
355
|
+
strings?: Partial<FaceZkStrings>;
|
|
356
|
+
/**
|
|
357
|
+
* Fully replace the loading / processing state UI.
|
|
358
|
+
* Receives the current stage label and resolved message string.
|
|
359
|
+
*/
|
|
360
|
+
renderLoading?: (stage: VerificationStage | string, message: string) => React.ReactNode;
|
|
361
|
+
/**
|
|
362
|
+
* Fully replace the verification success state UI.
|
|
363
|
+
* Receives the completed VerificationOutcome.
|
|
364
|
+
*/
|
|
365
|
+
renderSuccess?: (outcome: VerificationOutcome) => React.ReactNode;
|
|
366
|
+
/**
|
|
367
|
+
* Fully replace the error state UI.
|
|
368
|
+
* Receives the SdkError and retry/cancel callbacks.
|
|
369
|
+
*/
|
|
370
|
+
renderError?: (error: SdkError, actions: {
|
|
371
|
+
onRetry: () => void;
|
|
372
|
+
onCancel: () => void;
|
|
373
|
+
}) => React.ReactNode;
|
|
374
|
+
/**
|
|
375
|
+
* Custom overlay rendered on top of the camera/liveness view.
|
|
376
|
+
* Receives live WebView state (pose, instructions, etc).
|
|
377
|
+
*/
|
|
378
|
+
renderOverlay?: (state: any) => React.ReactNode;
|
|
379
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright 2026 JupiterMeta Labs
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.isSdkError = isSdkError;
|
|
19
|
+
const SDK_ERROR_CODES = new Set([
|
|
20
|
+
"NO_FACE",
|
|
21
|
+
"MULTIPLE_FACES",
|
|
22
|
+
"LOW_MATCH",
|
|
23
|
+
"SYSTEM_ERROR",
|
|
24
|
+
"ZK_ERROR",
|
|
25
|
+
"NO_REFERENCE",
|
|
26
|
+
"LIVENESS_FAILED",
|
|
27
|
+
"CANCELLED",
|
|
28
|
+
]);
|
|
29
|
+
/** Type guard to check if an unknown value is an SdkError */
|
|
30
|
+
function isSdkError(error) {
|
|
31
|
+
return (typeof error === "object" &&
|
|
32
|
+
error !== null &&
|
|
33
|
+
"code" in error &&
|
|
34
|
+
"message" in error &&
|
|
35
|
+
typeof error.message === "string" &&
|
|
36
|
+
SDK_ERROR_CODES.has(error.code));
|
|
37
|
+
}
|