La piste isolate est éliminée (474 ms pour 30 dérivations, aucune erreur). Reste l’étape réseau. Je teste l’appel exact qui échoue : getBalances sur 30 adresses.
● Confirmé : réseau g1, endpoint automatique. Je sonde maintenant l’appel RPC exact sur tous les nœuds Ğ1.
Sa clé racine a bien un solde sur Ğ1. Je vais maintenant inspecter sa base ObjectBox (sur une copie, pour ne pas toucher à l’app qui tourne).
● Preuve trouvée : sa base contient actuellement 0 coffre et 0 portefeuille. Je teste maintenant la requête de soldes en parallèle, comme le fait le scan.
Bug reproduit. Plusieurs nœuds Ğ1 rejettent la rafale de 30 requêtes simultanées. Je récupère le message d’erreur exact.
J’ai trouvé. Je n’ai pas pu lire les logs de ton app en direct (elle écrit dans ton terminal, et
LogCollectionService garde tout en mémoire, rien sur disque), alors j’ai reproduit la panne de
l’extérieur.
Ce que dit ta base
J’ai ouvert une copie de ton ObjectBox (~/.gecko/objectbox) : 0 coffre, 0 portefeuille. Autrement
dit, la restauration ne laisse rien derrière elle — elle supprime ce qu’elle vient de créer.
La cause
La chaîne, vérifiée bout à bout :
- restore_modal.dart:168 crée le coffre, tu saisis le PIN.
- Le scan des dérivations appelle getBalances sur 30 adresses — qui lance 30 state_call d’API
runtime en parallèle (durt2/lib/src/services/duniter_storage_service.dart:321).
- Beaucoup de nœuds Ğ1 refusent cette rafale. Mesuré à l’instant sur ton poste, avec ta clé racine :
wss://rpc.duniter.org → 30 réponses, 0 erreur
wss://g1.axiom-team.fr/ws/ → 30 réponses, 0 erreur
wss://g1.gyroi.de → 30 réponses, 22 erreurs | 4003 too many concurrent runtime API calls
wss://g1.1000i100.fr → 30 réponses, 19 erreurs | 4003 too many concurrent runtime API calls
wss://g1.pini.fr/ws → 30 réponses, 12 erreurs | 4003 too many concurrent runtime API calls
- Une seule erreur suffit : _scanBalances (wallet_scan_service.dart:326) la convertit en
TimeoutException, et _cleanupFailedScan (:404) supprime le coffre tout juste créé.
- deleteSafe voit qu’il ne reste aucun coffre → defaultSafeBoxNumber = -1 → importRootWallet
(restore_modal.dart:197) fait getSafeBox(-1) → exception → le catch affiche le message générique « erreur de dérivation ».
Et voilà pourquoi ça a commencé quand tu as tout supprimé : avant, il restait un autre coffre, le
nettoyage basculait dessus et l’erreur ne se voyait pas. Avec un Ğecko vierge, il n’y a plus de
filet.
Deux pistes que j’ai écartées au passage : la génération des clés en isolate marche (474 ms pour 30 dérivations), et ta clé racine a bien un solde sur Ğ1 — tes ğ1 ne sont pas perdues, c’est uniquement l’import local qui casse.
Pour te débloquer tout de suite
Dans Paramètres → réseau, désactive l’endpoint automatique et mets wss://rpc.duniter.org (ou
wss://g1.axiom-team.fr/ws/), puis refais la restauration. Ces deux-là encaissent les 30 appels sans broncher.
Les deux corrections de fond
- durt2 — getBalances doit étaler ses appels (lots de 5, ou réessai sur le code 4003) au lieu d’en lancer 30 d’un coup.
- Ğecko — _cleanupFailedScan ne doit pas détruire le coffre quand le scan échoue pour une raison réseau : la phrase est valide, seule la découverte on-chain a raté. Le repli correct est d’importer juste le portefeuille racine — c’est déjà ce que fait le chemin « pas connecté »
(wallet_scan_service.dart:82), qui lui ne supprime rien. La suppression ne se justifie que pour le cas « ce coffre existe déjà ailleurs ».