ncantu 0db7a76044 Fix: double déclaration const now, scripts .mjs, /api/utxo/count accepte ancrages
**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
2026-01-26 02:06:10 +01:00

4.7 KiB
Raw Blame History

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 à larrêt (SIGINT/SIGTERM) et périodique (configurable via SAVE_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 hash
  • signatures: Map<string, StoredSignature[]> - Signatures indexées par hash de message
  • keys: Map<string, StoredKey[]> - Clés de déchiffrement indexées par hash de message
  • seenHashes: Set<string> - Hash vus pour déduplication

Sur disque :

  • Fichier {STORAGE_PATH}/messages.json contenant :
    • 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.json si présent (ENOENT = premier run, démarrage à vide).
  • Sauvegarde : À larrê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 :

  1. userwallet_identity : Identité locale

    {
      uuid: string,
      privateKey: string,
      publicKey: string,
      name?: string,
      t0_anniversaire: number,
      version: string
    }
    
  2. userwallet_relays : Configuration des relais

    Array<{
      endpoint: string,
      priority: number,
      enabled: boolean,
      last_sync?: number
    }>
    
  3. userwallet_pairs : Configuration des pairs

    Array<{
      uuid: string,
      membres_parents_uuid: string[],
      is_local: boolean,
      can_sign: boolean
    }>
    
  4. userwallet_hash_cache : Cache des hash vus

    string[] // Array de hash
    
  5. userwallet_keypair : (Legacy) Paire de clés

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