**Motivations:** - Fix insufficient UTXO amount error in anchor API - Ensure continuous availability of usable UTXOs for anchor transactions - Improve anchor transaction reliability and efficiency **Root causes:** - UTXO selection logic was too restrictive, rejecting UTXOs larger than needed - No automatic provisioning of new usable UTXOs when existing ones were not suitable - Algorithm prevented efficient use of available UTXOs **Correctifs:** - Refactored createAnchorTransaction() to provision 7 UTXOs of 2500 sats on each anchor - Use single large UTXO to create 1 anchor output + 7 provisioning outputs + change - Simplified UTXO selection: single large UTXO per transaction instead of multiple small ones - Added UTXO provisioning logic in signet-dashboard - Enhanced Bitcoin RPC methods in both api-anchorage and signet-dashboard - Added documentation in fixKnowledge/api-anchorage-utxo-provisioning.md **Evolutions:** - Enhanced signet-dashboard with new pages (hash-list, utxo-list, join-signet, api-docs) - Improved Bitcoin RPC client with better error handling and UTXO management - Added cache files for hash and UTXO lists - Updated api-faucet with improved server configuration - Enhanced anchor count tracking **Pages affectées:** - api-anchorage/src/bitcoin-rpc.js: Complete refactor of createAnchorTransaction() - api-anchorage/src/routes/anchor.js: Enhanced anchor route - api-anchorage/src/server.js: Server configuration updates - signet-dashboard/src/bitcoin-rpc.js: Added comprehensive Bitcoin RPC client - signet-dashboard/src/server.js: Enhanced server with new routes - signet-dashboard/public/: Added new HTML pages and updated app.js - api-faucet/src/server.js: Server improvements - api-faucet/README.md: Documentation updates - fixKnowledge/api-anchorage-utxo-provisioning.md: New documentation - anchor_count.txt, hash_list.txt, utxo_list.txt: Tracking files
328 lines
7.1 KiB
Markdown
328 lines
7.1 KiB
Markdown
# API Faucet Bitcoin Signet
|
|
|
|
**Auteur** : Équipe 4NK
|
|
**Date** : 2026-01-23
|
|
**Version** : 1.0.0
|
|
|
|
## Description
|
|
|
|
API REST pour distribuer des sats (50000 sats = 0.0005 BTC) sur la blockchain Bitcoin Signet. Cette API permet aux utilisateurs de recevoir des fonds de test pour développer et tester des applications Bitcoin.
|
|
|
|
## Caractéristiques
|
|
|
|
- **Port** : `3021`
|
|
- **Format** : JSON REST API
|
|
- **Bitcoin** : Connexion RPC au nœud Bitcoin Signet (port 38332)
|
|
- **Montant par défaut** : 50 000 sats (0.0005 BTC)
|
|
|
|
## 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 distribuer
|
|
|
|
### Installation des Dépendances
|
|
|
|
```bash
|
|
cd api-faucet
|
|
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
|
|
BITCOIN_RPC_TIMEOUT=30000
|
|
|
|
# API Configuration
|
|
FAUCET_API_PORT=3021
|
|
FAUCET_API_HOST=0.0.0.0
|
|
|
|
# Faucet Configuration
|
|
FAUCET_AMOUNT=0.0005 # Montant en BTC (50000 sats par défaut)
|
|
|
|
# API Keys (séparées par des virgules)
|
|
API_KEYS=your-api-key-here,another-api-key
|
|
|
|
# Logging
|
|
LOG_LEVEL=info
|
|
NODE_ENV=production
|
|
```
|
|
|
|
**Important** :
|
|
- `BITCOIN_RPC_HOST` : Si l'API est dans un conteneur Docker, utiliser l'IP du conteneur Bitcoin ou `host.docker.internal`
|
|
- `FAUCET_AMOUNT` : Montant à distribuer en BTC (par défaut 0.0005 = 50000 sats)
|
|
- `API_KEYS` : Définir au moins une clé API valide (séparées par des virgules)
|
|
|
|
## Démarrage
|
|
|
|
### Mode Développement
|
|
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
### Mode Production
|
|
|
|
```bash
|
|
npm start
|
|
```
|
|
|
|
### Avec PM2 (recommandé pour production)
|
|
|
|
```bash
|
|
# Installer PM2 globalement
|
|
sudo npm install -g pm2
|
|
|
|
# Démarrer l'API avec PM2
|
|
pm2 start src/server.js --name faucet-api
|
|
|
|
# Sauvegarder la configuration PM2
|
|
pm2 save
|
|
|
|
# Configurer PM2 pour démarrer au boot
|
|
pm2 startup
|
|
# Suivre les instructions affichées
|
|
```
|
|
|
|
## Endpoints
|
|
|
|
### GET /health
|
|
|
|
Vérifie l'état de l'API et de la connexion Bitcoin.
|
|
|
|
**Authentification** : Non requise
|
|
|
|
**Réponse** :
|
|
```json
|
|
{
|
|
"status": "ok",
|
|
"service": "bitcoin-signet-faucet-api",
|
|
"version": "1.0.0",
|
|
"bitcoin": {
|
|
"connected": true,
|
|
"chain": "signet",
|
|
"blocks": 1234,
|
|
"networkactive": true,
|
|
"connections": 5,
|
|
"wallet_balance": 10.5
|
|
},
|
|
"timestamp": "2026-01-23T12:00:00.000Z"
|
|
}
|
|
```
|
|
|
|
### POST /api/faucet/request
|
|
|
|
Demande des sats via le faucet.
|
|
|
|
**Authentification** : Requise (clé API dans le header `x-api-key`)
|
|
|
|
**Headers** :
|
|
```
|
|
x-api-key: your-api-key-here
|
|
Content-Type: application/json
|
|
```
|
|
|
|
**Body** :
|
|
```json
|
|
{
|
|
"address": "tb1qwe0nv3s0ewedd63w20r8kwnv22uw8dp2tnj3qc"
|
|
}
|
|
```
|
|
|
|
**Réponse (succès)** :
|
|
```json
|
|
{
|
|
"success": true,
|
|
"txid": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890",
|
|
"address": "tb1qwe0nv3s0ewedd63w20r8kwnv22uw8dp2tnj3qc",
|
|
"amount": 0.0005,
|
|
"amount_sats": 50000,
|
|
"status": "pending",
|
|
"confirmations": 0,
|
|
"block_height": null
|
|
}
|
|
```
|
|
|
|
**Réponse (erreur - adresse invalide)** :
|
|
```json
|
|
{
|
|
"error": "Bad Request",
|
|
"message": "Invalid Bitcoin address format"
|
|
}
|
|
```
|
|
|
|
**Réponse (erreur - clé API invalide)** :
|
|
```json
|
|
{
|
|
"error": "Unauthorized",
|
|
"message": "Invalid or missing API key"
|
|
}
|
|
```
|
|
|
|
## Exemples d'Utilisation
|
|
|
|
### Avec curl
|
|
|
|
```bash
|
|
# Vérifier l'état de l'API
|
|
curl http://localhost:3021/health
|
|
|
|
# Demander des sats
|
|
curl -X POST http://localhost:3021/api/faucet/request \
|
|
-H "Content-Type: application/json" \
|
|
-H "x-api-key: your-api-key-here" \
|
|
-d '{
|
|
"address": "tb1qwe0nv3s0ewedd63w20r8kwnv22uw8dp2tnj3qc"
|
|
}'
|
|
```
|
|
|
|
### Avec JavaScript (fetch)
|
|
|
|
```javascript
|
|
const response = await fetch('http://localhost:3021/api/faucet/request', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'x-api-key': 'your-api-key-here',
|
|
},
|
|
body: JSON.stringify({
|
|
address: 'tb1qwe0nv3s0ewedd63w20r8kwnv22uw8dp2tnj3qc',
|
|
}),
|
|
});
|
|
|
|
const result = await response.json();
|
|
console.log(result);
|
|
```
|
|
|
|
## Configuration Nginx (sur proxy 192.168.1.100)
|
|
|
|
Ajouter dans la configuration nginx du proxy :
|
|
|
|
```nginx
|
|
# API Faucet
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name faucet.signet.4nkweb.com;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/faucet.signet.4nkweb.com/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/faucet.signet.4nkweb.com/privkey.pem;
|
|
|
|
location / {
|
|
proxy_pass http://192.168.1.103:3021;
|
|
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 Faucet (port 3021)
|
|
↓ RPC
|
|
Bitcoin Signet Node (port 38332)
|
|
```
|
|
|
|
## Sécurité
|
|
|
|
### Rate Limiting (Recommandé)
|
|
|
|
Pour éviter les abus, il est recommandé d'implémenter un rate limiting. Exemple avec `express-rate-limit` :
|
|
|
|
```bash
|
|
npm install express-rate-limit
|
|
```
|
|
|
|
```javascript
|
|
import rateLimit from 'express-rate-limit';
|
|
|
|
const limiter = rateLimit({
|
|
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
max: 1, // 1 requête par adresse IP toutes les 15 minutes
|
|
message: 'Too many requests from this IP, please try again later.',
|
|
});
|
|
|
|
app.use('/api/faucet/request', limiter);
|
|
```
|
|
|
|
### Validation des Adresses
|
|
|
|
L'API valide automatiquement les adresses Bitcoin avant d'envoyer les fonds. Seules les adresses valides sont acceptées.
|
|
|
|
### Gestion des Erreurs
|
|
|
|
- **401 Unauthorized** : Clé API manquante ou invalide
|
|
- **400 Bad Request** : Adresse invalide
|
|
- **503 Service Unavailable** : Solde insuffisant
|
|
- **500 Internal Server Error** : Erreur serveur
|
|
|
|
## Dépannage
|
|
|
|
### L'API ne démarre pas
|
|
|
|
- Vérifier que le port 3021 n'est pas utilisé : `netstat -tlnp | grep 3021`
|
|
- Vérifier les logs : `pm2 logs faucet-api`
|
|
- Vérifier la configuration dans `.env`
|
|
|
|
### Erreur "Insufficient balance"
|
|
|
|
- Vérifier le solde du wallet : `bitcoin-cli getbalance`
|
|
- Miner des blocs pour obtenir des fonds
|
|
- Vérifier que le wallet est déverrouillé
|
|
|
|
### Erreur "Invalid Bitcoin address"
|
|
|
|
- Vérifier que l'adresse est une adresse Signet valide (commence par `tb1`, `bcrt1`, `2`, ou `3`)
|
|
- Vérifier le format de l'adresse (25-62 caractères)
|
|
|
|
### Transaction non envoyée
|
|
|
|
- Vérifier les logs de l'API pour les erreurs RPC
|
|
- Vérifier que le nœud Bitcoin est accessible
|
|
- Vérifier que le wallet est déverrouillé et a des fonds
|
|
|
|
## Structure des Fichiers
|
|
|
|
```
|
|
api-faucet/
|
|
├── package.json
|
|
├── README.md
|
|
├── .env.example
|
|
└── src/
|
|
├── server.js # Serveur Express
|
|
├── bitcoin-rpc.js # Client Bitcoin RPC
|
|
├── logger.js # Logger
|
|
└── routes/
|
|
├── faucet.js # Routes du faucet
|
|
└── health.js # Routes de santé
|
|
```
|
|
|
|
## Licence
|
|
|
|
MIT
|