#!/usr/bin/env node /** * Client de test pour l'API d'ancrage * Usage: node src/test-client.js */ import https from 'https'; import http from 'http'; import crypto from 'crypto'; // Configuration const API_URL = process.env.API_URL || 'http://localhost:3010'; const API_KEY = process.env.API_KEY || 'your-api-key-here'; /** * Effectue une requête HTTP/HTTPS */ function makeRequest(method, path, data = null) { return new Promise((resolve, reject) => { const url = new URL(path, API_URL); const isHttps = url.protocol === 'https:'; const httpModule = isHttps ? https : http; const options = { hostname: url.hostname, port: url.port || (isHttps ? 443 : 80), path: url.pathname, method: method, headers: { 'Content-Type': 'application/json', 'x-api-key': API_KEY, }, }; const req = httpModule.request(options, (res) => { let body = ''; res.on('data', (chunk) => { body += chunk; }); res.on('end', () => { try { const json = JSON.parse(body); if (res.statusCode >= 200 && res.statusCode < 300) { resolve(json); } else { reject(new Error(`HTTP ${res.statusCode}: ${json.error || body}`)); } } catch (e) { reject(new Error(`Parse error: ${e.message}`)); } }); }); req.on('error', (error) => { reject(error); }); if (data) { req.write(JSON.stringify(data)); } req.end(); }); } /** * Vérifie l'état de l'API */ async function checkHealth() { try { console.log('🔍 Vérification de l\'état de l\'API...'); const response = await makeRequest('GET', '/health'); console.log('✅ API opérationnelle'); console.log(` Bitcoin connecté: ${response.bitcoin.connected ? 'Oui' : 'Non'}`); console.log(` Blocs: ${response.bitcoin.blocks}`); return response; } catch (error) { console.error('❌ Erreur:', error.message); throw error; } } /** * Ancre un document sur Bitcoin Signet * La transaction est envoyée au mempool et retournée immédiatement. */ async function anchorDocument(documentUid, hash) { try { console.log(`\n📎 Ancrage du document: ${documentUid}`); console.log(` Hash: ${hash.substring(0, 16)}...`); const data = { documentUid, hash, }; const response = await makeRequest('POST', '/api/anchor/document', data); console.log('✅ Document ancré avec succès'); console.log(` Transaction ID: ${response.txid}`); console.log(` Confirmations: ${response.confirmations}`); if (response.block_height) { console.log(` Block height: ${response.block_height}`); } return response; } catch (error) { console.error('❌ Erreur lors de l\'ancrage:', error.message); throw error; } } /** * Vérifie si un hash est ancré */ async function verifyAnchor(hash, txid = null) { try { console.log(`\n🔍 Vérification de l'ancrage...`); console.log(` Hash: ${hash.substring(0, 16)}...`); const data = { hash }; if (txid) { data.txid = txid; console.log(` Transaction ID: ${txid.substring(0, 16)}...`); } const response = await makeRequest('POST', '/api/anchor/verify', data); if (response.verified) { console.log('✅ Hash vérifié et ancré'); if (response.anchor_info) { console.log(` Transaction ID: ${response.anchor_info.transaction_id}`); console.log(` Block height: ${response.anchor_info.block_height}`); console.log(` Confirmations: ${response.anchor_info.confirmations}`); } } else { console.log('❌ Hash non trouvé dans la blockchain'); } return response; } catch (error) { console.error('❌ Erreur lors de la vérification:', error.message); throw error; } } /** * Fonction principale */ async function main() { console.log('=== Client API Anchor ===\n'); try { // 1. Vérifier l'état de l'API await checkHealth(); // 2. Générer un hash de test const documentContent = `Document de test - ${new Date().toISOString()}`; const hash = crypto.createHash('sha256').update(documentContent).digest('hex'); const documentUid = `doc-${Date.now()}`; console.log(`\n📄 Document de test:`); console.log(` UID: ${documentUid}`); console.log(` Hash: ${hash}`); // 3. Ancrer le document const anchorResult = await anchorDocument(documentUid, hash); // 4. Attendre un peu pour que la transaction soit propagée console.log('\n⏳ Attente de 3 secondes pour la propagation...'); await new Promise((resolve) => setTimeout(resolve, 3000)); // 5. Vérifier l'ancrage await verifyAnchor(hash, anchorResult.txid); console.log('\n✅ Tous les tests sont passés avec succès!'); } catch (error) { console.error('\n❌ Erreur:', error.message); process.exit(1); } } // Exécuter le script if (import.meta.url === `file://${process.argv[1]}`) { main(); } // Exports pour utilisation comme module export { checkHealth, anchorDocument, verifyAnchor, };