**Motivations:** - Corriger erreur syntaxe double déclaration const now dans bitcoin-rpc.js - Scripts batch en .mjs (ES modules) sans dépendance dotenv - /api/utxo/count doit accepter catégorie ancrages (pluriel) du fichier **Root causes:** - const now déclaré deux fois dans même portée (lignes 294 et 299) - Scripts utilisent dotenv non installé globalement - /api/utxo/count cherchait seulement 'anchor' mais fichier utilise 'ancrages' **Correctifs:** - Supprimer deuxième déclaration const now (ligne 299) - Scripts .mjs : parser .env manuellement sans dotenv - /api/utxo/count : accepter 'anchor' OU 'ancrages' **Evolutions:** - Aucune **Pages affectées:** - signet-dashboard/src/bitcoin-rpc.js - signet-dashboard/src/server.js - scripts/complete-utxo-list-blocktime.mjs - scripts/diagnose-bloc-rewards.mjs
4.7 KiB
4.7 KiB
Stockage des données - UserWallet
Author: Équipe 4NK Date: 2026-01-26
Synthèse
- Relais (api-relay) : Stockage hybride (mémoire +
./data/messages.json). Messages,seenHashes, signatures et clés persistés. Sauvegarde à l’arrêt (SIGINT/SIGTERM) et périodique (configurable viaSAVE_INTERVAL_SECONDS). - Front (userwallet) : LocalStorage (
userwallet_identity,userwallet_relays,userwallet_pairs,userwallet_hash_cache; legacy :userwallet_keypair,userwallet_services). Graphe contractuel en mémoire uniquement (GraphResolver).
Stockage sur le relais (api-relay)
Architecture
Le relais utilise un stockage hybride : mémoire + persistance sur disque.
Structure de stockage
En mémoire :
messages: Map<string, StoredMessage>- Messages chiffrés indexés par hashsignatures: Map<string, StoredSignature[]>- Signatures indexées par hash de messagekeys: Map<string, StoredKey[]>- Clés de déchiffrement indexées par hash de messageseenHashes: Set<string>- Hash vus pour déduplication
Sur disque :
- Fichier
{STORAGE_PATH}/messages.jsoncontenant :messages: Array de[hash, StoredMessage]seenHashes: Array de hash (string[])signatures: Array de[hash, StoredSignature[]]keys: Array de[hash, StoredKey[]]
Persistance
- Chargement : Au démarrage, charge
messages.jsonsi présent (ENOENT = premier run, démarrage à vide). - Sauvegarde : À l’arrêt (SIGINT/SIGTERM) et périodiquement si
SAVE_INTERVAL_SECONDS> 0 (défaut 300 s).
Format de données
StoredMessage :
{
msg: {
hash: string,
message_chiffre: string,
datajson_public: {
services_uuid: string[],
types_uuid: string[],
timestamp?: number,
...
}
},
received_at: number,
relayed: boolean
}
StoredSignature :
{
msg: {
signature: {
hash: string,
cle_publique: string,
signature: string,
nonce: string,
materiel?: object
},
hash_cible?: string
},
received_at: number,
relayed: boolean
}
StoredKey :
{
msg: {
hash_message: string,
cle_de_chiffrement_message: {
algo: string,
params: object,
cle_chiffree?: string
},
df_ecdh_scannable: string
},
received_at: number,
relayed: boolean
}
Configuration
STORAGE_PATH: Chemin du répertoire de stockage (défaut:./data)SAVE_INTERVAL_SECONDS: Intervalle de sauvegarde périodique en secondes (défaut: 300). Mettre à 0 pour désactiver.
Limitations actuelles
- Pas de base de données (SQLite/PostgreSQL recommandé en production)
- Pas de compression des données
Stockage sur le front (userwallet)
Architecture
Le front utilise LocalStorage du navigateur pour toutes les données locales.
Structure de stockage
Clés utilisées :
-
userwallet_identity: Identité locale{ uuid: string, privateKey: string, publicKey: string, name?: string, t0_anniversaire: number, version: string } -
userwallet_relays: Configuration des relaisArray<{ endpoint: string, priority: number, enabled: boolean, last_sync?: number }> -
userwallet_pairs: Configuration des pairsArray<{ uuid: string, membres_parents_uuid: string[], is_local: boolean, can_sign: boolean }> -
userwallet_hash_cache: Cache des hash vusstring[] // Array de hash -
userwallet_keypair: (Legacy) Paire de clés -
userwallet_services: (Legacy) Services configurés
Données en mémoire (non persistées)
- Graphe contractuel : Résolu dynamiquement depuis les messages synchronisés
- Services, Contrats, Champs, Actions, Membres, Pairs
- Stocké dans
GraphResolver.cache(Map) - Perdu au rechargement de page
Limitations
- Taille limitée : LocalStorage a une limite (~5-10MB selon navigateur)
- Pas de synchronisation : Données locales uniquement
- Sécurité : Clés privées stockées en clair (à chiffrer avec mot de passe)
Export / Import
- Export : Écran « Export / Import données » (
/data). Télécharge un JSON (identité, relais, pairs, hash_cache, keypair, services). - Import : Même écran, bouton « Choisir un fichier ». Remplace les données locales puis recharge la page.
Recommandations
- Chiffrer les clés privées avec un mot de passe utilisateur
- Utiliser IndexedDB pour des données plus volumineuses
- Implémenter une synchronisation cloud optionnelle (chiffrée)