# API d'Ancrage Bitcoin Signet **Auteur** : Équipe 4NK **Date** : 2026-01-23 **Version** : 1.0 ## Description API REST pour ancrer des documents sur la blockchain Bitcoin Signet. Cette API permet de créer des transactions Bitcoin qui incluent les hash de documents dans des outputs OP_RETURN, permettant ainsi de prouver l'existence d'un document à un moment donné. ## Caractéristiques - **Port** : `3010` - **Domaine** : `certificator.4nkweb.com` (via nginx sur proxy 192.168.1.100) - **Authentification** : API Key via header `x-api-key` - **Format** : JSON REST API - **Bitcoin** : Connexion RPC au nœud Bitcoin Signet (port 38332) - **Mempool** : Les transactions sont envoyées au mempool et retournées immédiatement (pas de callbacks) ## Installation ### Prérequis - Node.js >= 18.0.0 - Accès au nœud Bitcoin Signet (RPC sur port 38332) - Wallet Bitcoin avec des fonds pour créer des transactions ### Installation des Dépendances ```bash cd api-anchorage npm install ``` ### Configuration 1. Copier le fichier d'exemple : ```bash cp .env.example .env ``` 2. Éditer `.env` : ```bash # Bitcoin RPC Configuration BITCOIN_RPC_HOST=localhost BITCOIN_RPC_PORT=38332 BITCOIN_RPC_USER=bitcoin BITCOIN_RPC_PASSWORD=bitcoin # API Configuration API_PORT=3010 API_HOST=0.0.0.0 # API Keys (séparées par des virgules) API_KEYS=your-api-key-here,another-api-key # Logging LOG_LEVEL=info # Mining Configuration MINING_ENABLED=true MINING_FEE_RATE=0.00001 ``` **Important** : - `BITCOIN_RPC_HOST` : Si l'API est dans un conteneur Docker, utiliser l'IP du conteneur Bitcoin ou `host.docker.internal` - `API_KEYS` : Définir au moins une clé API valide ## Démarrage ### Mode Développement ```bash npm run dev ``` ### Mode Production ```bash npm start ``` ### Avec PM2 (recommandé pour production) ```bash pm2 start src/server.js --name anchor-api pm2 save pm2 startup ``` ## Endpoints ### GET /health Vérifie l'état de l'API et de la connexion Bitcoin. **Authentification** : Non requise **Réponse** : ```json { "ok": true, "service": "anchor-api", "bitcoin": { "connected": true, "blocks": 152321, "chain": "signet", "networkactive": true, "connections": 1 }, "timestamp": "2026-01-23T16:35:27.821Z" } ``` ### POST /api/anchor/document Ancre un document sur Bitcoin Signet. La transaction est créée et envoyée au mempool, puis retournée immédiatement. **Authentification** : Requise (header `x-api-key`) **Body** : ```json { "documentUid": "doc-123456", "hash": "a1b2c3d4e5f6...", "skipIfExists": false } ``` **Paramètres** : - `documentUid` : string (optionnel, identifiant du document) - `hash` : string (requis, hash SHA256 du document en hex, 64 caractères) - `skipIfExists` : boolean (optionnel, par défaut `false`, si `true`, ne réancrera pas un hash déjà ancré et retournera les informations existantes) **Note** : La transaction est envoyée au mempool et retournée immédiatement. Aucun callback n'est supporté. **Réponse** (nouvel ancrage) : ```json { "ok": true, "txid": "56504e002d95301ebcfb4b30eaedc5d3fd9a448e121ffdce4f356b8d34169e85", "status": "confirmed", "confirmations": 0, "block_height": 152321, "outputs": [...], "fee": 0.00001, "fee_sats": 1000, "old": false } ``` **Réponse** (hash déjà ancré avec `skipIfExists: true`) : ```json { "ok": true, "txid": "56504e002d95301ebcfb4b30eaedc5d3fd9a448e121ffdce4f356b8d34169e85", "status": "confirmed", "confirmations": 5, "block_height": 152316, "old": true } ``` **Champs de réponse** : - `ok` : boolean, toujours `true` en cas de succès - `txid` : string, ID de la transaction Bitcoin - `status` : string, statut de la transaction (`"confirmed"` ou `"pending"`) - `confirmations` : number, nombre de confirmations - `block_height` : number|null, hauteur du bloc (null si pas encore dans un bloc) - `outputs` : array, liste des outputs de la transaction (uniquement pour nouveaux ancrages) - `fee` : number|null, frais de transaction en BTC (uniquement pour nouveaux ancrages) - `fee_sats` : number|null, frais de transaction en sats (uniquement pour nouveaux ancrages) - `old` : boolean, `true` si le hash était déjà ancré, `false` si c'est un nouvel ancrage **Erreurs** : - `400 Bad Request` : Hash invalide - `401 Unauthorized` : Clé API invalide ou manquante - `402 Payment Required` : Solde insuffisant - `500 Internal Server Error` : Erreur serveur ### POST /api/anchor/verify Vérifie si un hash est ancré sur Bitcoin Signet. **Authentification** : Requise (header `x-api-key`) **Body** : ```json { "hash": "a1b2c3d4e5f6...", "txid": "56504e002d95301ebcfb4b30eaedc5d3fd9a448e121ffdce4f356b8d34169e85" // optionnel } ``` **Réponse** (hash trouvé) : ```json { "verified": true, "anchor_info": { "transaction_id": "56504e002d95301ebcfb4b30eaedc5d3fd9a448e121ffdce4f356b8d34169e85", "block_height": 152321, "confirmations": 0, "current_block_height": 152321 } } ``` **Réponse** (hash non trouvé) : ```json { "verified": false, "message": "Hash not found in recent blocks" } ``` ## Utilisation ### Exemple avec curl ```bash # Health check curl http://localhost:3010/health # Ancrer un document curl -X POST http://localhost:3010/api/anchor/document \ -H "Content-Type: application/json" \ -H "x-api-key: your-api-key-here" \ -d '{ "documentUid": "doc-123", "hash": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890" }' # Ancrer un document sans réancrer si déjà ancré curl -X POST http://localhost:3010/api/anchor/document \ -H "Content-Type: application/json" \ -H "x-api-key: your-api-key-here" \ -d '{ "documentUid": "doc-123", "hash": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890", "skipIfExists": true }' # Vérifier un ancrage curl -X POST http://localhost:3010/api/anchor/verify \ -H "Content-Type: application/json" \ -H "x-api-key: your-api-key-here" \ -d '{ "hash": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890" }' ``` ### Exemple avec le client de test ```bash # Configurer la clé API export API_KEY=your-api-key-here export API_URL=http://localhost:3010 # Exécuter le test npm test ``` ## Configuration Nginx (sur proxy 192.168.1.100) Ajouter dans la configuration nginx du proxy : ```nginx # API Anchor sur certificator.4nkweb.com server { listen 443 ssl http2; server_name certificator.4nkweb.com; ssl_certificate /etc/letsencrypt/live/certificator.4nkweb.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/certificator.4nkweb.com/privkey.pem; location / { proxy_pass http://192.168.1.103:3010; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; } } ``` **Note** : Remplacer `192.168.1.103` par l'IP du serveur où l'API est déployée. ## Architecture ``` Client ↓ HTTPS Nginx (proxy 192.168.1.100:443) ↓ HTTP API Anchor (port 3010) ↓ RPC Bitcoin Signet Node (port 38332) ``` ## Sécurité ### Clés API - Les clés API sont définies dans `.env` (variable `API_KEYS`) - Plusieurs clés peuvent être définies (séparées par des virgules) - La clé doit être envoyée dans le header `x-api-key` - Le endpoint `/health` ne nécessite pas d'authentification ### Recommandations 1. **Ne jamais commiter `.env`** : Le fichier `.env` contient des secrets 2. **Utiliser HTTPS** : Via nginx avec certificats Let's Encrypt 3. **Restreindre RPCALLOWIP** : Dans la configuration Bitcoin, limiter l'accès RPC 4. **Rotater les clés API** : Changer régulièrement les clés API 5. **Monitoring** : Surveiller les logs pour détecter les abus ## Dépannage ### L'API ne peut pas se connecter à Bitcoin **Vérifier** : ```bash # Vérifier que le nœud Bitcoin est accessible curl -u bitcoin:bitcoin http://localhost:38332 # Vérifier les variables d'environnement grep BITCOIN_RPC .env ``` ### Erreur "Insufficient balance" Le wallet Bitcoin n'a pas assez de fonds pour créer des transactions. **Solution** : - Miner des blocs pour obtenir des récompenses - Recevoir des fonds depuis un autre wallet - Vérifier le solde : `bitcoin-cli getbalance` ### Erreur "Unauthorized" La clé API est invalide ou manquante. **Solution** : - Vérifier que le header `x-api-key` est présent - Vérifier que la clé est dans `API_KEYS` du `.env` ## Logs Les logs sont affichés sur la console avec le format : ``` [2026-01-23T16:35:27.821Z] [INFO] API d'ancrage Bitcoin Signet démarrée {"host":"0.0.0.0","port":3010} ``` Niveaux de log : - `error` : Erreurs critiques - `warn` : Avertissements - `info` : Informations générales - `debug` : Détails de débogage Contrôlé par la variable `LOG_LEVEL` dans `.env`. ## Structure du Projet ``` api-anchorage/ ├── src/ │ ├── server.js # Serveur Express principal │ ├── bitcoin-rpc.js # Client Bitcoin RPC │ ├── logger.js # Système de logging │ └── routes/ │ ├── health.js # Route health check │ └── anchor.js # Routes d'ancrage ├── package.json ├── .env.example ├── .env # Configuration (ne pas commiter) ├── README.md └── src/test-client.js # Client de test ``` ## Développement ### Tests Locaux ```bash # Démarrer l'API npm run dev # Dans un autre terminal, tester npm test ``` ### Format de Transaction Les transactions d'ancrage utilisent un output OP_RETURN avec le format : - Préfixe : `"ANCHOR:"` (7 bytes) - Hash : Hash SHA256 du document (32 bytes) Total : 39 bytes dans l'output OP_RETURN. --- **Dernière mise à jour** : 2026-01-23