Integración con carteras

Integra el SDK cliente de Unlukey en una cartera para avisar a los usuarios cuando su frase de recuperación fue generada por una vulnerabilidad conocida de generación débil de semillas.

El SDK está publicado en el repositorio coinspect/unlukey.

Cómo funciona la verificación

  1. La cartera deriva la entropía BIP-39 a partir de la frase de recuperación.
  2. El SDK cliente aplica hash SHA-256 a la entropía y toma un prefijo corto del hash resultante.
  3. Descarga únicamente el bucket del dataset que corresponde a ese prefijo desde un hosting estático.
  4. Compara localmente los bytes restantes del hash con las entradas de ese bucket.

El prefijo agrupa muchas claves posibles en el mismo bucket (k-anonimato). El proveedor de hosting estático solo ve qué bucket fue solicitado, nunca la clave completa que se está verificando ni si hubo coincidencia.

Los datasets están separados por longitud de entropía: uno para entropía de 128 bits (12 palabras) y otro para 256 bits (24 palabras). El cliente selecciona el correcto automáticamente.

Instalación

npm install @unlukey/client

(Hasta que el paquete esté publicado, instálalo directamente desde el repositorio: npm install github:coinspect/unlukey#path:client.)

Uso básico

import { check } from '@unlukey/client'
import { mnemonicToEntropy } from '@scure/bip39'
import { wordlist } from '@scure/bip39/wordlists/english'

const entropy = mnemonicToEntropy(secretRecoveryPhrase, wordlist)

const { vulnerable } = await check(entropy)

if (vulnerable) {
  // Avisa al usuario: esta frase de recuperación coincide con una semilla
  // débil conocida y los fondos deben moverse a una cartera nueva.
}

La lógica de búsqueda se ejecuta en el cliente. La frase de recuperación y la entropía nunca salen del dispositivo; solo se envía un prefijo del hash de la entropía al servidor de datasets. entropy es un Uint8Array y debe tener:

  • 16 bytes, para mnemónicos de 12 palabras, o
  • 32 bytes, para mnemónicos de 24 palabras.

Cómo interpretar el resultado

check() resuelve a { vulnerable, key, prefix, bucketPath, reason? }:

  • vulnerable: true — la entropía coincide con una semilla débil conocida. Pide al usuario que mueva sus fondos a una cartera nueva generada con aleatoriedad segura.

  • vulnerable: false — no se encontró ninguna coincidencia. Esto no prueba que la frase de recuperación sea segura; solo significa que no coincide con ningún candidato en los datasets actuales de Unlukey. La cobertura sigue creciendo; consulta la hoja de ruta.

reason aporta información de diagnóstico para depurar la integración. No cambia el significado de vulnerable.

Cuándo ejecutar la verificación

Ejecuta la verificación cuando un usuario importa una frase de recuperación existente, una vez que la cartera haya derivado la entropía BIP-39.

Hosting personalizado

Por defecto, el cliente descarga los buckets desde el hosting público de datasets de Unlukey. Pasa una URL base distinta a check() para usar otro hosting de datasets, como tu propio CDN:

const result = await check(
  entropy,
  'https://your-cdn.example.com/unlukey-datasets'
)

Para tener control total sobre cómo se descargan los buckets del dataset, usa checkWith(entropy, readBucket) y proporciona tu propia implementación de readBucket(bits, prefixHex). Consulta client/index.js en el repositorio del SDK.

Pruebas locales

La CLI del repositorio del SDK es útil para probar la integración sin implementar interfaz:

node client/cli.js --remote 72039ecb02a3c880d4249e4b206933945a4f3a76ebaab26fa14e47a24e0f907e
# VULNERABLE

Consulta el README del repositorio del SDK para generar un dataset de muestra local y probar el cliente contra él.