NicolasCantu 924ab8e185 refactor: Replace UUID transaction_id with Bitcoin txid
**Motivations :**
* transaction_id doit être un identifiant de transaction Bitcoin consultable sur mempool
* Les UUID n'ont pas d'utilité pour identifier une transaction Bitcoin
* Simplification de l'architecture en supprimant la logique de queue inutile

**Root causes :**
* transaction_id était généré comme UUID au lieu d'utiliser le txid Bitcoin
* Logique de queue/job complexe pour gérer des identifiants temporaires
* Réponse HTTP 202 alors que la transaction est créée immédiatement

**Correctifs :**
* transaction_id est maintenant directement le txid Bitcoin (64 hex)
* Suppression complète de la logique de queue et de job (Map, cleanup, etc.)
* Création immédiate de la transaction Bitcoin dans enqueue()
* getStatus() interroge directement Bitcoin au lieu d'une Map en mémoire
* Réponse HTTP 200 OK au lieu de 202 Accepted
* Suppression de la dépendance uuid (plus utilisée)

**Evolutions :**
* API simplifiée : plus de queue, transactions créées directement
* transaction_id consultable immédiatement sur mempool
* Documentation complète des réponses JSON (API_RESPONSES.md)
* Scripts de test mis à jour pour valider le format txid Bitcoin

**Page affectées :**
* src/services/AnchorQueueService.ts : refactor complet, suppression queue
* src/controllers/AnchorController.ts : mise à jour pour txid, status 200
* src/index.ts : suppression cleanup périodique
* test-api-ok.sh : validation format txid, status 200
* test-api.sh : validation format txid, status 200
* README.md : mise à jour exemples avec txid Bitcoin
* API_RESPONSES.md : nouvelle documentation complète des réponses JSON
2025-11-21 08:11:02 +01:00

329 lines
7.6 KiB
Markdown

# LeCoffre Anchor API
API d'ancrage Bitcoin Signet pour LeCoffre.io, déployée sur `dev3.4nkweb.com`.
## 📦 Vue d'ensemble
Cette API autonome gère l'ancrage de hashes de documents sur la blockchain Bitcoin Signet. Elle est séparée du backend principal (`lecoffre-back-main`) pour:
- **Isolation**: Le nœud Bitcoin et l'API d'ancrage tournent sur un serveur dédié (dev3.4nkweb.com)
- **Performance**: Évite la surcharge du backend principal avec des opérations blockchain lentes
- **Sécurité**: Accès restreint par API key
- **Scalabilité**: Peut gérer une file d'attente d'ancrages indépendamment
## 🏗️ Architecture
```
lecoffre-back-main (local.4nkweb.com:3001)
├─── HTTP POST ───> lecoffre-anchor-api (dev3.4nkweb.com:3002)
│ │
│ ├─── JSON-RPC ───> Bitcoin Node (localhost:38332)
│ └─── Callback ───> lecoffre-back-main
└─── Continue processing...
```
## 🚀 Installation
### Prérequis
- Node.js >= 18
- Bitcoin Core node (Signet) configuré avec JSON-RPC
- Accès au fichier cookie Bitcoin (`.cookie`)
### 1. Installer les dépendances
```bash
npm install
```
### 2. Configuration
Copier `.env.example` vers `.env` et configurer:
```bash
cp .env.example .env
nano .env
```
Variables importantes:
```env
PORT=3002
API_KEY=your-secure-api-key-here # Générer avec uuidv4
BITCOIN_COOKIE_PATH=/home/bitcoin/.4nk/.cookie
CORS_ORIGINS=http://local.4nkweb.com:3001
```
### 3. Build
```bash
npm run build
```
### 4. Démarrer l'API
```bash
# Production
npm start
# Développement (avec auto-reload)
npm run dev
```
## 📡 Endpoints API
### Health Check
```bash
GET /health
```
**Response**:
```json
{
"ok": true,
"service": "anchor-api",
"bitcoin": {
"connected": true,
"blocks": 245678
},
"timestamp": "2025-10-17T14:00:00.000Z"
}
```
---
### Ancrer un document
```bash
POST /api/anchor/document
Headers:
x-api-key: your-secure-api-key
Content-Type: application/json
Body:
{
"documentUid": "uuid-of-document",
"hash": "64-char-hex-hash",
"callback_url": "http://local.4nkweb.com:3001/api/v1/anchors/callback"
}
```
**Response** (200 OK):
```json
{
"transaction_id": "7b6f473879b3993812bc5eda39d801c1fd3f918cd35c9f6d922f1c3e95db9825",
"status": "pending",
"confirmations": 0,
"block_height": null,
"txid": "7b6f473879b3993812bc5eda39d801c1fd3f918cd35c9f6d922f1c3e95db9825",
"hash": "64-char-hex-hash",
"documentUid": "uuid-of-document",
"explorer_url": "https://mempool2.4nkweb.com/fr/tx/7b6f473879b3993812bc5eda39d801c1fd3f918cd35c9f6d922f1c3e95db9825",
"context": {
"network": "Bitcoin Signet",
"explorer": "mempool2.4nkweb.com",
"api_version": "1.0.0",
"request_timestamp": "2025-11-14T10:30:00.000Z",
"document_uid": "uuid-of-document",
"hash": "64-char-hex-hash",
"status": "pending"
}
}
```
**Note** : Le `transaction_id` est maintenant directement le `txid` Bitcoin (64 hex), consultable sur mempool.
---
### Vérifier le statut d'un ancrage
```bash
GET /api/anchor/status/:transactionId
Headers:
x-api-key: your-secure-api-key
```
**Response**:
```json
{
"transaction_id": "7b6f473879b3993812bc5eda39d801c1fd3f918cd35c9f6d922f1c3e95db9825",
"status": "confirmed",
"confirmations": 6,
"block_height": 245680,
"txid": "7b6f473879b3993812bc5eda39d801c1fd3f918cd35c9f6d922f1c3e95db9825",
"hash": "64-char-hex-hash",
"documentUid": "uuid-of-document",
"explorer_url": "https://mempool2.4nkweb.com/fr/tx/7b6f473879b3993812bc5eda39d801c1fd3f918cd35c9f6d922f1c3e95db9825",
"network": "signet",
"timestamp": "2025-11-14T10:25:00.000Z",
"fee": -0.00000234,
"size": 250,
"anchor_info": {
"hash": "64-char-hex-hash",
"document_uid": "uuid-of-document",
"op_return_data": "64-char-hex-hash",
"anchored_at": "2025-11-14T10:25:00.000Z",
"block_height": 245680,
"confirmations": 6,
"explorer_url": "https://mempool2.4nkweb.com/fr/tx/7b6f473879b3993812bc5eda39d801c1fd3f918cd35c9f6d922f1c3e95db9825",
"network": "signet"
}
}
```
**Note** : Le `transaction_id` est le `txid` Bitcoin, directement consultable sur mempool.
---
### Vérifier si un hash est ancré
```bash
POST /api/anchor/verify
Headers:
x-api-key: your-secure-api-key
Content-Type: application/json
Body:
{
"hash": "64-char-hex-hash",
"txid": "bitcoin-transaction-id" # optionnel
}
```
**Response**:
```json
{
"verified": true,
"anchor_info": {
"transaction_id": "txid",
"block_height": 245680,
"confirmations": 6,
"timestamp": "2025-10-17T14:00:00.000Z"
}
}
```
## 🔧 Intégration avec lecoffre-back-main
### 1. Configuration backend
Dans `lecoffre-back-main/.env`:
```env
ANCHOR_API_URL=http://dev3.4nkweb.com:3002
ANCHOR_API_KEY=your-secure-api-key
```
### 2. Modifier BitcoinSignetService
Au lieu d'appeler directement le nœud Bitcoin, faire des appels HTTP vers l'API d'ancrage:
```typescript
// Ancien (direct Bitcoin RPC)
const txid = await this.rpcCall('sendrawtransaction', [signedTx.hex]);
// Nouveau (via Anchor API)
const response = await fetch(`${ANCHOR_API_URL}/api/anchor/document`, {
method: 'POST',
headers: {
'x-api-key': ANCHOR_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
documentUid: document.uid,
hash: documentHash,
callback_url: `${LECOFFRE_BACK_URL}/api/v1/anchors/callback`
})
});
```
## 🔒 Sécurité
- **API Key**: Toutes les routes `/api/*` nécessitent un header `x-api-key`
- **CORS**: Restreint aux origines configurées
- **Rate Limiting**: 100 requêtes/minute par défaut
- **Helmet**: Headers de sécurité HTTP
## 📊 Logs
Logs écrits dans `./logs/anchor-api.log` (configurable via `LOG_FILE_PATH`).
Niveaux de log:
- `error`: Erreurs critiques
- `warn`: Avertissements
- `info`: Informations générales
- `debug`: Détails de debug
## 🛠️ Déploiement
### PM2 (production)
```bash
pm2 start dist/index.js --name lecoffre-anchor-api
pm2 save
```
### Docker (optionnel)
```dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist ./dist
EXPOSE 3002
CMD ["node", "dist/index.js"]
```
## 📝 Maintenance
### Architecture simplifiée
L'API ne gère plus de queue en mémoire. Les transactions Bitcoin sont créées immédiatement et le `transaction_id` retourné est directement le `txid` Bitcoin, consultable sur mempool.
### Monitoring
- Health check: `curl http://dev3.4nkweb.com:3002/health`
- PM2 logs: `pm2 logs lecoffre-anchor-api`
- Logs fichier: `tail -f logs/anchor-api.log`
## 🚨 Troubleshooting
### Erreur "Bitcoin cookie file not accessible"
```bash
# Vérifier les permissions
ls -l /home/bitcoin/.4nk/.cookie
# Donner accès au user de l'API
sudo chmod 644 /home/bitcoin/.4nk/.cookie
# OU ajouter le user au groupe bitcoin
sudo usermod -a -G bitcoin debian
```
### Erreur "No unspent outputs available"
Le wallet Bitcoin n'a pas de fonds. Envoyer des tBTC Signet au wallet:
```bash
bitcoin-cli -signet getnewaddress
# Utiliser un faucet Signet pour obtenir des tBTC
```
### Callback échoue
Vérifier que `lecoffre-back-main` est accessible depuis `dev3.4nkweb.com`:
```bash
curl -I http://local.4nkweb.com:3001/api/v1/public/health
```
## 📚 Documentation supplémentaire
- Bitcoin Signet: https://en.bitcoin.it/wiki/Signet
- Bitcoin RPC API: https://developer.bitcoin.org/reference/rpc/
- OP_RETURN: https://en.bitcoin.it/wiki/OP_RETURN
## 📞 Support
Pour toute question ou problème, consulter:
- `/todo/TODO6_IMPLEMENTATION_COMPLETE.md` (backend principal)
- Logs: `pm2 logs lecoffre-anchor-api`