J'ai passé la semaine dernière à essayer de comprendre comment fonctionnent réellement les domaines .night. Pas à partir d'une fiche technique, mais en construisant quelque chose qui interagit directement avec la blockchain. Le résultat est un petit visionneur de profil. Vous tapez un nom comme tomin.night, et il résout le profil directement depuis la blockchain. Pas d'API de registraire. Pas de barrière d'authentification. Juste un smart contract et un peu de JavaScript.
Voici comment cela fonctionne, ce que j'ai appris, et les deux pièges spécifiques qui m'ont fait perdre tout mon après-midi.
Pourquoi les noms on-chain sont importants
Sur Midnight, les domaines .night sont gérés par Midnames. Au lieu d'interroger le serveur central d'une entreprise, vous lisez directement depuis un smart contract qui réside sur la chaîne. Le registre lui-même détient le domaine, le propriétaire et tous les champs de profil que le propriétaire y a attachés. Comme ces données sont on-chain, l'identité est portable. Vous ne la louez pas à une plateforme qui peut changer ses conditions ou couper le service. Si vous contrôlez les clés, vous contrôlez le nom.
Ce changement est également important pour les développeurs. Lorsque vous développez par rapport à un système DNS traditionnel, vous devez gérer les limites de débit (rate limits), les clés d'API et les promesses de disponibilité (uptime). Ici, l'état du contrat est la source de vérité. Votre application le lit de la même manière que toutes les autres applications. Il n'y a pas de niveau d'API privilégié.
Le code est presque trop simple
Le @midnames/sdk s'occupe du plus gros du travail. Résoudre un domaine en une adresse et un profil prend exactement deux lignes :
const provider = createDefaultProvider({ networkId: "mainnet" });
const result = await resolveDomain(provider, "tomin.night");
C'est tout. Le provider cible le réseau, et le resolver communique avec le contrat. Le SDK renvoie un objet de résultat qui inclut un flag de succès. Si le domaine n'existe pas, vous n'avez pas besoin de couches de gestion d'erreurs ou de blocs try-catch autour des échecs RPC. Le SDK vous indique clairement que rien n'est présent. Cela rend la création d'interfaces utilisateur (UI) étonnamment agréable. Vous pouvez bifurquer selon le flag de succès et afficher un état « non trouvé » sans avoir à deviner si l'échec est dû à un nom manquant ou à un nœud hors service.
Ce que vous recevez en retour
Lorsque la recherche réussit, la charge utile (payload) contient deux éléments importants.
Target est l'adresse du wallet vers laquelle le domaine pointe. C'est l'utilité principale. Cela transforme une longue adresse hexadécimale en quelque chose qu'un humain peut lire, taper et mémoriser.
Fields contient les détails du profil. Tout ce que le propriétaire a attaché au domaine — liens sociaux, avatars, enregistrements textuels — se trouve à l'intérieur de cette structure. Ces champs ne sont pas stockés sur le cluster MongoDB d'une entreprise. Ce sont des champs dans l'état du contrat, ce qui signifie que n'importe quelle application sachant lire le registre peut afficher le même profil. Aucune synchronisation de base de données n'est requise.
Deux pièges qui m'ont ralenti
Tout n'était pas aussi simple que deux lignes et un flag de succès. J'ai rencontré deux obstacles spécifiques qu'il vaut mieux détailler pour que vous ne les répétiez pas.
Incohérence de réseau
Le SDK prend en charge les environnements mainnet et preprod. J'ai passé un temps considérable à déboguer un domaine qui « n'existait pas ». Le nom était correct. Le code semblait bon. Le provider tournait. Le problème était que mon script interrogeait preprod alors que le domaine lui-même était enregistré sur mainnet. L'erreur ressemblait à un domaine manquant, mais il s'agissait en réalité d'un contexte réseau manquant.
Si vous résolvez un nom et recevez un échec, vérifiez les paramètres du provider avant de déboguer quoi que ce soit d'autre. Assurez-vous que votre networkId correspond au réseau sur lequel le domaine a été réellement minté. C'est le genre d'erreur qui semble évidente avec le recul, mais qui est vraiment difficile à repérer quand on suppose que le problème vient de la logique du contrat.
Problèmes de sérialisation
Les données renvoyées par le SDK ne sont pas du JavaScript standard. Elles contiennent des valeurs BigInt et des objets Map. Si vous essayez de les envoyer directement dans JSON.stringify pour les transmettre à un navigateur, cela générera une erreur ou supprimera silencieusement des données. BigInt n'a pas de représentation JSON native, et Map ne se sérialise pas de la même manière que les objets simples.
J'ai fini par écrire un sérialiseur personnalisé. Il parcourt l'objet de résultat, convertit les valeurs BigInt en chaînes de caractères et transforme les instances Map en objets ordinaires avant que la réponse ne quitte le serveur. Si vous construisez une API qui sert des données Midnight à un frontend, prévoyez cette étape dès le début. Ne supposez pas que la sortie du SDK est immédiatement compatible avec le frontend simplement parce qu'il s'agit de JavaScript.
L'architecture
J'ai délibérément choisi une stack sans fioritures. Le backend est un serveur Node tournant sous Express. Il importe le @midnames/sdk, exécute la logique de résolution, gère les acrobaties de sérialisation et sert du JSON propre. Le frontend est du HTML pur et du JavaScript vanilla. Pas d'étape de build. Pas de framework. Pas d'adaptateur de wallet.
J'ai choisi d'exécuter le SDK sur le backend plutôt que dans le navigateur pour plusieurs raisons pratiques. Cela permet de garder toute configuration de provider hors du client, cela me donne un endroit unique pour corriger le désordre de la sérialisation, et cela signifie que le frontend n'a plus qu'à récupérer les données et à les afficher.
Voici ce qui m'a le plus surpris : la résolution d'un nom est une opération de lecture publique. Vous n'avez pas besoin de connexion de wallet. Vous n'avez pas besoin de signature. Vous n'avez pas besoin que l'utilisateur s'authentifie. Si le domaine existe, l'état du contrat est visible par quiconque le demande. C'est une différence majeure par rapport au flux web3 typique où chaque interaction commence par « connect wallet ». Lire une identité sur Midnight est sans permission, de la même manière que la consultation d'un site web public est sans permission.
Ce qu'il faut vraiment retenir
La création de ce viewer m'a rappelé que la partie la plus difficile du développement blockchain est rarement la blockchain elle-même. Midnight a déjà résolu le problème complexe : permettre aux gens de posséder leur nom et leur profil sans base de données centrale. La partie difficile, du point de vue du développeur, consistait à se rappeler sur quel réseau je pointais et à écrire une fonction utilitaire pour nettoyer les types de données.
Le protocole vous offre une identité portable. Votre travail en tant que développeur consiste simplement à la lire correctement et à ne pas gêner l'utilisateur. Gardez une architecture simple, séparez la logique liée à la blockchain de l'interface utilisateur, et traitez les lectures publiques pour ce qu'elles sont : des requêtes de base de données ordinaires qui se trouvent simplement sur un registre distribué.
Si vous souhaitez voir le code ou l'exécuter vous-même, le code source complet est disponible à l'adresse https://github.com/tomiin/midnames-profile-viewer.
