**Motivations:** - Ajouter dates manquantes dans hash_list.txt et compléter historique - Compléter blockTime manquants dans utxo_list.txt et compléter historique - Récupérer frais depuis transactions d'ancrage (OP_RETURN) et les stocker - Bouton UI pour déclencher récupération frais - Diagnostic Bloc Rewards (pourquoi ~4700 BTC au lieu de 50 BTC) **Root causes:** - hash_list.txt sans date (format ancien) - utxo_list.txt blockTime souvent vide - Frais absents du fichier (métadonnées OP_RETURN non stockées) - Pas de moyen de récupérer/compléter frais depuis UI **Correctifs:** - hash_list.txt : format étendu avec date (rétrocompatible) - utxo_list.txt : blockTime complété automatiquement lors écritures - fees_list.txt : nouveau fichier pour stocker frais - updateFeesFromAnchors() : récupère frais depuis OP_RETURN ancrages - Endpoint /api/utxo/fees/update pour déclencher récupération - Bouton "Récupérer les frais depuis les ancrages" dans section Frais (spinner) - Scripts batch : complete-hash-list-dates.js, complete-utxo-list-blocktime.js - Script diagnostic : diagnose-bloc-rewards.js (subsidy, coinbase, listunspent) **Evolutions:** - Frais chargés depuis fees_list.txt dans getUtxoList - Complétion automatique dates/blockTime lors écritures futures **Pages affectées:** - signet-dashboard/src/bitcoin-rpc.js - signet-dashboard/src/server.js - signet-dashboard/public/utxo-list.html - scripts/complete-hash-list-dates.js - scripts/complete-utxo-list-blocktime.js - scripts/diagnose-bloc-rewards.js - features/utxo-list-fees-update-and-historical-completion.md
58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import type { AppError } from '../hooks/useErrorHandler';
|
||
|
||
interface ErrorDisplayProps {
|
||
error: AppError;
|
||
onDismiss: () => void;
|
||
}
|
||
|
||
export function ErrorDisplay({ error, onDismiss }: ErrorDisplayProps): JSX.Element {
|
||
return (
|
||
<div
|
||
role="alert"
|
||
aria-live="assertive"
|
||
style={{
|
||
padding: '1rem',
|
||
backgroundColor: '#fee',
|
||
border: '1px solid #fcc',
|
||
borderRadius: '0.5rem',
|
||
marginBottom: '1rem',
|
||
}}
|
||
>
|
||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'start' }}>
|
||
<div>
|
||
<strong>Erreur</strong>
|
||
{error.code !== undefined && (
|
||
<span style={{ marginLeft: '0.5rem', fontSize: '0.875rem' }}>
|
||
({error.code})
|
||
</span>
|
||
)}
|
||
<p>{error.message}</p>
|
||
{error.details !== undefined && (
|
||
<details style={{ marginTop: '0.5rem' }}>
|
||
<summary style={{ cursor: 'pointer', fontSize: '0.875rem' }}>
|
||
Détails techniques
|
||
</summary>
|
||
<pre style={{ fontSize: '0.75rem', marginTop: '0.5rem', overflow: 'auto' }}>
|
||
{JSON.stringify(error.details, null, 2)}
|
||
</pre>
|
||
</details>
|
||
)}
|
||
</div>
|
||
<button
|
||
onClick={onDismiss}
|
||
aria-label="Fermer l'erreur"
|
||
style={{
|
||
background: 'none',
|
||
border: 'none',
|
||
fontSize: '1.5rem',
|
||
cursor: 'pointer',
|
||
padding: '0 0.5rem',
|
||
}}
|
||
>
|
||
×
|
||
</button>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|