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
npm install
2. Configuration
Copier .env.example vers .env et configurer:
cp .env.example .env
nano .env
Variables importantes:
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
npm run build
4. Démarrer l'API
# Production
npm start
# Développement (avec auto-reload)
npm run dev
📡 Endpoints API
Health Check
GET /health
Response:
{
"ok": true,
"service": "anchor-api",
"bitcoin": {
"connected": true,
"blocks": 245678
},
"timestamp": "2025-10-17T14:00:00.000Z"
}
Ancrer un document
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):
{
"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
GET /api/anchor/status/:transactionId
Headers:
x-api-key: your-secure-api-key
Response:
{
"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é
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:
{
"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:
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:
// 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 headerx-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 critiqueswarn: Avertissementsinfo: Informations généralesdebug: Détails de debug
🛠️ Déploiement
PM2 (production)
pm2 start dist/index.js --name lecoffre-anchor-api
pm2 save
Docker (optionnel)
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"
# 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:
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:
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