1032 lines
22 KiB
Markdown
1032 lines
22 KiB
Markdown
# API Reference - sdk_relay
|
|
|
|
## Vue d'Ensemble
|
|
|
|
`sdk_relay` expose deux interfaces principales pour l'intégration avec les clients :
|
|
|
|
- **WebSocket API** (port 8090) : Communication temps réel bidirectionnelle
|
|
- **HTTP REST API** (port 8091) : Interface REST pour les opérations CRUD
|
|
|
|
## Base URLs
|
|
|
|
```bash
|
|
# WebSocket
|
|
ws://localhost:8090
|
|
wss://localhost:8090 # Sécurisé
|
|
|
|
# HTTP REST
|
|
http://localhost:8091
|
|
https://localhost:8091 # Sécurisé
|
|
```
|
|
|
|
---
|
|
|
|
## WebSocket API
|
|
|
|
### Connexion
|
|
|
|
```javascript
|
|
const ws = new WebSocket('ws://localhost:8090');
|
|
|
|
ws.onopen = () => {
|
|
console.log('Connecté à sdk_relay');
|
|
// Envoyer le handshake initial
|
|
sendHandshake();
|
|
};
|
|
|
|
ws.onmessage = (event) => {
|
|
const message = JSON.parse(event.data);
|
|
handleMessage(message);
|
|
};
|
|
|
|
ws.onerror = (error) => {
|
|
console.error('Erreur WebSocket:', error);
|
|
};
|
|
|
|
ws.onclose = (event) => {
|
|
console.log('Connexion fermée:', event.code, event.reason);
|
|
};
|
|
```
|
|
|
|
### Handshake Initial
|
|
|
|
**Endpoint :** `ws://localhost:8090`
|
|
|
|
**Message de Handshake :**
|
|
```json
|
|
{
|
|
"type": "handshake",
|
|
"client_id": "my-client-123",
|
|
"version": "1.0.0",
|
|
"capabilities": ["sync", "notifications", "health"],
|
|
"timestamp": 1703001600
|
|
}
|
|
```
|
|
|
|
**Réponse de Handshake :**
|
|
```json
|
|
{
|
|
"type": "handshake_response",
|
|
"status": "accepted",
|
|
"relay_id": "relay-1",
|
|
"version": "1.0.0",
|
|
"capabilities": ["sync", "notifications", "health", "metrics"],
|
|
"timestamp": 1703001600
|
|
}
|
|
```
|
|
|
|
### Messages de Synchronisation
|
|
|
|
#### 1. StateSync
|
|
|
|
**Envoi :**
|
|
```json
|
|
{
|
|
"type": "sync",
|
|
"sync_type": "StateSync",
|
|
"relay_id": "relay-1",
|
|
"payload": {
|
|
"state": {
|
|
"uptime": "3600",
|
|
"version": "1.0.0",
|
|
"network": "signet",
|
|
"status": "healthy",
|
|
"last_block": "12345",
|
|
"connections": 5
|
|
}
|
|
},
|
|
"timestamp": 1703001600,
|
|
"message_id": "msg-123"
|
|
}
|
|
```
|
|
|
|
**Réception :**
|
|
```json
|
|
{
|
|
"type": "sync_response",
|
|
"sync_type": "StateSync",
|
|
"relay_id": "relay-2",
|
|
"payload": {
|
|
"state": {
|
|
"uptime": "1800",
|
|
"version": "1.0.0",
|
|
"network": "signet",
|
|
"status": "healthy",
|
|
"last_block": "12345",
|
|
"connections": 3
|
|
}
|
|
},
|
|
"timestamp": 1703001600,
|
|
"message_id": "msg-124"
|
|
}
|
|
```
|
|
|
|
#### 2. HealthSync
|
|
|
|
**Envoi :**
|
|
```json
|
|
{
|
|
"type": "sync",
|
|
"sync_type": "HealthSync",
|
|
"relay_id": "relay-1",
|
|
"payload": {
|
|
"health": {
|
|
"status": "healthy",
|
|
"memory_usage": "128MB",
|
|
"cpu_usage": "5%",
|
|
"disk_usage": "2GB",
|
|
"network_latency": "45ms"
|
|
}
|
|
},
|
|
"timestamp": 1703001600,
|
|
"message_id": "msg-125"
|
|
}
|
|
```
|
|
|
|
#### 3. MetricsSync
|
|
|
|
**Envoi :**
|
|
```json
|
|
{
|
|
"type": "sync",
|
|
"sync_type": "MetricsSync",
|
|
"relay_id": "relay-1",
|
|
"payload": {
|
|
"metrics": {
|
|
"known_relays": 3,
|
|
"mesh_connections": 6,
|
|
"sync_requests": 150,
|
|
"sync_responses": 150,
|
|
"cache_hits": 120,
|
|
"cache_misses": 30,
|
|
"avg_latency": 45.2,
|
|
"error_count": 0
|
|
}
|
|
},
|
|
"timestamp": 1703001600,
|
|
"message_id": "msg-126"
|
|
}
|
|
```
|
|
|
|
### Messages de Notification
|
|
|
|
#### 1. Payment Detected
|
|
|
|
```json
|
|
{
|
|
"type": "notification",
|
|
"notification_type": "payment_detected",
|
|
"data": {
|
|
"txid": "abc123def456789...",
|
|
"block_height": 12345,
|
|
"block_hash": "def789abc123456...",
|
|
"amount": "0.001",
|
|
"address": "sp1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
|
|
"confirmations": 1,
|
|
"timestamp": 1703001600
|
|
},
|
|
"timestamp": 1703001600
|
|
}
|
|
```
|
|
|
|
#### 2. Block Mined
|
|
|
|
```json
|
|
{
|
|
"type": "notification",
|
|
"notification_type": "block_mined",
|
|
"data": {
|
|
"block_height": 12346,
|
|
"block_hash": "ghi012jkl345678...",
|
|
"transactions": 150,
|
|
"size": "1024000",
|
|
"timestamp": 1703001600
|
|
},
|
|
"timestamp": 1703001600
|
|
}
|
|
```
|
|
|
|
#### 3. Relay Connected
|
|
|
|
```json
|
|
{
|
|
"type": "notification",
|
|
"notification_type": "relay_connected",
|
|
"data": {
|
|
"relay_id": "relay-4",
|
|
"address": "relay-4.example.com:8090",
|
|
"version": "1.0.0",
|
|
"capabilities": ["sync", "notifications"],
|
|
"timestamp": 1703001600
|
|
},
|
|
"timestamp": 1703001600
|
|
}
|
|
```
|
|
|
|
### Messages de Contrôle
|
|
|
|
#### 1. Ping/Pong
|
|
|
|
**Ping :**
|
|
```json
|
|
{
|
|
"type": "ping",
|
|
"client_id": "my-client-123",
|
|
"timestamp": 1703001600
|
|
}
|
|
```
|
|
|
|
**Pong :**
|
|
```json
|
|
{
|
|
"type": "pong",
|
|
"relay_id": "relay-1",
|
|
"timestamp": 1703001600
|
|
}
|
|
```
|
|
|
|
#### 2. Subscribe/Unsubscribe
|
|
|
|
**Subscribe :**
|
|
```json
|
|
{
|
|
"type": "subscribe",
|
|
"subscriptions": ["notifications", "health", "metrics"],
|
|
"client_id": "my-client-123",
|
|
"timestamp": 1703001600
|
|
}
|
|
```
|
|
|
|
**Unsubscribe :**
|
|
```json
|
|
{
|
|
"type": "unsubscribe",
|
|
"subscriptions": ["metrics"],
|
|
"client_id": "my-client-123",
|
|
"timestamp": 1703001600
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## HTTP REST API
|
|
|
|
### Endpoints de Base
|
|
|
|
#### 1. Health Check
|
|
|
|
**GET** `/health`
|
|
|
|
**Description :** Vérifier l'état de santé du service
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"uptime": 3600,
|
|
"version": "1.0.0",
|
|
"timestamp": 1703001600,
|
|
"services": {
|
|
"bitcoin_core": "connected",
|
|
"blindbit": "connected",
|
|
"websocket": "listening",
|
|
"sync_manager": "active"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Codes de réponse :**
|
|
- `200` : Service en bonne santé
|
|
- `503` : Service indisponible
|
|
|
|
#### 2. Métriques
|
|
|
|
**GET** `/metrics`
|
|
|
|
**Description :** Obtenir les métriques de performance
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"sync_metrics": {
|
|
"known_relays": 3,
|
|
"mesh_connections": 6,
|
|
"sync_requests": 150,
|
|
"sync_responses": 150,
|
|
"cache_hits": 120,
|
|
"cache_misses": 30,
|
|
"avg_latency": 45.2,
|
|
"error_count": 0
|
|
},
|
|
"system_metrics": {
|
|
"memory_usage": "128MB",
|
|
"cpu_usage": "5%",
|
|
"active_connections": 10,
|
|
"total_requests": 1000,
|
|
"uptime": 3600
|
|
},
|
|
"bitcoin_metrics": {
|
|
"block_height": 12345,
|
|
"connections": 8,
|
|
"mempool_size": 150,
|
|
"verification_progress": 0.9999
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 3. Configuration
|
|
|
|
**GET** `/config`
|
|
|
|
**Description :** Obtenir la configuration actuelle
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"relay_id": "relay-1",
|
|
"network": "signet",
|
|
"ws_url": "0.0.0.0:8090",
|
|
"http_url": "0.0.0.0:8091",
|
|
"bitcoin_core": {
|
|
"url": "http://bitcoin:18443",
|
|
"wallet": "relay_wallet",
|
|
"zmq_url": "tcp://bitcoin:29000"
|
|
},
|
|
"blindbit": {
|
|
"url": "http://blindbit:8000"
|
|
},
|
|
"sync": {
|
|
"interval": 30,
|
|
"health_interval": 60,
|
|
"metrics_interval": 120
|
|
},
|
|
"dev_mode": true,
|
|
"standalone": false
|
|
}
|
|
```
|
|
|
|
### Endpoints de Gestion des Relais
|
|
|
|
#### 4. Liste des Relais
|
|
|
|
**GET** `/relays`
|
|
|
|
**Description :** Obtenir la liste des relais connus
|
|
|
|
**Paramètres de requête :**
|
|
- `status` : Filtrer par statut (healthy, warning, critical)
|
|
- `limit` : Limiter le nombre de résultats (défaut: 100)
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"relays": [
|
|
{
|
|
"relay_id": "relay-1",
|
|
"address": "sdk_relay_1:8090",
|
|
"version": "1.0.0",
|
|
"uptime": 3600,
|
|
"health": "healthy",
|
|
"last_seen": 1703001600,
|
|
"capabilities": ["sync", "notifications", "health"],
|
|
"connections": 5
|
|
},
|
|
{
|
|
"relay_id": "relay-2",
|
|
"address": "sdk_relay_2:8090",
|
|
"version": "1.0.0",
|
|
"uptime": 1800,
|
|
"health": "healthy",
|
|
"last_seen": 1703001600,
|
|
"capabilities": ["sync", "notifications"],
|
|
"connections": 3
|
|
}
|
|
],
|
|
"total": 2,
|
|
"healthy": 2,
|
|
"warning": 0,
|
|
"critical": 0
|
|
}
|
|
```
|
|
|
|
#### 5. Détails d'un Relais
|
|
|
|
**GET** `/relays/{relay_id}`
|
|
|
|
**Description :** Obtenir les détails d'un relais spécifique
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"relay_id": "relay-1",
|
|
"address": "sdk_relay_1:8090",
|
|
"version": "1.0.0",
|
|
"uptime": 3600,
|
|
"health": "healthy",
|
|
"last_seen": 1703001600,
|
|
"capabilities": ["sync", "notifications", "health"],
|
|
"connections": 5,
|
|
"metrics": {
|
|
"sync_requests": 50,
|
|
"sync_responses": 50,
|
|
"avg_latency": 45.2
|
|
},
|
|
"configuration": {
|
|
"network": "signet",
|
|
"dev_mode": true
|
|
}
|
|
}
|
|
```
|
|
|
|
**Codes de réponse :**
|
|
- `200` : Relais trouvé
|
|
- `404` : Relais non trouvé
|
|
|
|
### Endpoints de Synchronisation
|
|
|
|
#### 6. Statut de Synchronisation
|
|
|
|
**GET** `/sync/status`
|
|
|
|
**Description :** Obtenir le statut de la synchronisation
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"status": "syncing",
|
|
"last_sync": 1703001600,
|
|
"next_sync": 1703001630,
|
|
"sync_types": [
|
|
"StateSync",
|
|
"HealthSync",
|
|
"MetricsSync"
|
|
],
|
|
"errors": [],
|
|
"statistics": {
|
|
"total_syncs": 150,
|
|
"successful_syncs": 148,
|
|
"failed_syncs": 2,
|
|
"success_rate": 98.67
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 7. Forcer la Synchronisation
|
|
|
|
**POST** `/sync/force`
|
|
|
|
**Description :** Forcer une synchronisation immédiate
|
|
|
|
**Corps de la requête :**
|
|
```json
|
|
{
|
|
"sync_types": ["StateSync", "HealthSync"],
|
|
"target_relays": ["relay-2", "relay-3"]
|
|
}
|
|
```
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"status": "sync_triggered",
|
|
"sync_types": ["StateSync", "HealthSync"],
|
|
"target_relays": ["relay-2", "relay-3"],
|
|
"timestamp": 1703001600,
|
|
"estimated_duration": "30s"
|
|
}
|
|
```
|
|
|
|
#### 8. Historique des Synchronisations
|
|
|
|
**GET** `/sync/history`
|
|
|
|
**Description :** Obtenir l'historique des synchronisations
|
|
|
|
**Paramètres de requête :**
|
|
- `limit` : Nombre d'entrées (défaut: 50)
|
|
- `since` : Timestamp de début
|
|
- `until` : Timestamp de fin
|
|
- `sync_type` : Filtrer par type de synchronisation
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"history": [
|
|
{
|
|
"timestamp": 1703001600,
|
|
"sync_type": "StateSync",
|
|
"target_relay": "relay-2",
|
|
"status": "success",
|
|
"duration": 45,
|
|
"message_id": "msg-123"
|
|
},
|
|
{
|
|
"timestamp": 1703001570,
|
|
"sync_type": "HealthSync",
|
|
"target_relay": "relay-3",
|
|
"status": "success",
|
|
"duration": 32,
|
|
"message_id": "msg-122"
|
|
}
|
|
],
|
|
"total": 2,
|
|
"successful": 2,
|
|
"failed": 0
|
|
}
|
|
```
|
|
|
|
### Endpoints de Bitcoin Core
|
|
|
|
#### 9. Informations Bitcoin
|
|
|
|
**GET** `/bitcoin/info`
|
|
|
|
**Description :** Obtenir les informations Bitcoin Core
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"blockchain_info": {
|
|
"chain": "signet",
|
|
"blocks": 12345,
|
|
"headers": 12345,
|
|
"bestblockhash": "abc123...",
|
|
"difficulty": 1.0,
|
|
"verificationprogress": 0.9999,
|
|
"initialblockdownload": false
|
|
},
|
|
"network_info": {
|
|
"connections": 8,
|
|
"connections_in": 4,
|
|
"connections_out": 4
|
|
},
|
|
"mempool_info": {
|
|
"size": 150,
|
|
"bytes": 1024000,
|
|
"usage": 2048000
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 10. Bloc Spécifique
|
|
|
|
**GET** `/bitcoin/blocks/{block_hash}`
|
|
|
|
**Description :** Obtenir les détails d'un bloc
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"hash": "abc123...",
|
|
"height": 12345,
|
|
"version": 536870912,
|
|
"merkleroot": "def456...",
|
|
"time": 1703001600,
|
|
"mediantime": 1703001500,
|
|
"nonce": 123456,
|
|
"bits": "207fffff",
|
|
"difficulty": 1.0,
|
|
"size": 1024,
|
|
"strippedsize": 512,
|
|
"weight": 4096,
|
|
"tx": [
|
|
"txid1...",
|
|
"txid2..."
|
|
]
|
|
}
|
|
```
|
|
|
|
### Endpoints de Logs
|
|
|
|
#### 11. Logs
|
|
|
|
**GET** `/logs`
|
|
|
|
**Description :** Obtenir les logs du service
|
|
|
|
**Paramètres de requête :**
|
|
- `level` : Niveau de log (debug, info, warn, error)
|
|
- `limit` : Nombre de lignes (défaut: 100)
|
|
- `since` : Timestamp de début
|
|
- `search` : Recherche dans les logs
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"logs": [
|
|
{
|
|
"timestamp": "2024-12-19T10:00:00Z",
|
|
"level": "info",
|
|
"message": "Relay started successfully",
|
|
"relay_id": "relay-1"
|
|
},
|
|
{
|
|
"timestamp": "2024-12-19T10:00:30Z",
|
|
"level": "info",
|
|
"message": "Sync completed",
|
|
"relay_id": "relay-1",
|
|
"sync_type": "StateSync"
|
|
}
|
|
],
|
|
"total": 2,
|
|
"levels": {
|
|
"debug": 0,
|
|
"info": 2,
|
|
"warn": 0,
|
|
"error": 0
|
|
}
|
|
}
|
|
```
|
|
|
|
### Endpoints de Configuration
|
|
|
|
#### 12. Mettre à Jour la Configuration
|
|
|
|
**PUT** `/config`
|
|
|
|
**Description :** Mettre à jour la configuration
|
|
|
|
**Corps de la requête :**
|
|
```json
|
|
{
|
|
"sync": {
|
|
"interval": 60,
|
|
"health_interval": 120
|
|
},
|
|
"dev_mode": false
|
|
}
|
|
```
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"status": "updated",
|
|
"changes": [
|
|
"sync.interval: 30 -> 60",
|
|
"sync.health_interval: 60 -> 120",
|
|
"dev_mode: true -> false"
|
|
],
|
|
"timestamp": 1703001600
|
|
}
|
|
```
|
|
|
|
#### 13. Redémarrer le Service
|
|
|
|
**POST** `/restart`
|
|
|
|
**Description :** Redémarrer le service
|
|
|
|
**Réponse :**
|
|
```json
|
|
{
|
|
"status": "restarting",
|
|
"timestamp": 1703001600,
|
|
"estimated_duration": "30s"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Codes d'Erreur
|
|
|
|
### WebSocket
|
|
- `1000` : Fermeture normale
|
|
- `1001` : Client part
|
|
- `1002` : Erreur de protocole
|
|
- `1003` : Type de données non supporté
|
|
- `1006` : Connexion fermée anormalement
|
|
- `1011` : Erreur serveur
|
|
|
|
### HTTP
|
|
- `200` : Succès
|
|
- `400` : Requête invalide
|
|
- `401` : Non autorisé
|
|
- `404` : Endpoint non trouvé
|
|
- `422` : Données invalides
|
|
- `429` : Trop de requêtes
|
|
- `500` : Erreur serveur interne
|
|
- `503` : Service indisponible
|
|
|
|
---
|
|
|
|
## Exemples d'Utilisation
|
|
|
|
### Client JavaScript Complet
|
|
|
|
```javascript
|
|
class SdkRelayClient {
|
|
constructor(wsUrl, httpUrl) {
|
|
this.wsUrl = wsUrl;
|
|
this.httpUrl = httpUrl;
|
|
this.ws = null;
|
|
this.clientId = `client-${Date.now()}`;
|
|
}
|
|
|
|
async connect() {
|
|
return new Promise((resolve, reject) => {
|
|
this.ws = new WebSocket(this.wsUrl);
|
|
|
|
this.ws.onopen = () => {
|
|
console.log('Connecté à sdk_relay');
|
|
this.sendHandshake();
|
|
resolve();
|
|
};
|
|
|
|
this.ws.onmessage = (event) => {
|
|
const message = JSON.parse(event.data);
|
|
this.handleMessage(message);
|
|
};
|
|
|
|
this.ws.onerror = (error) => {
|
|
console.error('Erreur WebSocket:', error);
|
|
reject(error);
|
|
};
|
|
});
|
|
}
|
|
|
|
sendHandshake() {
|
|
const handshake = {
|
|
type: 'handshake',
|
|
client_id: this.clientId,
|
|
version: '1.0.0',
|
|
capabilities: ['sync', 'notifications', 'health']
|
|
};
|
|
this.ws.send(JSON.stringify(handshake));
|
|
}
|
|
|
|
handleMessage(message) {
|
|
switch(message.type) {
|
|
case 'handshake_response':
|
|
console.log('Handshake accepté');
|
|
break;
|
|
case 'notification':
|
|
this.handleNotification(message);
|
|
break;
|
|
case 'sync':
|
|
this.handleSync(message);
|
|
break;
|
|
case 'pong':
|
|
console.log('Pong reçu');
|
|
break;
|
|
}
|
|
}
|
|
|
|
handleNotification(message) {
|
|
console.log('Notification:', message.notification_type, message.data);
|
|
}
|
|
|
|
handleSync(message) {
|
|
console.log('Sync:', message.sync_type, message.payload);
|
|
}
|
|
|
|
// Méthodes HTTP
|
|
async getHealth() {
|
|
const response = await fetch(`${this.httpUrl}/health`);
|
|
return response.json();
|
|
}
|
|
|
|
async getMetrics() {
|
|
const response = await fetch(`${this.httpUrl}/metrics`);
|
|
return response.json();
|
|
}
|
|
|
|
async getRelays() {
|
|
const response = await fetch(`${this.httpUrl}/relays`);
|
|
return response.json();
|
|
}
|
|
|
|
async forceSync(syncTypes = ['StateSync']) {
|
|
const response = await fetch(`${this.httpUrl}/sync/force`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ sync_types: syncTypes })
|
|
});
|
|
return response.json();
|
|
}
|
|
|
|
disconnect() {
|
|
if (this.ws) {
|
|
this.ws.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Utilisation
|
|
const client = new SdkRelayClient('ws://localhost:8090', 'http://localhost:8091');
|
|
|
|
async function main() {
|
|
await client.connect();
|
|
|
|
// Obtenir les métriques
|
|
const metrics = await client.getMetrics();
|
|
console.log('Métriques:', metrics);
|
|
|
|
// Forcer une synchronisation
|
|
await client.forceSync(['HealthSync']);
|
|
}
|
|
|
|
main().catch(console.error);
|
|
```
|
|
|
|
### Client Python Complet
|
|
|
|
```python
|
|
import asyncio
|
|
import aiohttp
|
|
import json
|
|
import websockets
|
|
from datetime import datetime
|
|
|
|
class SdkRelayClient:
|
|
def __init__(self, ws_url, http_url):
|
|
self.ws_url = ws_url
|
|
self.http_url = http_url
|
|
self.websocket = None
|
|
self.client_id = f"python-client-{int(datetime.now().timestamp())}"
|
|
|
|
async def connect(self):
|
|
self.websocket = await websockets.connect(self.ws_url)
|
|
await self.send_handshake()
|
|
|
|
async def send_handshake(self):
|
|
handshake = {
|
|
"type": "handshake",
|
|
"client_id": self.client_id,
|
|
"version": "1.0.0",
|
|
"capabilities": ["sync", "notifications", "health"]
|
|
}
|
|
await self.websocket.send(json.dumps(handshake))
|
|
|
|
async def listen(self):
|
|
async for message in self.websocket:
|
|
data = json.loads(message)
|
|
await self.handle_message(data)
|
|
|
|
async def handle_message(self, message):
|
|
if message['type'] == 'handshake_response':
|
|
print(f"Handshake accepté par {message['relay_id']}")
|
|
elif message['type'] == 'notification':
|
|
await self.handle_notification(message)
|
|
elif message['type'] == 'sync':
|
|
await self.handle_sync(message)
|
|
|
|
async def handle_notification(self, message):
|
|
print(f"Notification {message['notification_type']}: {message['data']}")
|
|
|
|
async def handle_sync(self, message):
|
|
print(f"Sync {message['sync_type']}: {message['payload']}")
|
|
|
|
# Méthodes HTTP
|
|
async def get_health(self):
|
|
async with aiohttp.ClientSession() as session:
|
|
async with session.get(f"{self.http_url}/health") as response:
|
|
return await response.json()
|
|
|
|
async def get_metrics(self):
|
|
async with aiohttp.ClientSession() as session:
|
|
async with session.get(f"{self.http_url}/metrics") as response:
|
|
return await response.json()
|
|
|
|
async def get_relays(self):
|
|
async with aiohttp.ClientSession() as session:
|
|
async with session.get(f"{self.http_url}/relays") as response:
|
|
return await response.json()
|
|
|
|
async def force_sync(self, sync_types=None):
|
|
if sync_types is None:
|
|
sync_types = ['StateSync']
|
|
|
|
async with aiohttp.ClientSession() as session:
|
|
async with session.post(
|
|
f"{self.http_url}/sync/force",
|
|
json={"sync_types": sync_types}
|
|
) as response:
|
|
return await response.json()
|
|
|
|
async def close(self):
|
|
if self.websocket:
|
|
await self.websocket.close()
|
|
|
|
async def main():
|
|
client = SdkRelayClient('ws://localhost:8090', 'http://localhost:8091')
|
|
|
|
try:
|
|
await client.connect()
|
|
|
|
# Obtenir les métriques
|
|
metrics = await client.get_metrics()
|
|
print("Métriques:", metrics)
|
|
|
|
# Écouter les messages
|
|
await client.listen()
|
|
|
|
except Exception as e:
|
|
print(f"Erreur: {e}")
|
|
finally:
|
|
await client.close()
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|
|
```
|
|
|
|
### Client cURL
|
|
|
|
```bash
|
|
# Vérifier la santé
|
|
curl -X GET http://localhost:8091/health
|
|
|
|
# Obtenir les métriques
|
|
curl -X GET http://localhost:8091/metrics
|
|
|
|
# Obtenir la liste des relais
|
|
curl -X GET http://localhost:8091/relays
|
|
|
|
# Obtenir les détails d'un relais
|
|
curl -X GET http://localhost:8091/relays/relay-1
|
|
|
|
# Forcer une synchronisation
|
|
curl -X POST http://localhost:8091/sync/force \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"sync_types": ["StateSync", "HealthSync"]}'
|
|
|
|
# Obtenir l'historique des synchronisations
|
|
curl -X GET "http://localhost:8091/sync/history?limit=10"
|
|
|
|
# Obtenir les logs
|
|
curl -X GET "http://localhost:8091/logs?level=info&limit=50"
|
|
|
|
# Obtenir les informations Bitcoin
|
|
curl -X GET http://localhost:8091/bitcoin/info
|
|
|
|
# Obtenir un bloc spécifique
|
|
curl -X GET http://localhost:8091/bitcoin/blocks/abc123...
|
|
|
|
# Mettre à jour la configuration
|
|
curl -X PUT http://localhost:8091/config \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"sync": {"interval": 60}}'
|
|
|
|
# Redémarrer le service
|
|
curl -X POST http://localhost:8091/restart
|
|
```
|
|
|
|
---
|
|
|
|
## Limites et Quotas
|
|
|
|
### WebSocket
|
|
- **Connexions simultanées** : 1000 par relais
|
|
- **Taille des messages** : 1MB maximum
|
|
- **Heartbeat** : 30 secondes
|
|
- **Timeout de connexion** : 60 secondes
|
|
- **Rate limiting** : 1000 messages/minute par client
|
|
|
|
### HTTP REST
|
|
- **Taux limite** : 1000 requêtes/minute par IP
|
|
- **Taille des requêtes** : 10MB maximum
|
|
- **Timeout** : 30 secondes
|
|
- **Connexions simultanées** : 100 par IP
|
|
- **Rate limiting** : 100 requêtes/minute par endpoint
|
|
|
|
---
|
|
|
|
## Sécurité
|
|
|
|
### Authentification
|
|
- **WebSocket** : Authentification optionnelle via handshake
|
|
- **HTTP** : Authentification basique (à configurer)
|
|
- **Rate limiting** : Protection contre les abus
|
|
|
|
### Validation
|
|
- Validation JSON des messages
|
|
- Validation des types de données
|
|
- Protection contre les injections
|
|
- Validation des URLs et paramètres
|
|
|
|
### Chiffrement
|
|
- **WebSocket** : WSS (WebSocket Secure) recommandé
|
|
- **HTTP** : HTTPS recommandé
|
|
- **Certificats** : Certificats SSL/TLS valides
|
|
|
|
---
|
|
|
|
## Monitoring
|
|
|
|
### Métriques Clés
|
|
- **Latence** : Temps de réponse des APIs
|
|
- **Débit** : Messages/requêtes par seconde
|
|
- **Erreurs** : Taux d'erreur par endpoint
|
|
- **Connexions** : Nombre de connexions actives
|
|
- **Synchronisation** : Taux de succès des syncs
|
|
|
|
### Alertes
|
|
- Service indisponible
|
|
- Latence élevée (> 1s)
|
|
- Taux d'erreur élevé (> 5%)
|
|
- Mémoire/CPU élevés
|
|
- Échecs de synchronisation
|
|
|
|
---
|
|
|
|
**Cette API permet une intégration complète et professionnelle avec sdk_relay pour tous types de clients.** 🚀
|