diff --git a/signet-dashboard/public/app.js b/signet-dashboard/public/app.js
index 0b64cae..3b30b91 100644
--- a/signet-dashboard/public/app.js
+++ b/signet-dashboard/public/app.js
@@ -69,6 +69,7 @@ async function loadData() {
loadLatestBlock(),
loadWalletBalance(),
loadAnchorCount(),
+ loadAvailableForAnchor(),
loadNetworkPeers(),
loadMiningDifficulty(),
loadAvgBlockTime(),
@@ -187,6 +188,53 @@ async function loadAnchorCount() {
}
}
+/**
+ * Charge la capacité d'ancrage restante
+ */
+async function loadAvailableForAnchor() {
+ const availableForAnchorValue = document.getElementById('available-for-anchor-value');
+ const availableForAnchorSpinner = document.getElementById('available-for-anchor-spinner');
+ const confirmedAvailableForAnchorValue = document.getElementById('confirmed-available-for-anchor-value');
+
+ if (!availableForAnchorValue || !availableForAnchorSpinner || !confirmedAvailableForAnchorValue) {
+ console.error('Elements for available-for-anchor not found in DOM');
+ return;
+ }
+
+ // Afficher le spinner
+ availableForAnchorSpinner.style.display = 'inline';
+ availableForAnchorValue.textContent = '...';
+ confirmedAvailableForAnchorValue.textContent = '...';
+
+ try {
+ const response = await fetch(`${API_BASE_URL}/api/utxo/list`);
+
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+
+ const data = await response.json();
+ const counts = data.counts || {};
+ const availableForAnchor = counts.availableForAnchor || 0;
+ const confirmedAvailableForAnchor = counts.confirmedAvailableForAnchor || 0;
+
+ // Masquer le spinner et mettre à jour les valeurs
+ availableForAnchorSpinner.style.display = 'none';
+ availableForAnchorValue.textContent = availableForAnchor.toLocaleString('fr-FR') + ' ancrages';
+ confirmedAvailableForAnchorValue.textContent = confirmedAvailableForAnchor.toLocaleString('fr-FR');
+ } catch (error) {
+ console.error('Error loading available for anchor:', error);
+ // Masquer le spinner
+ availableForAnchorSpinner.style.display = 'none';
+ // Afficher une valeur par défaut en cas d'erreur
+ const currentValue = availableForAnchorValue.textContent;
+ if (currentValue === '-' || currentValue === 'Erreur' || currentValue === '...') {
+ availableForAnchorValue.textContent = '0 ancrages';
+ }
+ confirmedAvailableForAnchorValue.textContent = '0';
+ }
+}
+
/**
* Charge les informations sur les pairs
*/
@@ -476,11 +524,21 @@ function handleFileSelect(event) {
if (file) {
selectedFile = file;
const fileInfo = document.getElementById('file-info');
- fileInfo.innerHTML = `
+ const maxSize = 100 * 1024 * 1024; // 100 MB en bytes
+ const fileSize = file.size;
+ const isOverLimit = fileSize > maxSize;
+
+ let infoHtml = `
Fichier sélectionné : ${file.name}
Taille : ${formatFileSize(file.size)}
Type : ${file.type || 'Non spécifié'}
`;
+
+ if (isOverLimit) {
+ infoHtml += `
⚠️ Fichier trop volumineux (limite : 100 MB)`;
+ }
+
+ fileInfo.innerHTML = infoHtml;
}
}
@@ -537,34 +595,64 @@ async function generateHashFromFile() {
return;
}
+ // Vérifier la taille du fichier (limite : 100 MB)
+ const maxSize = 100 * 1024 * 1024; // 100 MB en bytes
+ if (selectedFile.size > maxSize) {
+ showResult('anchor-result', 'error', `Le fichier est trop volumineux (${formatFileSize(selectedFile.size)}). La limite est de 100 MB.`);
+ return;
+ }
+
try {
const reader = new FileReader();
- reader.onload = async (e) => {
- const fileContent = e.target.result;
- try {
- const response = await fetch(`${API_BASE_URL}/api/hash/generate`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({ fileContent }),
- });
+ await new Promise((resolve, reject) => {
+ reader.onload = async (e) => {
+ try {
+ const arrayBuffer = e.target.result;
+ // Convertir l'ArrayBuffer en base64 pour l'envoi au backend
+ // Utiliser une boucle pour éviter les limites de taille des arguments de fonction
+ const uint8Array = new Uint8Array(arrayBuffer);
+ let binaryString = '';
+ for (let i = 0; i < uint8Array.length; i++) {
+ binaryString += String.fromCharCode(uint8Array[i]);
+ }
+ const base64 = btoa(binaryString);
- const data = await response.json();
+ const response = await fetch(`${API_BASE_URL}/api/hash/generate`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ fileContent: base64, isBase64: true }),
+ });
- if (data.hash) {
- document.getElementById('anchor-hash').value = data.hash;
- showResult('anchor-result', 'success', `Hash généré avec succès : ${data.hash}`);
- } else {
- showResult('anchor-result', 'error', 'Erreur lors de la génération du hash.');
+ if (!response.ok) {
+ const errorData = await response.json().catch(() => ({ error: `HTTP ${response.status}: ${response.statusText}` }));
+ throw new Error(errorData.error || `HTTP ${response.status}: ${response.statusText}`);
+ }
+
+ const data = await response.json();
+
+ if (data.hash) {
+ document.getElementById('anchor-hash').value = data.hash;
+ showResult('anchor-result', 'success', `Hash généré avec succès : ${data.hash}`);
+ } else {
+ showResult('anchor-result', 'error', data.error || 'Erreur lors de la génération du hash.');
+ }
+ resolve();
+ } catch (error) {
+ showResult('anchor-result', 'error', `Erreur : ${error.message}`);
+ reject(error);
}
- } catch (error) {
- showResult('anchor-result', 'error', `Erreur : ${error.message}`);
- }
- };
+ };
- reader.readAsText(selectedFile);
+ reader.onerror = (error) => {
+ showResult('anchor-result', 'error', `Erreur lors de la lecture du fichier : ${error.message || 'Erreur inconnue'}`);
+ reject(error);
+ };
+
+ reader.readAsArrayBuffer(selectedFile);
+ });
} catch (error) {
showResult('anchor-result', 'error', `Erreur lors de la lecture du fichier : ${error.message}`);
}
diff --git a/signet-dashboard/public/index.html b/signet-dashboard/public/index.html
index 9af9001..53bdbdb 100644
--- a/signet-dashboard/public/index.html
+++ b/signet-dashboard/public/index.html
@@ -65,6 +65,16 @@
+ - + +
++ - UTXOs confirmés +
+-
@@ -118,6 +128,9 @@+ Limite de taille : 100 MB maximum +
Bitcoin Ancrage Dashboard - Équipe 4NK
Dernière mise à jour : -
-