anchorage_layer_simple/fixKnowledge/userwallet-api-relay-fixes.md
ncantu cad73cb265 UTXO-list: dates/blockTime historiques, récupération frais depuis ancrages, diagnostic Bloc Rewards
**Motivations:**
- Ajouter dates manquantes dans hash_list.txt et compléter historique
- Compléter blockTime manquants dans utxo_list.txt et compléter historique
- Récupérer frais depuis transactions d'ancrage (OP_RETURN) et les stocker
- Bouton UI pour déclencher récupération frais
- Diagnostic Bloc Rewards (pourquoi ~4700 BTC au lieu de 50 BTC)

**Root causes:**
- hash_list.txt sans date (format ancien)
- utxo_list.txt blockTime souvent vide
- Frais absents du fichier (métadonnées OP_RETURN non stockées)
- Pas de moyen de récupérer/compléter frais depuis UI

**Correctifs:**
- hash_list.txt : format étendu avec date (rétrocompatible)
- utxo_list.txt : blockTime complété automatiquement lors écritures
- fees_list.txt : nouveau fichier pour stocker frais
- updateFeesFromAnchors() : récupère frais depuis OP_RETURN ancrages
- Endpoint /api/utxo/fees/update pour déclencher récupération
- Bouton "Récupérer les frais depuis les ancrages" dans section Frais (spinner)
- Scripts batch : complete-hash-list-dates.js, complete-utxo-list-blocktime.js
- Script diagnostic : diagnose-bloc-rewards.js (subsidy, coinbase, listunspent)

**Evolutions:**
- Frais chargés depuis fees_list.txt dans getUtxoList
- Complétion automatique dates/blockTime lors écritures futures

**Pages affectées:**
- signet-dashboard/src/bitcoin-rpc.js
- signet-dashboard/src/server.js
- signet-dashboard/public/utxo-list.html
- scripts/complete-hash-list-dates.js
- scripts/complete-utxo-list-blocktime.js
- scripts/diagnose-bloc-rewards.js
- features/utxo-list-fees-update-and-historical-completion.md
2026-01-26 01:59:46 +01:00

4.8 KiB
Raw Permalink Blame History

Correctifs UserWallet et API Relay

Auteur: Équipe 4NK
Date: 2026-01-26

Motivations

  • Corriger la condition de relais dans POST /messages (api-relay) : les messages nétaient jamais relayés.
  • Supprimer la duplication du type MessageBase dans SyncService et utiliser les types partagés.
  • Supprimer les fallbacks (retour de [] ou false en erreur) dans relay.ts et remonter les erreurs.
  • Implémenter une vraie dérivation clé publique depuis la clé privée à limport didentité, et documenter la limite (pas de mnemonic/seed).

Root causes

  • Relais : On appelait storage.storeMessage() puis if (!storage.hasSeenHash()) pour relayer. Or storeMessage marque le hash comme vu, donc la condition était toujours fausse et le relais jamais exécuté.
  • MessageBase : SyncService définissait une interface locale MessageBase avec hash?: string, alors que le code utilisait msg.hash.hash_value (type Hash). Incohérence de typage et duplication.
  • relay.ts : Les GET renvoyaient [] et les POST false en cas derreur, ce qui masquait les échecs (fallback interdit).
  • importIdentity : On générait une nouvelle paire, puis on écrasait privateKey par la seed fournie tout en gardant la publicKey de la paire générée. Aucune dérivation depuis la clé importée.

Correctifs

1. api-relay POST /messages (relay condition)

Fichier: api-relay/src/routes/messages.ts

  • Calculer alreadySeen = storage.hasSeenHash(msg.hash) avant storage.storeMessage(stored).
  • Appeler storage.storeMessage(stored).
  • Relayer seulement si !alreadySeen : await relay.relayMessage(msg) et stored.relayed = true.

2. userwallet SyncService MessageBase

Fichier: userwallet/src/services/syncService.ts

  • Importer MessageBase depuis ../types/message.
  • Supprimer linterface locale MessageBase en fin de fichier.
  • Utiliser le type partagé pour validateMessage et updateGraph.

3. userwallet relay.ts (remonter les erreurs)

Fichier: userwallet/src/utils/relay.ts

  • GET (getMessagesChiffres, getSignatures, getKeys) : ne plus retourner [] en erreur ; throw new Error(...) en cas de !response.ok ou déchec fetch, avec message incluant statut et URL du relais.
  • POST (postMessageChiffre, postSignature, postKey) : ne plus retourner false ; throw new Error(...) en cas déchec. Types de retour passés à Promise<void>.

Fichier: userwallet/src/components/LoginScreen.tsx

  • Adapter la boucle de publication : await postMessageChiffre / await postSignature sans vérifier de booléen ; en cas de throw, le catch existant pousse { relay, success: false } et on continue.

4. userwallet importIdentity (dérivation + limite)

Fichiers: userwallet/src/utils/crypto.ts, userwallet/src/utils/identity.ts

  • crypto.ts : Ajouter publicKeyFromPrivateKey(privateKeyHex: string): string qui dérive la clé publique secp256k1 (compressée, hex) depuis la clé privée hex.
  • identity.ts :
    • Valider que lentrée est 64 caractères hexadécimaux (32 octets), après trim et suppression dun préfixe 0x éventuel.
    • Utiliser publicKeyFromPrivateKey(raw) pour la clé publique.
    • Stocker raw comme privateKey et la clé dérivée comme publicKey.
    • Documenter en JSDoc : seul limport dune clé privée hex brute est supporté ; mnemonic (BIP39) et dérivation depuis seed ne sont pas implémentés.

Évolutions

  • Aucune évolution fonctionnelle au-delà des correctifs cidessus.

Pages affectées

  • api-relay/src/routes/messages.ts
  • userwallet/src/services/syncService.ts
  • userwallet/src/utils/relay.ts
  • userwallet/src/utils/crypto.ts
  • userwallet/src/utils/identity.ts
  • userwallet/src/components/LoginScreen.tsx

Modalités de déploiement

  • api-relay : Redémarrer le serveur après déploiement.
  • userwallet : Rebuild du frontend et déploiement des assets. Les appelants de relay.ts (SyncService, LoginScreen) gèrent déjà les erreurs (try/catch) ; les throws sont remontés jusquà eux.

Modalités danalyse

  • Relais : Poster un message sur un relais avec pairs configurés ; vérifier quil est bien relayé vers les pairs (logs, GET sur un pair).
  • SyncService : Vérifier que le type-check et le lint passent ; lancer une sync et sassurer quaucune régression sur la résolution du graphe.
  • relay.ts : En cas de relais injoignable ou réponse non ok, vérifier que lerreur est bien levée (et non masquée par [] / false).
  • importIdentity : Importer une clé privée hex valide (64 caractères), vérifier que la clé publique stockée correspond à la dérivation secp256k1. Tester un format invalide (ex. mnemonic) et vérifier le retour null et le message en console.