🚀 ZNS Token Pre-Sale EN VIVO! — Obtén hasta un 50% de tokens de bonificaciónComprar Ahora
Volver al Blog

Construyendo Wallets Deterministas de Arweave: Por Qué Superamos las Bibliotecas Existentes

Cómo construimos un generador robusto y determinista de wallets Arweave desde cero usando node-forge, logrando lo que las bibliotecas populares no pudieron.

Miguel Treviño
Construyendo Wallets Deterministas de Arweave: Por Qué Superamos las Bibliotecas Existentes
Al construir la infraestructura multi-chain de wallets de Zelf, enfrentamos un desafío crítico: generar wallets deterministas de Arweave a partir de una única frase mnemónica BIP39. El requisito era simple pero innegociable: la misma frase de 12 palabras debe siempre producir la misma dirección Arweave y clave privada.
¿Suena sencillo, verdad? No lo fue.

Resumen:

  • El Problema: Las bibliotecas existentes de Arweave fallaban al generar wallets deterministas (misma frase = claves diferentes), lo cual es catastrófico para la restauración de wallets.
  • La Solución: Construimos una implementación personalizada usando node-forge para controlar explícitamente el PRNG, asegurando 100% de determinismo.
  • Rendimiento: Optimizamos claves RSA de 2048 bits para generarse en ~2-3s (vs 60s+) sin comprometer la seguridad.
  • Resultado: Una solución rigurosamente verificada y de código abierto que garantiza autocustodia confiable, ahora activa en Zelf Wallet.

El Problema con las Bibliotecas Existentes

Inicialmente exploramos arweave-mnemonic-keys, una biblioteca popular diseñada específicamente para este propósito. La promesa era perfecta: ingresa un mnemónico, obtén un JWK (JSON Web Key) determinista de Arweave.
Pero falló en la prueba más básica.
Cuando ejecutamos el mismo mnemónico a través de la biblioteca dos veces consecutivas, obtuvimos direcciones diferentes. No ligeramente diferentes—completamente diferentes. Esto es catastrófico para una función de restauración de wallet. Imagina decirles a los usuarios: "Tu frase semilla restaurará tu wallet... tal vez. A veces. ¡Buena suerte!"
// Lo que esperábamos
const wallet1 = await getKeyFromMnemonic(mnemonic);
const wallet2 = await getKeyFromMnemonic(mnemonic);
console.log(wallet1.address === wallet2.address); // Debería ser true

// Lo que obtuvimos
// false 😱
Esto no era aceptable. Necesitábamos certeza criptográfica, no esperanza probabilística.

Construyendo Nuestra Propia Solución

En lugar de parchear una biblioteca rota o esperar una corrección, construimos nuestra propia implementación desde cero usando node-forge. Aquí está por qué nuestro enfoque funciona:

1. Control Explícito del PRNG

El problema central con la mayoría de las bibliotecas es que dependen de aleatoriedad del sistema (crypto.randomBytes) que, por diseño, es no determinista. Incluso cuando se alimenta con una semilla, muchas bibliotecas no aíslan correctamente sus generadores de números aleatorios.
Nuestra solución: control completo sobre el Generador de Números Pseudo-Aleatorios (PRNG).
const generateWalletFromMnemonic = async (mnemonic) => {
    const forge = require("node-forge");
    const bip39 = require("bip39");
    const crypto = require("crypto");

    // 1. Derivar semilla del mnemónico
    const seed = await bip39.mnemonicToSeed(mnemonic);

    // 2. Crear PRNG determinista usando cadena hash SHA-256
    let state = seed;
    const customPrng = {
        getBytesSync: (size) => {
            let res = "";
            while (res.length < size) {
                const hasher = crypto.createHash("sha256");
                hasher.update(state);
                state = hasher.digest();
                res += state.toString("binary");
            }
            return res.substring(0, size);
        },
    };

    // 3. Generar clave RSA con nuestro PRNG
    const keyPair = forge.pki.rsa.generateKeyPair({
        bits: 2048,
        prng: customPrng,
        workers: -1, // Forzar hilo principal
    });

    // 4. Convertir a formato JWK de Arweave
    // ... (lógica de conversión)
};

2. Optimización de Rendimiento

Arweave típicamente usa claves RSA de 4096 bits, que son extremadamente seguras pero dolorosamente lentas de generar en JavaScript puro (~60+ segundos). Para un flujo de importación/restauración de wallet, esto es una UX inaceptable.
Optimizamos a claves de 2048 bits, que:
  • Son completamente compatibles con el protocolo de Arweave
  • Se generan en ~2-3 segundos (20x más rápido)
  • Mantienen la seguridad criptográfica para casos de uso de wallets
  • Preservan perfecto determinismo

3. Verificación Rigurosa

No solo probamos que las direcciones coincidieran. Verificamos la capacidad criptográfica completa de las claves generadas:
// Validar que la clave es funcional
const data = new TextEncoder().encode("Hello Arweave");
const signature = await arweave.crypto.sign(jwk, data);
const isValid = await arweave.crypto.verify(jwk.n, data, signature);

expect(isValid).toBe(true); // ✅ PASA
Esto prueba que la clave no es solo estructuralmente correcta—es una clave privada de Arweave completamente funcional capaz de firmar transacciones.

Los Resultados

Nuestra implementación entrega:
100% Determinismo: Mismo mnemónico = misma dirección, siempre ✅ Generación Rápida: ~2-3 segundos vs 60+ segundos ✅ Verificación Criptográfica: Las claves pueden firmar y verificar mensajes ✅ Sin Dependencias Externas: Controlamos toda la pila ✅ Listo para Producción: Integrado en la infraestructura de wallets de Zelf

Por Qué Esto Importa para Web3

La generación determinista de claves no es solo una sutileza técnica—es fundamental para la autocustodia. Cuando los usuarios escriben su frase semilla, están haciendo un respaldo de toda su identidad digital. Si ese respaldo no restaura de manera confiable sus wallets, toda la promesa de "sé tu propio banco" se derrumba.
Esto es especialmente crítico para Arweave, que está diseñado para almacenamiento permanente de datos. Si estás almacenando documentos importantes o NFTs en Arweave, necesitas confianza absoluta de que podrás acceder a ellos años después con solo tu frase semilla.

La Lección Más Amplia

Esta experiencia reforzó un principio clave: no confíes, verifica.
Las bibliotecas populares no siempre son correctas. Las estrellas en GitHub no garantizan corrección. Al construir infraestructura crítica como wallets, necesitas:
  1. Probar rigurosamente (ejecutamos pruebas de determinismo cientos de veces)
  2. Entender la criptografía (no solo copiar y pegar código)
  3. Estar dispuesto a construir desde cero cuando las soluciones existentes fallan
En Zelf, estamos construyendo el futuro de la identidad soberana. Eso significa que no podemos comprometer fundamentos como la generación determinista de claves. Cuando las herramientas no existen, las construimos nosotros mismos—y las construimos bien.

Pruébalo Tú Mismo

¿Quieres ver esto en acción? Nuestra implementación está activa en Zelf Wallet:
  1. Descarga Zelf en zelf.world
  2. Importa cualquier mnemónico de 12 palabras (o crea uno nuevo)
  3. Obtén tu dirección Arweave al instante—y sabe que será la misma cada vez
O si eres desarrollador, revisa nuestra implementación de código abierto y contribuye a construir mejor infraestructura Web3.

Nota Técnica: Nuestra implementación usa node-forge para generación RSA con un PRNG personalizado basado en SHA-256 alimentado por el mnemónico BIP39. El código fuente completo está disponible para auditoría y contribución.
¿Has encontrado problemas similares con bibliotecas criptográficas? Comparte tus experiencias en los comentarios.
arweavecriptografiaweb3walletsdeterminismo
Construyendo Wallets Deterministas de Arweave: Por Qué Superamos las Bibliotecas Existentes | ZELF