diff --git a/FIXTURES.md b/FIXTURES.md index 8d5a467..949f44a 100644 --- a/FIXTURES.md +++ b/FIXTURES.md @@ -35,7 +35,7 @@ nodo y corrige la fila). | # | Tipo | address | Resultado esperado | Verificado | |---|------|---------|--------------------|------------| -| A | Máxima reutilización (Satoshi genesis) | `1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa` | Reutilización crítica, banda BAJA extrema | ☐ | +| A | Máxima reutilización (Satoshi genesis) | `1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa` | Reutilización crítica (−40), legacy (−20), banda BAJA. Análisis se muestra en Lab | ✅ 2026-06-03 | --- @@ -143,3 +143,14 @@ Nota de proceso: en una iteración, el cambio se quedó en el archivo de trabajo pero no se copió bien al repo, y se presentó una versión sin el cambio. Lección: verificar con grep que el archivo presentado contiene el cambio antes de desplegar. + +### 2026-06-03 — Fixture #A (dirección de Satoshi, reutilización extrema) +El motor clasificó bien la reutilización extrema (62.994 usos → reutilización +−40, legacy −20, banda BAJA). Pero se encontraron dos fallos de cara al usuario: +1. El botón "Analizar privacidad" del resultado de una dirección mandaba la + dirección a la pestaña Auditoría, que solo acepta txids → callejón sin salida + con error "introduce un txid válido". Corregido: el análisis de privacidad de + la dirección (que ya se calculaba) ahora se muestra ahí mismo en Lab, con sus + checks, reutilizando el componente PrivacyLab. +2. El texto de la banda decía "Esta transacción..." aun analizando una dirección. + Corregido: el texto se adapta (transacción / dirección) según lo analizado. diff --git a/dashboard.html b/dashboard.html index eb6d12d..0f78aa9 100644 --- a/dashboard.html +++ b/dashboard.html @@ -1544,7 +1544,7 @@ const funded = addr.chain_stats ? addr.chain_stats.funded_txo_sum : 0; checks.push({ id:"volume", label:"Volumen de actividad", certainty:"CERTEZA", pass:true, detail:`Total recibido: ${(funded/1e8).toFixed(4)} BTC en ${txCount} transacciones.`, penalty:0, informational:true }); score = Math.max(0, Math.min(100, score)); - return { score, checks, summary: score >= 70 ? "Privacidad aceptable" : score >= 40 ? "Privacidad mejorable" : "Privacidad baja", summaryColor: score >= 70 ? C.green : score >= 40 ? C.amber : C.red }; + return { score, checks, band: score>=75?"ALTA":score>=45?"MEDIA":"BAJA", summary: score >= 75 ? "Privacidad aceptable" : score >= 45 ? "Privacidad mejorable" : "Privacidad baja", summaryColor: score >= 75 ? C.green : score >= 45 ? C.amber : C.red, wallets: [] }; } // ── fetch con timeout — protege el nodo y evita el spinner infinito ── @@ -1811,7 +1811,9 @@
NIVEL DE PRIVACIDAD
{summary}
- {score>=75?"La transacción presenta buenas propiedades de privacidad.":score>=45?"La transacción es funcional, pero tiene características que reducen su privacidad.":"Esta transacción tiene características que facilitan su rastreo."} + {tx + ? (score>=75?"La transacción presenta buenas propiedades de privacidad.":score>=45?"La transacción es funcional, pero tiene características que reducen su privacidad.":"Esta transacción tiene características que facilitan su rastreo.") + : (score>=75?"La dirección presenta buenas propiedades de privacidad.":score>=45?"La dirección es funcional, pero tiene características que reducen su privacidad.":"Esta dirección tiene características que facilitan su rastreo.")}
{wallets&&wallets.length>0&&(
@@ -2647,7 +2649,7 @@ {err&&
Error: {err}
} {loading&&} {result&&result.type==="tx"&&{window.__setTab&&window.__setTab("auditoria",q);}}/>} - {result&&result.type==="address"&&{window.__setTab&&window.__setTab("auditoria",q);}}/>} + {result&&result.type==="address"&&} {result&&result.type==="block"&&}
@@ -3458,7 +3460,7 @@ ); } - function AddressResult({addr, onAnalyze}) { + function AddressResult({addr, analysis}) { const c=addr.chain_stats||{funded_txo_sum:0,spent_txo_sum:0,tx_count:0}; const m=addr.mempool_stats||{funded_txo_sum:0,spent_txo_sum:0}; const balance=c.funded_txo_sum-c.spent_txo_sum; @@ -3475,12 +3477,8 @@ - {onAnalyze&&
- -
} + {analysis&&} {addr.utxos&&addr.utxos.length>0&&
UTXOs
{addr.utxos.slice(0,6).map((u,i)=>
{fmt.hash(u.txid)}:{u.vout}
{fmt.btc(u.value)}{u.status&&u.status.confirmed?`#${fmt.num(u.status.block_height)}`:"mempool"}
)}
} {addr.txs&&addr.txs.length>0&&
Transacciones Recientes
{addr.txs.slice(0,8).map((tx,i)=>{const out=tx.vout?tx.vout.reduce((s,v)=>s+v.value,0):0;return
{fmt.hash(tx.txid)}
{tx.status&&tx.status.block_time?fmt.date(tx.status.block_time):"pendiente"}
{tx.status&&tx.status.confirmed?"conf":"pend"}{fmt.btc(out)}
;})}
}