20 KiB
Référence API — sdk_client
Ce document spécifie les interfaces publiques du module sdk_client
exposées aux consommateurs via WebAssembly et, de manière secondaire, via l’API Rust. Il décrit le périmètre fonctionnel, les structures de données échangées, les erreurs et les invariants, sans inclure d’exemples exécutables.
Portée
- Cible: bibliothèque cliente pour Silent Payments, intégrée côté navigateur ou environnement compatible WASM.
- Interfaces: fonctions exportées via
wasm_bindgen
et types sérialisables viatsify
/serde
. - Hors périmètre: APIs d’infrastructure (RPC Bitcoin, services HTTP, WebSocket relais) qui relèvent d’autres composants.
Interfaces
- Interface WASM: fonctions exportées pour un usage JavaScript/TypeScript. Les types transitent en JSON/JsValue selon
tsify
etserde_wasm_bindgen
. - Interface Rust: accès direct aux mêmes primitives lorsqu’intégré en Rust natif. Cette intégration suit les mêmes contrats mais n’est pas l’interface principale.
Domaines fonctionnels et fonctions exportées
Les fonctions suivantes sont regroupées par domaine. Sauf mention contraire, les fonctions retournent soit un type de résultat propre (ApiResult<T>
), soit des structures sérialisables définies ci‑dessous.
1) Gestion d’appareil et portefeuille
- setup
- create_new_device(birthday, network)
- create_device_from_sp_wallet(sp_wallet_json)
- restore_device(device)
- dump_device / dump_neutered_device
- reset_device
- dump_wallet
- get_address
- get_member
- is_paired
- pair_device(process_id, sp_addresses)
- unpair_device
Pré‑requis usuels: certaines opérations nécessitent un appareil initialisé et/ou appairé.
2) Cache de processus et état local
- reset_process_cache
- dump_process_cache / set_process_cache / add_to_process_cache
- get_pairing_process_id
Invariants: le cache en mémoire ne doit pas être écrasé s’il contient déjà des données actives.
3) Transactions et fonds
- get_txid(transaction_hex)
- get_outputs
- get_available_amount
- create_transaction(addresses, fee_rate)
- sign_transaction(partial_tx)
Notes: la création de transaction déduit des UTXOs disponibles et peut marquer certains UTXOs comme dépensés (prévention d’un double‑spend local pendant la signature/envoi).
4) Détection et traitement d’événements réseau
- parse_new_tx(new_tx_message, block_height, members_list)
- parse_cipher(cipher_message, members_list)
Comportements principaux: création/actualisation de processus, génération de diffs utilisateurs, collecte de secrets partagés et préparation d’artefacts à persister et/ou à transmettre.
5) Processus, états et échanges PRD
- create_new_process(private_data, roles, public_data, relay_address, fee_rate, members_list)
- update_process(process, new_attributes, roles, new_public_data, members_list)
- evaluate_state(process, state_id, members_list)
- validate_state(process, state_id, members_list)
- refuse_state(process, state_id, members_list)
- create_update_message(process, state_id, members_list)
- create_response_prd(process, state_id, members_list)
- request_data(process_id, state_ids, roles, members_list)
Garantie fonctionnelle: les rôles et règles de validation associés aux états déterminent les champs visibles/validables par chaque membre.
6) Chiffrement, preuves et utilitaires
- reset_shared_secrets / set_shared_secrets
- create_faucet_msg
- get_storages(process_outpoint)
- is_child_role(parent_roles, child_roles)
- decrypt_data(key, data)
- encode_binary / encode_json / decode_value
- hash_value(value, commited_in, label)
- get_merkle_proof(process_state, attribute_name)
- validate_merkle_proof(proof_result, hash)
Contraintes: tailles maximales de messages, formats hexadécimaux pour les preuves et empreintes, et cohérence des clés/indices de Merkle.
Structures de données principales
Les noms de champs listés ci‑dessous sont fournis à titre de référence contractuelle. Le format concret dépend de la sérialisation (serde
) et du passage de frontières WASM.
- ApiReturn: regroupe les retours multi‑canaux (secrets mis à jour, processus à persister, messages à diffuser, transactions partielles, etc.).
- ApiError: erreur normalisée (conversion depuis diverses erreurs internes, notamment de parsing, cryptographie, hex, PSBT, etc.).
- DiffStatus: indicateur d’état d’un diff (None/Rejected/Validated).
- UserDiff: proposition d’évolution d’attribut (process_id, state_id, valeur engagée, champ, rôles, besoin de validation, notification, statut de validation).
- UpdatedProcess: cliché de processus actualisé (process_id, état courant, diffs, données chiffrées, éventuel state validé).
- MerkleProofResult: résultat de preuve Merkle (preuve, racine, attribut, index, nombre total de feuilles).
Les types membres, rôles, clés, engagements PCD et transactions s’appuient sur sdk_common
(Silent Payments, PSBT, Merkle, signature, etc.).
Erreurs et gestion des échecs
- Normalisation:
ApiError
unifie les erreurs en surface (parsing JSON/hex, erreurs réseau/cryptographie, formats PSBT, conversions sérielles WASM, etc.). - Messages: volontairement explicites et destinés au diagnostic applicatif, sans fuite d’éléments secrets.
- Bonnes pratiques: valider en amont formats, tailles et pré‑requis (appareil initialisé/appairé, états existants, rôles cohérents).
Invariants et contrats
- Appairage: requis pour certaines opérations (validation d’état, envoi de réponses, filtrage de champs par rôle).
- Secrets partagés: stockés et confirmés par adresse; jamais exposés en clair au consommateur.
- États de processus: identifiés par racine Merkle; les preuves et validations manipulent exclusivement des engagements.
- Tailles: les charges utiles et messages sont bornés pour éviter abus et sur‑consommation mémoire côté WASM.
Limitations actuelles et compatibilité
- Réseau de test: certaines constantes sont orientées test (ex. réseau par défaut, montants par défaut). Adapter côté intégration selon les besoins.
- Environnement: l’interface prioritaire est WASM (navigateurs/JS runtimes compatibles). L’API Rust est de niveau bibliothèque.
Traçabilité documentaire
- Toute évolution de signature ou d’invariant doit être répercutée ici et dans
docs/ARCHITECTURE.md
. - Les impacts sur les parcours doivent être décrits dans
docs/USAGE.md
. - Les risques/contrôles associés doivent être référencés dans
docs/SECURITY_AUDIT.md
.
1. API Bitcoin Core RPC
Informations Générales
- Protocole : JSON-RPC
- Port : 18443
- Authentification : Cookie ou credentials
- Réseau : Signet
- Base URL :
http://localhost:18443
Authentification
Méthode Cookie (Recommandée)
# Le cookie est automatiquement utilisé par Bitcoin Core
curl -X POST http://localhost:18443 \
-H "Content-Type: application/json" \
--data '{"jsonrpc": "1.0", "id": "test", "method": "getblockchaininfo", "params": []}'
Méthode Credentials
curl -X POST http://localhost:18443 \
-H "Content-Type: application/json" \
-u "username:password" \
--data '{"jsonrpc": "1.0", "id": "test", "method": "getblockchaininfo", "params": []}'
Endpoints Principaux
getblockchaininfo
Récupère les informations sur la blockchain.
Requête :
{
"jsonrpc": "1.0",
"id": "test",
"method": "getblockchaininfo",
"params": []
}
Réponse :
{
"result": {
"chain": "signet",
"blocks": 12345,
"headers": 12345,
"bestblockhash": "0000000000000000000000000000000000000000000000000000000000000000",
"difficulty": 1.0,
"mediantime": 1234567890,
"verificationprogress": 1.0,
"initialblockdownload": false,
"chainwork": "0000000000000000000000000000000000000000000000000000000000000000",
"size_on_disk": 123456789,
"pruned": false,
"pruneheight": null,
"automatic_pruning": false,
"prune_target_size": null,
"warnings": ""
},
"error": null,
"id": "test"
}
getblock
Récupère les informations d'un bloc spécifique.
Requête :
{
"jsonrpc": "1.0",
"id": "test",
"method": "getblock",
"params": ["blockhash", 2]
}
Paramètres :
blockhash
: Hash du blocverbosity
: Niveau de détail (0, 1, 2)
getrawtransaction
Récupère une transaction brute.
Requête :
{
"jsonrpc": "1.0",
"id": "test",
"method": "getrawtransaction",
"params": ["txid", true]
}
sendrawtransaction
Envoie une transaction brute au réseau.
Requête :
{
"jsonrpc": "1.0",
"id": "test",
"method": "sendrawtransaction",
"params": ["hexstring"]
}
getwalletinfo
Récupère les informations du wallet.
Requête :
{
"jsonrpc": "1.0",
"id": "test",
"method": "getwalletinfo",
"params": []
}
Gestion des Erreurs
Erreur typique :
{
"result": null,
"error": {
"code": -32601,
"message": "Method not found"
},
"id": "test"
}
Codes d'erreur courants :
-32601
: Méthode non trouvée-32602
: Paramètres invalides-32603
: Erreur interne-1
: Erreur d'authentification
2. API Blindbit HTTP
Informations Générales
- Protocole : HTTP REST
- Port : 8000
- Base URL :
http://localhost:8000
- Content-Type :
application/json
Endpoints
GET /health
Vérifie la santé du service.
Requête :
curl -X GET http://localhost:8000/health
Réponse :
{
"status": "healthy",
"timestamp": "2024-12-19T14:30:00Z",
"version": "1.0.0"
}
POST /generate-address
Génère une adresse de paiement silencieux.
Requête :
{
"label": "payment_001",
"amount": 0.001
}
Réponse :
{
"address": "bc1p...",
"label": "payment_001",
"amount": 0.001,
"created_at": "2024-12-19T14:30:00Z"
}
GET /payments
Liste les paiements reçus.
Requête :
curl -X GET "http://localhost:8000/payments?limit=10&offset=0"
Paramètres de requête :
limit
: Nombre maximum de résultats (défaut: 10)offset
: Décalage pour la pagination (défaut: 0)
Réponse :
{
"payments": [
{
"id": "payment_001",
"address": "bc1p...",
"amount": 0.001,
"txid": "txid...",
"block_height": 12345,
"created_at": "2024-12-19T14:30:00Z"
}
],
"total": 1,
"limit": 10,
"offset": 0
}
GET /payments/{id}
Récupère les détails d'un paiement spécifique.
Requête :
curl -X GET http://localhost:8000/payments/payment_001
Réponse :
{
"id": "payment_001",
"address": "bc1p...",
"amount": 0.001,
"txid": "txid...",
"block_height": 12345,
"confirmations": 6,
"created_at": "2024-12-19T14:30:00Z",
"status": "confirmed"
}
Codes de Statut HTTP
200
: Succès201
: Créé400
: Requête invalide404
: Ressource non trouvée500
: Erreur serveur
3. API SDK Relay WebSocket
Informations Générales
- Protocole : WebSocket/WSS
- Port : 8090
- URL :
ws://localhost:8090
ouwss://localhost:8090
- Format : JSON
Connexion
const ws = new WebSocket('ws://localhost:8090');
ws.onopen = function() {
console.log('Connexion WebSocket établie');
};
ws.onmessage = function(event) {
const message = JSON.parse(event.data);
console.log('Message reçu:', message);
};
ws.onerror = function(error) {
console.error('Erreur WebSocket:', error);
};
ws.onclose = function() {
console.log('Connexion WebSocket fermée');
};
Format des Messages
Tous les messages suivent le format JSON suivant :
{
"type": "message_type",
"id": "unique_message_id",
"timestamp": 1234567890,
"data": {
// Données spécifiques au type de message
}
}
Types de Messages
Messages de Synchronisation
StateSync :
{
"type": "StateSync",
"id": "state_001",
"timestamp": 1234567890,
"data": {
"relay_id": "relay-1",
"state": "running",
"version": "1.0.0",
"uptime": 3600
}
}
HealthSync :
{
"type": "HealthSync",
"id": "health_001",
"timestamp": 1234567890,
"data": {
"relay_id": "relay-1",
"status": "healthy",
"uptime": 3600,
"cpu_usage": 15.5,
"memory_usage": 45.2
}
}
MetricsSync :
{
"type": "MetricsSync",
"id": "metrics_001",
"timestamp": 1234567890,
"data": {
"relay_id": "relay-1",
"messages_sent": 1000,
"messages_received": 950,
"sync_errors": 5,
"connected_relays": 3
}
}
Messages de Transaction
TransactionReceived :
{
"type": "TransactionReceived",
"id": "tx_001",
"timestamp": 1234567890,
"data": {
"txid": "txid...",
"amount": 0.001,
"address": "bc1p...",
"block_height": 12345,
"confirmations": 1
}
}
BlockScanned :
{
"type": "BlockScanned",
"id": "block_001",
"timestamp": 1234567890,
"data": {
"block_height": 12345,
"block_hash": "hash...",
"transactions_count": 150,
"silent_payments_found": 2
}
}
Commandes Client
Ping
{
"type": "ping",
"id": "ping_001",
"timestamp": 1234567890,
"data": {}
}
Réponse :
{
"type": "pong",
"id": "ping_001",
"timestamp": 1234567890,
"data": {
"relay_id": "relay-1"
}
}
GetStatus
{
"type": "get_status",
"id": "status_001",
"timestamp": 1234567890,
"data": {}
}
Réponse :
{
"type": "status",
"id": "status_001",
"timestamp": 1234567890,
"data": {
"relay_id": "relay-1",
"status": "running",
"uptime": 3600,
"connected_relays": 3,
"last_block_height": 12345
}
}
4. API SDK Relay HTTP
Informations Générales
- Protocole : HTTP REST
- Port : 8091
- Base URL :
http://localhost:8091
- Content-Type :
application/json
Endpoints
GET /health
Vérifie la santé du relais.
Requête :
curl -X GET http://localhost:8091/health
Réponse :
{
"status": "healthy",
"relay_id": "relay-1",
"uptime": 3600,
"version": "1.0.0",
"connected_relays": 3
}
GET /status
Récupère le statut détaillé du relais.
Requête :
curl -X GET http://localhost:8091/status
Réponse :
{
"relay_id": "relay-1",
"status": "running",
"uptime": 3600,
"version": "1.0.0",
"connected_relays": 3,
"last_block_height": 12345,
"sync_metrics": {
"messages_sent": 1000,
"messages_received": 950,
"sync_errors": 5
}
}
GET /relays
Liste les relais connectés.
Requête :
curl -X GET http://localhost:8091/relays
Réponse :
{
"relays": [
{
"relay_id": "relay-2",
"address": "sdk_relay_2:8090",
"status": "connected",
"connected_since": 1234567890,
"last_heartbeat": 1234567890
},
{
"relay_id": "relay-3",
"address": "sdk_relay_3:8090",
"status": "connected",
"connected_since": 1234567890,
"last_heartbeat": 1234567890
}
]
}
GET /metrics
Récupère les métriques de synchronisation.
Requête :
curl -X GET http://localhost:8091/metrics
Réponse :
{
"messages_sent": 1000,
"messages_received": 950,
"sync_errors": 5,
"last_sync_timestamp": 1234567890,
"connected_relays": 3,
"mesh_health": 0.95
}
POST /sync
Force une synchronisation manuelle.
Requête :
{
"sync_type": "StateSync",
"target_relay": "relay-2"
}
Réponse :
{
"success": true,
"message": "Synchronisation initiée",
"sync_id": "sync_001"
}
5. Gestion des Erreurs
Erreurs WebSocket
Erreur de connexion :
{
"type": "error",
"id": "error_001",
"timestamp": 1234567890,
"data": {
"code": "CONNECTION_ERROR",
"message": "Impossible de se connecter au relais",
"details": "Connection refused"
}
}
Erreur de message :
{
"type": "error",
"id": "error_002",
"timestamp": 1234567890,
"data": {
"code": "INVALID_MESSAGE",
"message": "Format de message invalide",
"details": "Missing required field 'type'"
}
}
Erreurs HTTP
Erreur 400 :
{
"error": {
"code": "INVALID_REQUEST",
"message": "Requête invalide",
"details": "Missing required parameter 'relay_id'"
}
}
Erreur 500 :
{
"error": {
"code": "INTERNAL_ERROR",
"message": "Erreur interne du serveur",
"details": "Database connection failed"
}
}
6. Exemples d'Utilisation
Exemple Python - WebSocket
import asyncio
import websockets
import json
async def connect_to_relay():
uri = "ws://localhost:8090"
async with websockets.connect(uri) as websocket:
# Envoyer un ping
ping_message = {
"type": "ping",
"id": "ping_001",
"timestamp": int(time.time()),
"data": {}
}
await websocket.send(json.dumps(ping_message))
# Écouter les messages
async for message in websocket:
data = json.loads(message)
print(f"Message reçu: {data}")
asyncio.run(connect_to_relay())
Exemple JavaScript - WebSocket
const ws = new WebSocket('ws://localhost:8090');
ws.onopen = function() {
// Envoyer un ping
const pingMessage = {
type: 'ping',
id: 'ping_001',
timestamp: Date.now(),
data: {}
};
ws.send(JSON.stringify(pingMessage));
};
ws.onmessage = function(event) {
const message = JSON.parse(event.data);
console.log('Message reçu:', message);
};
Exemple cURL - Bitcoin Core RPC
# Récupérer les informations de la blockchain
curl -X POST http://localhost:18443 \
-H "Content-Type: application/json" \
--data '{
"jsonrpc": "1.0",
"id": "test",
"method": "getblockchaininfo",
"params": []
}'
# Récupérer un bloc spécifique
curl -X POST http://localhost:18443 \
-H "Content-Type: application/json" \
--data '{
"jsonrpc": "1.0",
"id": "test",
"method": "getblock",
"params": ["blockhash", 2]
}'
7. Limites et Quotas
Bitcoin Core RPC
- Taux limite : 1000 requêtes/minute par défaut
- Taille des requêtes : 32MB maximum
- Connexions simultanées : 125 par défaut
Blindbit HTTP
- Taux limite : 100 requêtes/minute
- Taille des requêtes : 10MB maximum
- Connexions simultanées : 50
SDK Relay WebSocket
- Connexions simultanées : 1000 par relais
- Taille des messages : 1MB maximum
- Heartbeat : 30 secondes
SDK Relay HTTP
- Taux limite : 200 requêtes/minute
- Taille des requêtes : 5MB maximum
- Connexions simultanées : 100
8. Sécurité
Authentification
- Bitcoin Core : Cookie d'authentification
- Blindbit : À définir selon les besoins
- SDK Relay : Authentification WebSocket (optionnelle)
Chiffrement
- RPC Bitcoin : HTTP (non chiffré en local)
- HTTP Blindbit : HTTP (non chiffré en local)
- WebSocket SDK Relay : WSS (chiffré)
Bonnes Pratiques
- Utiliser HTTPS/WSS en production
- Implémenter l'authentification appropriée
- Valider toutes les entrées
- Limiter les taux de requêtes
- Monitorer les accès
9. Monitoring et Observabilité
Métriques à Surveiller
- Latence des APIs : Temps de réponse
- Taux d'erreur : Pourcentage d'erreurs
- Débit : Requêtes par seconde
- Utilisation des ressources : CPU, mémoire, réseau
Logs
- Logs d'accès : Requêtes et réponses
- Logs d'erreur : Erreurs et exceptions
- Logs de performance : Métriques de performance
Alertes
- Erreurs 5xx : Erreurs serveur
- Latence élevée : Temps de réponse > 1s
- Taux d'erreur élevé : > 5%
- Services indisponibles : Health checks en échec