**Motivations:** - Corriger erreur syntaxe double déclaration const now dans bitcoin-rpc.js - Scripts batch en .mjs (ES modules) sans dépendance dotenv - /api/utxo/count doit accepter catégorie ancrages (pluriel) du fichier **Root causes:** - const now déclaré deux fois dans même portée (lignes 294 et 299) - Scripts utilisent dotenv non installé globalement - /api/utxo/count cherchait seulement 'anchor' mais fichier utilise 'ancrages' **Correctifs:** - Supprimer deuxième déclaration const now (ligne 299) - Scripts .mjs : parser .env manuellement sans dotenv - /api/utxo/count : accepter 'anchor' OU 'ancrages' **Evolutions:** - Aucune **Pages affectées:** - signet-dashboard/src/bitcoin-rpc.js - signet-dashboard/src/server.js - scripts/complete-utxo-list-blocktime.mjs - scripts/diagnose-bloc-rewards.mjs
135 lines
4.0 KiB
JavaScript
Executable File
135 lines
4.0 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
/**
|
|
* Script batch pour compléter les blockTime manquants dans utxo_list.txt
|
|
* Récupère blockTime depuis RPC pour les UTXOs confirmés sans blockTime
|
|
*/
|
|
|
|
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
import { fileURLToPath } from 'url';
|
|
import { dirname, join } from 'path';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
const utxoListPath = join(__dirname, '../utxo_list.txt');
|
|
|
|
// Charger les variables d'environnement depuis .env si disponible
|
|
let envVars = {};
|
|
try {
|
|
const envPath = join(__dirname, '../signet-dashboard/.env');
|
|
if (existsSync(envPath)) {
|
|
const envContent = readFileSync(envPath, 'utf8');
|
|
for (const line of envContent.split('\n')) {
|
|
const match = line.match(/^([^#=]+)=(.*)$/);
|
|
if (match) {
|
|
envVars[match[1].trim()] = match[2].trim();
|
|
}
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.warn('Could not load .env file, using defaults');
|
|
}
|
|
|
|
const BITCOIN_RPC_URL = envVars.BITCOIN_RPC_URL || process.env.BITCOIN_RPC_URL || 'http://127.0.0.1:38332';
|
|
const BITCOIN_RPC_USER = envVars.BITCOIN_RPC_USER || process.env.BITCOIN_RPC_USER || 'bitcoin';
|
|
const BITCOIN_RPC_PASSWORD = envVars.BITCOIN_RPC_PASSWORD || process.env.BITCOIN_RPC_PASSWORD || 'bitcoin';
|
|
const BITCOIN_RPC_WALLET = envVars.BITCOIN_RPC_WALLET || process.env.BITCOIN_RPC_WALLET || 'custom_signet';
|
|
|
|
if (!existsSync(utxoListPath)) {
|
|
console.error('utxo_list.txt not found');
|
|
process.exit(1);
|
|
}
|
|
|
|
async function getTransactionBlockTime(txid) {
|
|
try {
|
|
const auth = Buffer.from(`${BITCOIN_RPC_USER}:${BITCOIN_RPC_PASSWORD}`).toString('base64');
|
|
const rpcUrl = `${BITCOIN_RPC_URL}/wallet/${BITCOIN_RPC_WALLET}`;
|
|
|
|
const response = await fetch(rpcUrl, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Basic ${auth}`,
|
|
},
|
|
body: JSON.stringify({
|
|
jsonrpc: '1.0',
|
|
id: 'gettx',
|
|
method: 'gettransaction',
|
|
params: [txid],
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
return null;
|
|
}
|
|
|
|
const result = await response.json();
|
|
if (result.error) {
|
|
return null;
|
|
}
|
|
|
|
return result.result.blocktime || null;
|
|
} catch (error) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
try {
|
|
const content = readFileSync(utxoListPath, 'utf8').trim();
|
|
if (!content) {
|
|
console.log('utxo_list.txt is empty');
|
|
process.exit(0);
|
|
}
|
|
|
|
const lines = content.split('\n');
|
|
let updated = 0;
|
|
let processed = 0;
|
|
const total = lines.length;
|
|
|
|
console.log(`📊 Traitement de ${total} lignes...`);
|
|
|
|
const outputLines = await Promise.all(lines.map(async (line) => {
|
|
if (!line.trim()) return line;
|
|
const parts = line.split(';');
|
|
|
|
// Format attendu: category;txid;vout;amount;confirmations;isAnchorChange;blockTime
|
|
if (parts.length >= 6) {
|
|
const confirmations = parseInt(parts[4], 10) || 0;
|
|
const blockTime = parts.length >= 7 ? parts[6] : '';
|
|
|
|
// Si confirmé mais blockTime manquant, récupérer depuis RPC
|
|
if (confirmations > 0 && (!blockTime || blockTime.trim() === '')) {
|
|
const txid = parts[1];
|
|
processed++;
|
|
|
|
if (processed % 10 === 0) {
|
|
console.log(`⏳ Traitement: ${processed}/${total}...`);
|
|
}
|
|
|
|
const txBlockTime = await getTransactionBlockTime(txid);
|
|
if (txBlockTime) {
|
|
updated++;
|
|
// Reconstruire la ligne avec blockTime
|
|
const newParts = [...parts];
|
|
if (newParts.length === 6) {
|
|
newParts.push(txBlockTime.toString());
|
|
} else {
|
|
newParts[6] = txBlockTime.toString();
|
|
}
|
|
return newParts.join(';');
|
|
}
|
|
}
|
|
}
|
|
return line;
|
|
}));
|
|
|
|
if (updated > 0) {
|
|
writeFileSync(utxoListPath, outputLines.join('\n'), 'utf8');
|
|
console.log(`✅ ${updated} ligne(s) mise(s) à jour avec blockTime dans utxo_list.txt`);
|
|
} else {
|
|
console.log('✅ Toutes les lignes ont déjà un blockTime dans utxo_list.txt');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error:', error.message);
|
|
process.exit(1);
|
|
}
|