diff --git a/CHANGELOG.md b/CHANGELOG.md index 945210c..2f712c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,28 @@ y el versionado sigue [Versionado Semántico](https://semver.org/lang/es/): --- +## [1.5.0] — 2026-06-03 + +### Cambiado + +- Mejoras de legibilidad del rastro de procedencia, para interpretar los datos + de un vistazo: + - Veredicto arriba del rastro: "Camino limpio" (en verde) si nada de lo + explorado toca entidades marcadas, o "Atención" (en ámbar) indicando qué + toca y a cuántos saltos. Responde de un vistazo si hay algo que revisar. + - Jerarquía visual: los eslabones con buena privacidad y sin marcas se + muestran discretos; los que merecen atención (marca o banda no alta) se + destacan con color. El ojo va directo a lo relevante. + - Barra visual de cantidad en cada eslabón, para captar la proporción sin + leer la cifra; el número queda al lado como apoyo. + - Indicador de estructura (entradas → salidas) siempre visible junto a cada + eslabón, útil para detectar consolidaciones grandes de un vistazo. + - Detalle ampliado al pasar el ratón (o tocar en móvil) sobre el indicador + de estructura: número exacto de entradas y salidas, valor en sat y BTC, + bloque, comisión y tasa. Mantiene la vista limpia y el detalle a mano. + +--- + ## [1.4.0] — 2026-06-02 ### Añadido diff --git a/dashboard.html b/dashboard.html index a27e311..5790d38 100644 --- a/dashboard.html +++ b/dashboard.html @@ -2420,6 +2420,24 @@ const {marcas, esCoinbase} = useMemo(()=>marcasDeTx(txData,ana),[txData,ana]); const mempoolUrl = base ? `${base}/tx/${txData.txid}` : `https://mempool.space/tx/${txData.txid}`; const inputs = txData.vin || []; + const [hover,setHover]=useState(false); + + // Detalle para el tooltip: lo que un noderunner querría ver de un eslabón + const detalle = useMemo(()=>{ + const nIn = (txData.vin||[]).length; + const nOut = (txData.vout||[]).length; + const totalOut = (txData.vout||[]).reduce((s,o)=>s+(o.value||0),0); + const totalIn = (txData.vin||[]).reduce((s,v)=>s+(v.prevout?.value||0),0); + const fee = txData.fee || (totalIn>totalOut ? totalIn-totalOut : null); + const vsize = txData.weight ? Math.ceil(txData.weight/4) : null; + const feeRate = (fee && vsize) ? (fee/vsize) : (txData.feerate ? Number(txData.feerate) : null); + return { + nIn, nOut, + btc: (fluyo/1e8).toFixed(8), + bloque: txData.status?.confirmed ? txData.status.block_height : null, + fee, feeRate, + }; + },[txData,fluyo]); const seguirInput = async (i) => { const vin=inputs[i]; @@ -2433,28 +2451,79 @@ }catch(e){ setHijos(s=>({...s,[i]:{err:e.message}})); } }; + // ¿Este eslabón merece atención? (tiene marca, o banda no es ALTA) + // Lo relevante se destaca; lo limpio se silencia. + const relevante = marcas.length>0 || (ana?.band && ana.band!=="ALTA"); + const acento = marcas.length>0 ? marcas[0].color : bandColorRastro(ana?.band); + // Barra visual de cantidad: proporción respecto al flujo de entrada (vout origen). + // Da una idea de tamaño sin leer la cifra. Si no hay referencia, escala suave. + const pctBarra = (() => { + const ref = fluyo || 1; + const outTotal = (txData.vout||[]).reduce((s,o)=>s+(o.value||0),0) || ref; + const p = Math.min(100, Math.round((fluyo/outTotal)*100)); + return isFinite(p) && p>0 ? p : 5; + })(); + return ( -