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 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)

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

# 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

📞 Support

Pour toute question ou problème, consulter:

  • /todo/TODO6_IMPLEMENTATION_COMPLETE.md (backend principal)
  • Logs: pm2 logs lecoffre-anchor-api
Description
No description provided
Readme 88 KiB
Languages
TypeScript 71.3%
Shell 28.7%