# Synthèse structurée – UserWallet & API Relay **Author:** Équipe 4NK **Date:** 2026-01-26 ## 1. userwallet/docs ### ports.md - **UserWallet (Vite)** : port **3018** (`vite.config.ts`). - **api-relay (Express)** : port **3019** (ou `PORT`), défaut 3019 dans `index.ts`. Le README api-relay indique 3019. - **Ports à éviter** : 3007, 8080, 3015–3017. ### specs.md Spécification du login décentralisé (secp256k1, contrats, pairing mFA, relais) : - **Modèle** : messages publiés sans signatures ni clés ; signatures et clés publiées séparément ; tout adressé par hash canonique ; récupération par **GET uniquement** (pull). - **Objets** : Service, Contrat, Champ, Action, ActionLogin, Membre, Pair, MessageBase, Hash, Signature, Validateurs, MsgChiffre, MsgSignature, MsgCle. - **Graphe** : Service → Contrat → Champ → Action(login) → Membre → Pair ; contraintes « au moins 1 parent ». - **Pairing** : UUID pair ↔ mots BIP32 ; pairing **obligatoire** pour login. - **Écrans** : accueil, création/import identité, relais, pairing, sync, services, chemin login, challenge, signatures mFA, publication, résultat. - **Machine à états** : S_INIT → S_HOME, S_SYNC_GLOBAL, S_PAIR_*, S_LOGIN_*, etc., avec erreurs récupérables / fatales. ### storage.md - **Relais** : stockage hybride (mémoire + `./data/messages.json`). Messages + `seenHashes` persistés ; **signatures et clés non persistées** (perdues au redémarrage). - **Front** : LocalStorage (`userwallet_identity`, `userwallet_relays`, `userwallet_pairs`, `userwallet_hash_cache`, plus legacy `userwallet_keypair`, `userwallet_services`). Graphe en mémoire uniquement (`GraphResolver`). --- ## 2. userwallet/ (frontend) ### Stack - React 18, React Router, Vite, TypeScript. - Crypto : `@noble/secp256k1`, `@noble/hashes`. - Pas de state global (hooks + services). ### Structure - **/components** : Home, CreateIdentity, ImportIdentity, Login, PairManagement, RelaySettings, Sync, ServiceList, ErrorDisplay, etc. - **/hooks** : useIdentity, useChannel, useErrorHandler, useServices, etc. - **/services** : GraphResolver, LoginBuilder, SyncService. - **/utils** : relay, storage, identity, crypto, canonical, encryption, verification, cache, bip32, pairing, iframeChannel, etc. - **/types** : identity, message, contract, auth, etc. ### Points notables - **Identité** : création (secp256k1), import (dérivation clé publique depuis clé privée hex ; mnemonic/seed non supportés). - **Relais** : config dans LocalStorage, test `/health`, GET/POST messages/signatures/keys via `utils/relay`. - **Pairing** : BIP32 UUID ↔ mots, `PairConfig` avec `membres_parents_uuid`, `is_local`, `can_sign`. - **Graphe** : GraphResolver avec caches (services, contrats, champs, actions, membres, pairs), `resolveLoginPath`, validation des parents. - **Login** : LoginBuilder (challenge, nonce, chiffrement « for all », preuve avec signatures), publication message → signatures → clés. - **Sync** : SyncService appelle les relais, HashCache (LocalStorage), déduplication, fetch clés/signatures, vérification hash/signatures/timestamp, mise à jour du graphe. - **Iframe** : iframeChannel + useChannel ; messages `auth-request`, `auth-response`, `login-proof`, `service-status`, `error` ; postMessage vers parent avec `'*'`. --- ## 3. api-relay (backend relais) ### Stack - Express, CORS, JSON. TypeScript, tsx en dev. - Pas de base de données : mémoire + persistance optionnelle (`./data`). ### Structure - **/routes** : messages, signatures, keys, health. - **/services** : StorageService, RelayService. - **/types** : message (MsgChiffre, MsgSignature, MsgCle, Stored), config. ### Endpoints - **GET /health** : `{ status: 'ok', timestamp }`. - **GET /messages?start=&end=&service=** : messages dans la fenêtre, optionnellement par service. - **POST /messages** : enregistrement + relais. - **GET /messages/:hash** : message par hash. - **GET/POST /signatures/:hash** et **/signatures** : idem pour signatures. - **GET/POST /keys/:hash** et **/keys** : idem pour clés. ### Comportement - **Storage** : messages, signatures, keys en mémoire ; `seenHashes` pour déduplication. Persistance : messages + `seenHashes` dans `messages.json` ; signatures et clés non sauvegardées. - **Relay** : `PEER_RELAYS` en env ; relais des messages/signatures/clés vers les pairs via POST. ### Correctif relais (POST /messages) - Vérifier `alreadySeen = storage.hasSeenHash(msg.hash)` **avant** `storeMessage`. - Puis `storage.storeMessage(stored)`. - Relayer seulement si `!alreadySeen` : `await relay.relayMessage(msg)` et `stored.relayed = true`. ### Autres points - **config.ts** : RelayConfig avec `relay_enabled`, `max_message_age_days`, etc. Non utilisé dans `index.ts` (config réelle : PORT, HOST, STORAGE_PATH, PEER_RELAYS). - **README** : port par défaut 3019. --- ## 4. Liens entre UserWallet et api-relay - UserWallet appelle les endpoints du relais (messages, signatures, keys, health) via `utils/relay`. - Types alignés : MsgChiffre, MsgSignature, MsgCle (structure équivalente, noms français). - UserWallet utilise `datajson_public` (services_uuid, types_uuid, timestamp, etc.) comme le relais. - Ports : front 3018, relais 3019 (voir `ports.md`). --- ## 5. Synthèse | Élément | userwallet | api-relay | |-----------|--------------------------------------------------------------------|----------------------------------------------------------| | **Rôle** | Front login décentralisé (secp256k1, contrats, pairing mFA) | Relais stockage + diffusion messages/signatures/clés | | **Port** | 3018 | 3019 | | **Stockage** | LocalStorage (identité, relais, pairs, hash cache) | Mémoire + JSON (messages, seenHashes) ; sig/keys non persistées | | **Specs** | Aligné avec specs.md (graphe, ordre message→sig→clés, pull-only) | Séparation messages / signatures / clés, dédup par hash |