const { B32, SECP, deriveChildPubkey, deriveAddresses } = require('/tmp/cripto/crypto.js'); let ok=0, ko=0; const debeFallar = async (nombre, fn) => { try { await fn(); console.log(` ✗ ${nombre} — NO falló`); ko++; } catch(e){ console.log(` ✓ ${nombre}\n → "${e.message}"`); ok++; } }; (async () => { const bueno = "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"; console.log("=== los cuatro hallazgos, revisados ===\n"); await debeFallar("checksum rota (un carácter cambiado)", () => deriveAddresses(bueno.slice(0,-1) + (bueno.slice(-1)==="8"?"9":"8"), 2)); await debeFallar("xpub truncado", () => deriveAddresses("xpub661MyMwAqRbcFtXgS5sYJ", 2)); await debeFallar("índice endurecido", async () => { const raw = await B32.decodeBase58Check(bueno); return deriveChildPubkey(raw.slice(45,78), raw.slice(13,45), 0x80000000); }); await debeFallar("índice negativo", async () => { const raw = await B32.decodeBase58Check(bueno); return deriveChildPubkey(raw.slice(45,78), raw.slice(13,45), -1); }); console.log("\n=== el xpub bueno sigue funcionando ==="); const a = await deriveAddresses(bueno, 3); console.log(" recepción:", a.receive.join(", ")); console.log(" huella:", a.fingerprint); const bien = a.receive.every(x=>x.startsWith("bc1q")&&x.length===42); console.log(` ${bien?'✓':'✗'} formato correcto`); bien?ok++:ko++; console.log("\n=== testnet: tpub ahora se detecta bien ==="); // vector 1 del BIP32 con los bytes de versión de testnet — dato público, no de nadie const tp = "tpubD6NzVbkrYhZ4XgiXtGrdW5XDAPFCL9h7we1vwNCpn8tGbBcgfVYjXyhWo4E1xkh56hjod1RhGjxbaTLV3X4FyWuejifB9jusQ46QzG87VKp"; try { const t = await deriveAddresses(tp, 2); const esTb = t.receive.every(x=>x.startsWith("tb1q")); console.log(` ${esTb?'✓':'✗'} genera direcciones de testnet: ${t.receive[0]}`); esTb?ok++:ko++; } catch(e){ console.log(" ✗ falló:", e.message); ko++; } console.log(`\nRESULTADO: ${ok} correctas, ${ko} incorrectas`); })();