feat: exportar UTXO Map a CSV (local, sin salir del nodo)

This commit is contained in:
Aitor
2026-06-01 20:58:49 +02:00
parent b3dedc1865
commit 0110e84c49
2 changed files with 61 additions and 0 deletions
+47
View File
@@ -2141,11 +2141,58 @@
const avgPrivacy = privacyScores.length>0
? Math.round(privacyScores.reduce((s,p)=>s+p.score,0)/privacyScores.length) : null;
// ── Exportar UTXOs a CSV ──────────────────────────────────────────
// Genera el archivo en el navegador y lo descarga en local.
// No pasa por ningún servidor, no sale nada del nodo.
const exportUtxosCSV = () => {
if(!utxos || utxos.length===0) return;
// Escapar campos: si llevan coma, comilla o salto, van entre comillas
const esc = (val) => {
const s = String(val ?? "");
return /[",\n]/.test(s) ? '"' + s.replace(/"/g,'""') + '"' : s;
};
const cabeceras = ["txid","vout","valor_sats","valor_btc","confirmado","altura_bloque","privacidad_score","problemas"];
const filas = utxos.map((u,i) => {
const priv = privacyScores[i] || {score:"", issues:[]};
return [
u.txid,
u.vout,
u.value,
(u.value/1e8).toFixed(8),
u.status?.confirmed ? "si" : "no",
u.status?.confirmed ? (u.status.block_height ?? "") : "mempool",
priv.score,
(priv.issues || []).join("; "),
].map(esc).join(",");
});
const csv = [cabeceras.join(","), ...filas].join("\n");
// BOM para que Excel abra los acentos bien + descarga vía Blob
const blob = new Blob(["\uFEFF" + csv], {type:"text/csv;charset=utf-8"});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
const fecha = new Date().toISOString().slice(0,10);
const addrCorto = (addr || "utxos").slice(0,12);
a.href = url;
a.download = `txoko-utxos-${addrCorto}-${fecha}.csv`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
};
return(
<Card>
<div style={{fontSize:"0.62rem",color:C.purple,fontFamily:"monospace",textTransform:"uppercase",letterSpacing:"0.2em",marginBottom:8,display:"flex",alignItems:"center",gap:8}}>
<span></span> UTXO Map
<div style={{flex:1,height:1,background:`linear-gradient(to right,${C.purple}40,transparent)`}}/>
{utxos&&utxos.length>0&&(
<button onClick={exportUtxosCSV} title="Descargar los UTXOs en CSV (local, no sale del nodo)"
style={{padding:"4px 10px",background:C.bg,border:`1px solid ${C.purple}40`,borderRadius:5,color:C.purple,fontFamily:"monospace",fontSize:"0.6rem",letterSpacing:"0.08em",cursor:"pointer",whiteSpace:"nowrap"}}
onMouseEnter={e=>e.currentTarget.style.borderColor=C.purple}
onMouseLeave={e=>e.currentTarget.style.borderColor=C.purple+"40"}>
CSV
</button>
)}
</div>
<div style={{fontSize:"0.65rem",color:C.t2,marginBottom:12,lineHeight:1.5}}>
Analiza los UTXOs de una dirección con score de privacidad por UTXO y contexto de origen. Máx. {MAX_UTXOS} UTXOs.