soulprint-verify 0.1.2 → 0.1.4

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.
@@ -4,6 +4,7 @@ exports.matchFaceWithDocument = matchFaceWithDocument;
4
4
  const node_child_process_1 = require("node:child_process");
5
5
  const node_path_1 = require("node:path");
6
6
  const node_fs_1 = require("node:fs");
7
+ const soulprint_core_1 = require("soulprint-core");
7
8
  // Path al script Python que corre on-demand
8
9
  const PYTHON_SCRIPT = (0, node_path_1.join)(__dirname, "face_match.py");
9
10
  /**
@@ -19,7 +20,7 @@ const PYTHON_SCRIPT = (0, node_path_1.join)(__dirname, "face_match.py");
19
20
  * @param documentPhoto Path a la foto del documento (cédula)
20
21
  */
21
22
  async function matchFaceWithDocument(selfiePhoto, documentPhoto, opts = {}) {
22
- const minSim = opts.minSimilarity ?? 0.65;
23
+ const minSim = opts.minSimilarity ?? soulprint_core_1.PROTOCOL.FACE_SIM_DOC_SELFIE;
23
24
  // Verificar que existe el script Python
24
25
  if (!(0, node_fs_1.existsSync)(PYTHON_SCRIPT)) {
25
26
  return {
@@ -28,6 +28,17 @@ def eprint(*args):
28
28
  print(*args, file=sys.stderr)
29
29
 
30
30
 
31
+ # ── Protocol Constants (espejo de PROTOCOL en soulprint-core) ─────────────────
32
+ # IMPORTANTE: estos valores deben mantenerse sincronizados con
33
+ # packages/core/src/protocol-constants.ts → PROTOCOL
34
+ # Son INMUTABLES a nivel de protocolo. No modificar sin un nuevo SIP.
35
+
36
+ FACE_SIM_DOC_SELFIE = 0.35 # PROTOCOL.FACE_SIM_DOC_SELFIE
37
+ FACE_SIM_SELFIE_SELFIE = 0.65 # PROTOCOL.FACE_SIM_SELFIE_SELFIE
38
+ FACE_KEY_DIMS = 32 # PROTOCOL.FACE_KEY_DIMS
39
+ FACE_KEY_PRECISION = 1 # PROTOCOL.FACE_KEY_PRECISION
40
+
41
+
31
42
  # ── Pre-procesamiento de imagen ────────────────────────────────────────────────
32
43
 
33
44
  def fix_exif_rotation(img):
@@ -208,7 +219,7 @@ def cosine_similarity(a, b) -> float:
208
219
  return float(np.dot(a, b))
209
220
 
210
221
 
211
- def quantize_embedding(embedding, precision: int = 1):
222
+ def quantize_embedding(embedding, precision: int = FACE_KEY_PRECISION):
212
223
  """
213
224
  Cuantiza el embedding para derivar nullifier determinístico.
214
225
  precision=1 (0.1 steps) absorbe ruido natural de InsightFace (±0.01).
@@ -285,7 +296,7 @@ def main():
285
296
  parser = argparse.ArgumentParser(description="Soulprint face match")
286
297
  parser.add_argument("--selfie", required=True, help="Path selfie del usuario")
287
298
  parser.add_argument("--document", required=True, help="Path foto del documento")
288
- parser.add_argument("--min-sim", type=float, default=0.65, help="Similitud mínima")
299
+ parser.add_argument("--min-sim", type=float, default=FACE_SIM_DOC_SELFIE, help="Similitud mínima (PROTOCOL.FACE_SIM_DOC_SELFIE)")
289
300
  parser.add_argument("--liveness", action="store_true", help="Verificar liveness")
290
301
  args = parser.parse_args()
291
302
 
@@ -351,7 +362,7 @@ def main():
351
362
  )
352
363
 
353
364
  # Embedding cuantizado para derivar nullifier (determinístico entre sesiones)
354
- quantized = quantize_embedding(selfie_emb, precision=1)
365
+ quantized = quantize_embedding(selfie_emb, precision=FACE_KEY_PRECISION)
355
366
 
356
367
  result = {
357
368
  "match": match,
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ async function verifyIdentity(opts) {
48
48
  log(`✓ Cédula: ${docResult.cedula_number}`);
49
49
  // ── PASO 3: Face match (subprocess Python on-demand) ──────────────────────
50
50
  log("Verificando coincidencia facial (iniciando proceso de IA)...");
51
- const faceResult = await (0, face_match_js_1.matchFaceWithDocument)(opts.selfiePhoto, opts.documentPhoto, { minSimilarity: opts.minFaceSim ?? 0.65, checkLiveness: opts.checkLiveness, verbose: opts.verbose });
51
+ const faceResult = await (0, face_match_js_1.matchFaceWithDocument)(opts.selfiePhoto, opts.documentPhoto, { minSimilarity: opts.minFaceSim ?? soulprint_core_1.PROTOCOL.FACE_SIM_DOC_SELFIE, checkLiveness: opts.checkLiveness, verbose: opts.verbose });
52
52
  if (!faceResult.match) {
53
53
  errors.push(...faceResult.errors);
54
54
  steps.face_match = "fail";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "soulprint-verify",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Soulprint local verification — on-demand cedula OCR + InsightFace match, zero persistent memory",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -34,8 +34,8 @@
34
34
  "tesseract.js": "^5.1.0",
35
35
  "sharp": "^0.33.3",
36
36
  "@noble/hashes": "^1.4.0",
37
- "soulprint-core": "0.1.2",
38
- "soulprint-zkp": "0.1.2"
37
+ "soulprint-zkp": "0.1.4",
38
+ "soulprint-core": "0.1.6"
39
39
  },
40
40
  "devDependencies": {
41
41
  "typescript": "^5.4.0",
@@ -28,6 +28,17 @@ def eprint(*args):
28
28
  print(*args, file=sys.stderr)
29
29
 
30
30
 
31
+ # ── Protocol Constants (espejo de PROTOCOL en soulprint-core) ─────────────────
32
+ # IMPORTANTE: estos valores deben mantenerse sincronizados con
33
+ # packages/core/src/protocol-constants.ts → PROTOCOL
34
+ # Son INMUTABLES a nivel de protocolo. No modificar sin un nuevo SIP.
35
+
36
+ FACE_SIM_DOC_SELFIE = 0.35 # PROTOCOL.FACE_SIM_DOC_SELFIE
37
+ FACE_SIM_SELFIE_SELFIE = 0.65 # PROTOCOL.FACE_SIM_SELFIE_SELFIE
38
+ FACE_KEY_DIMS = 32 # PROTOCOL.FACE_KEY_DIMS
39
+ FACE_KEY_PRECISION = 1 # PROTOCOL.FACE_KEY_PRECISION
40
+
41
+
31
42
  # ── Pre-procesamiento de imagen ────────────────────────────────────────────────
32
43
 
33
44
  def fix_exif_rotation(img):
@@ -208,7 +219,7 @@ def cosine_similarity(a, b) -> float:
208
219
  return float(np.dot(a, b))
209
220
 
210
221
 
211
- def quantize_embedding(embedding, precision: int = 1):
222
+ def quantize_embedding(embedding, precision: int = FACE_KEY_PRECISION):
212
223
  """
213
224
  Cuantiza el embedding para derivar nullifier determinístico.
214
225
  precision=1 (0.1 steps) absorbe ruido natural de InsightFace (±0.01).
@@ -285,7 +296,7 @@ def main():
285
296
  parser = argparse.ArgumentParser(description="Soulprint face match")
286
297
  parser.add_argument("--selfie", required=True, help="Path selfie del usuario")
287
298
  parser.add_argument("--document", required=True, help="Path foto del documento")
288
- parser.add_argument("--min-sim", type=float, default=0.65, help="Similitud mínima")
299
+ parser.add_argument("--min-sim", type=float, default=FACE_SIM_DOC_SELFIE, help="Similitud mínima (PROTOCOL.FACE_SIM_DOC_SELFIE)")
289
300
  parser.add_argument("--liveness", action="store_true", help="Verificar liveness")
290
301
  args = parser.parse_args()
291
302
 
@@ -351,7 +362,7 @@ def main():
351
362
  )
352
363
 
353
364
  # Embedding cuantizado para derivar nullifier (determinístico entre sesiones)
354
- quantized = quantize_embedding(selfie_emb, precision=1)
365
+ quantized = quantize_embedding(selfie_emb, precision=FACE_KEY_PRECISION)
355
366
 
356
367
  result = {
357
368
  "match": match,