Primal 3.5 livre une coque Android reconstruite, Amethyst ajoute les zaps Bitcoin onchain, White Noise gagne le rendu markdown et les liens profonds, Keycast passe un audit de sécurité, et AgentNoise vous permet de contrôler des agents de codage IA locaux via un chat chiffré par Marmot. Hostr lance une plateforme P2P de location d’hébergement sur Nostr avec quatre projets de NIPs couvrant les annonces, les réservations et l’entiercement basé sur EVM. Angor migre la messagerie chiffrée de NIP-04 vers NIP-44, Dart NDK ajoute NIP-77 et un signataire web, Alby js-sdk v8 livre une reconnexion multi-relais NWC native, et KeyChat corrige un trou de forward secrecy dans la suppression des préclés uniques Signal. Côté protocole, la caution anti-abus de Mostro atteint la Phase 2, Wisp livre les réponses privées et les réactions gift-wrapped, et une vague d’implémentation Namecoin NIP-05 touche une demi-douzaine de clients en une seule semaine.

Articles principaux

Primal 3.5 pour Android

Primal, le client social soutenu par sa propre infrastructure de relais de cache, a livré 3.5.9 cette semaine avec une coque d’application reconstruite. La refonte remplace la structure de navigation précédente par une nouvelle disposition et un nouvel écran Explorer, donnant à la surface de découverte principale sa propre maison dédiée. La sortie ajoute la lecture audio pour les aperçus de liens, afin que les fichiers audio intégrés dans les notes soient lus en ligne sans quitter le fil. Les badges de vérification NIP-05 s’affichent maintenant en ligne sur les profils, faisant apparaître la confirmation d’identité en un coup d’œil. Le filtrage des notifications a reçu une refonte, permettant aux utilisateurs de restreindre quels types d’événements atteignent leur liste de notifications. L’éditeur a gagné une meilleure gestion des liens d’événements, et la couche de base de données sous-jacente a reçu des correctifs de stabilité.

White Noise : markdown, liens profonds et métadonnées audio

White Noise, l’application de messagerie de groupe chiffrée par Marmot construite sur Nostr et MLS (RFC 9420), a eu l’une de ses semaines les plus occupées à ce jour à travers les dépôts frontend et backend.

Sur le frontend, PR #665 ajoute le rendu markdown complet pour les messages de chat, afin que le gras, l’italique, les blocs de code et les liens s’affichent maintenant nativement dans la vue des messages. PR #675 active le flux quitter-le-groupe qui était précédemment bloqué pour les non-derniers-admins, et PR #661 ajoute le support natif des liens profonds pour les URI whitenoise:// et whitenoise-staging:// couvrant les utilisateurs, les chats et les paramètres, sans nécessiter aucune infrastructure de redirection HTTP.

Sur le backend dans whitenoise-rs, PR #835 fait fonctionner correctement la rotation des key packages en réutilisant le slot d_tag pour les publications kind:30443, activant la sémantique d’événement remplaçable NIP-33 afin que les rotations successives de key package remplacent l’événement précédent sur les relais, ne gardant que le key package actuel. PR #833 étend FileMetadata avec des champs optionnels duration_ms et waveform pour les pièces jointes audio, coordonné avec PR #300 de MDK qui ajoute les mêmes champs aux balises média MIP-04. Un nouveau crate whitenoise-markdown (PR #836) remplace l’analyseur de token nostr-sdk précédent par une bibliothèque de rendu markdown dédiée.

La spécification Marmot elle-même a reçu un correctif de sécurité dans PR #68, qui ferme un problème de sécurité en spécifiant explicitement HKDF-SHA256 pour les dérivations de clé d’image dans MIP-01, supprimant une ambiguïté qui pourrait mener à une divergence d’implémentation. Dans MDK, PR #307 assainit les raisons d’échec de welcome et plafonne la longueur stockée, fermant une constatation de sécurité distincte.

Amethyst v1.10.0 : Zaps Bitcoin onchain

Amethyst a livré quatre sorties cette semaine, avec v1.10.0 comme titre. La sortie ajoute le support des zaps Bitcoin onchain NIP-BC, permettant aux utilisateurs d’envoyer, recevoir et afficher des zaps réglés directement onchain via des transactions Bitcoin. Les sorties précédentes dans la série ont corrigé la détection de blob Blossom pour rejeter les noms de fichiers non conformes (v1.09.2), corrigé les règles ProGuard pour les builds de bureau, et fusionné la pull request #2977 pour montrer les zappeurs Bitcoin onchain comme une ligne ₿ dédiée dans la galerie de réactions étendue. Un écran d’historique de transactions on-chain en cours avec pagination a atterri dans PR #2974.

AgentNoise : contrôler des agents de codage via White Noise

AgentNoise par nvk est un helper de bureau natif en Rust qui vous permet d’utiliser un téléphone exécutant White Noise comme surface de contrôle pour des sessions d’agents de codage Codex et Claude locales. L’outil écoute un ou plusieurs chats White Noise, authentifie les expéditeurs via un flux PIN de premier appairage, et lance des agents de codage locaux via le lanceur configuré. Envoyer /claude <prompt> depuis votre téléphone ouvre une nouvelle session de travail White Noise nommée d’après le nom d’hôte de la machine et un court résumé du prompt, puis diffuse les mises à jour de progression et la sortie finale de retour dans ce chat. Il est intentionnellement Rust-first et garde Node hors du chemin de pont de confiance. Le projet a atteint v0.1.24 cette semaine, ajoutant des réponses plus courtes lisibles par téléphone, des références de tâches par préfixe unique court, et un watcher de session local en opt-in. AgentNoise pilote les CLI wn et wnd de marmot-protocol/whitenoise-rs en tant que sous-processus, donc il partage son transport Nostr avec le client White Noise lui-même.

Audit de sécurité Keycast terminé

Keycast, le serveur de signature à distance NIP-46 orienté équipe qui stocke les clés privées Nostr chiffrées au repos dans SQLite, a terminé un audit de sécurité en mai 2026. La passe de durcissement a abordé les problèmes d’authentification, de permission, d’intégrité des données et de dépendances, et les résultats sont documentés dans AUDIT.md. Les changements incluent : l’auth HTTP NIP-98 nécessite maintenant exactement une balise u et une balise method, rejette les horodatages périmés, et valide les hashes de payload ; la liste blanche ALLOWED_PUBKEYS est analysée exactement et appliquée côté serveur ; les politiques vides refusent par défaut les demandes de sign/encrypt/decrypt ; l’application des clés étrangères est activée sur les connexions SQLite ; et les routes d’application imbriquées telles que /teams/:id sont protégées côté serveur. Une migration SQL normalise l’ancien JSON de permission allowed-kinds au démarrage. Le projet est encore en phase précoce et l’audit note des éléments résiduels avant de lui confier de vraies clés d’équipe.

Scramble : client Marmot pour bureau et Android

Scramble (anciennement OpenChat) est un client .NET/Avalonia de bureau et Android pour le protocole Marmot, implémentant les MIPs 00-04 : publication de KeyPackage (kind:30443), métadonnées de groupe avec l’extension MLS NostrGroupData, événements de welcome gift-wrapped NIP-59 (kind:444), messages chiffrés ChaCha20-Poly1305 (kind:445), et pièces jointes média chiffrées Blossom. Il est entièrement interopérable avec White Noise et tout autre client compatible Marmot.

Le projet a livré 13 sorties cette semaine, avec le support multi-appareils comme fonctionnalité principale. Chaque appareil génère un slot KeyPackage unique (une balise d sur kind:30443). Au démarrage, Scramble récupère les KeyPackages propres de l’utilisateur depuis les relais, détecte les IDs de slot des appareils pairs, et les ajoute automatiquement aux groupes MLS existants via le flux de commit en étapes. L’auto-ajout est restreint aux groupes où l’utilisateur actuel est admin ; les groupes non-admin sont sautés avec des instructions pour demander à l’admin du groupe. Une bannière de divulgation de forward secrecy informe les appareils nouvellement liés que les anciens messages ne sont pas disponibles. Une passe de réconciliation d’ID de slot (TryReconcileSlotId) gère les appareils migrés depuis les versions pré-multi-appareils en comparant les octets de KeyPackage du relais avec le matériel de clé local pour adopter la bonne balise d. La reconnexion du signataire externe pour les utilisateurs Amber et NIP-46 a également été corrigée : la garde IsConnected qui bloquait la reconnexion automatique intégrée de ExternalSignerService a été supprimée aux neuf sites d’appel dans NostrService.

Hostr : hébergement locatif P2P sur Nostr

Hostr (source) est une plateforme d’hébergement locatif peer-to-peer construite entièrement sur Nostr. Elle couvre le flux complet de style Airbnb (recherche et annonces de propriétés, négociation de réservations, et règlement des paiements) en utilisant quatre projets de NIPs que le projet développe en parallèle avec l’application.

Le NIP d’hébergement étend les annonces classées NIP-99 (kind:30402 actif, kind:30403 brouillon) avec des balises spécifiques à l’hébergement pour le type (room, house, apartment, villa, hotel, hostel, resort), les heures d’arrivée/départ, le séjour minimum, et les index de cellule géospatiale H3 pour la recherche basée sur la localisation à précision configurable. Le NIP de réservation définit un protocole complet de négociation et de cycle de vie : les événements de réservation remplaçables kind:32122 portent un ID de trade d, une balise d’ancrage d’annonce a, et des balises de participants p avec les rôles (buyer, seller, escrow) ; les rumeurs de messages structurés kind:1327 délivrent les contre-offres privées d’étape de négociation via des gift wraps NIP-59 afin que la négociation reste hors des relais publics ; les événements de transition en ajout uniquement kind:1326 créent une piste d’audit publique une fois qu’une réservation s’engage. La vie privée de l’acheteur est préservée via des clés Nostr temporaires par trade liées à l’identité réelle de l’acheteur via des balises participant_proof chiffrées. Le NIP d’entiercement définit les publicités de service d’entiercement kind:30303 et les déclarations de confiance utilisateur kind:17388 ; l’implémentation de référence utilise des smart contracts EVM sur Rootstock, avec contractBytecodeHash permettant aux clients de vérifier que le contrat déployé correspond à une implémentation auditée connue. Le NIP d’annonce de marketplace définit des balises génériques partagées entre tous les profils de marketplace NIP-99, y compris instantBook, negotiable, quantity, securityDeposit, cancellationPolicy et maxDisputePeriod. Cette semaine, le projet a préparé sa soumission à l’app store et fusionné le support d’identité de client MCP pour l’automatisation orientée agent.

Deux nouvelles entrées sont apparues sur la plateforme Shakespeare MiniApps cette semaine : InkPress, un générateur de magazine IA qui publie du contenu structuré de style magazine en tant qu’événements Nostr, et PressStr, une plateforme d’écriture et de publication pour la pile Soapbox.

Livraison cette semaine

ngit v2.4.4

ngit a livré v2.4.4, ajoutant ngit sync --trust-server (-t) pour les cas où un serveur git est en avance fast-forward sur l’état Nostr. Quand cette situation est détectée, sync signale les refs affectées et nécessite le drapeau pour signer et publier un événement d’état mis à jour ; un paramètre de configuration git nostr.trust-server-domains fournit une liste blanche séparée par des points-virgules pour les serveurs qui devraient être approuvés automatiquement sans le drapeau.

Amber v6.1.0-pre3 ajoute la signature PSBT

Amber a publié v6.1.0-pre3 avec une disposition améliorée pour les nouvelles connexions d’app, des correctifs de crash, et une option de sélection/désélection tout sur l’écran des permissions. PR #438 ajoute le support de signature PSBT à travers les chemins basé sur Intent et basé sur relais NIP-46, permettant à Amber de signer des Partially Signed Bitcoin Transactions sans exposer la nsec à l’application demandeuse.

Wisp v1.1.0 livre les réponses privées et abandonne le support Amber

Wisp a publié v1.1.0 avec les réponses privées via gift wrap NIP-17 (PR #540), les réactions gift-wrapped et zaps DIP-03 sur les réponses privées (PR #543), l’auto-traduction pour les notes (PR #523), et une saisie fiat de style registre sur le dialogue de zap. PR #541 migre les zaps privés d’un schéma texte-clair de relais DM maison vers DIP-03 avec un routage de relais DM correct. Le même cycle de sortie a supprimé le support du signataire distant NIP-55 (PR #531), abandonnant Amber et autres intégrations de signataires externes, et supprimé le relais local intégré (PR #533). Wisp est un client social Nostr pour Android.

Calendar by Formstr v1.5.4 corrige le gift wrap pour les nouveaux participants

Calendar by Formstr a livré v1.5.4 (le dernier dans une séquence v1.5.2 → v1.5.4). PR #160 corrige un bug où l’édition d’un événement de calendrier privé avec de nouveaux participants publiait l’événement mis à jour avec les nouveaux pubkeys dans les balises p mais ne créait ni ne délivrait jamais les invitations gift wrap à ces participants, cassant le flux d’invitation pour les ajouts de dernière minute. PR #156 ajoute la gestion des erreurs autour du déchiffrement d’événements privés afin que les clients ne lancent plus sur les événements indéchiffrables, et PR #138 corrige les heures d’événements récurrents qui dérivaient entre fuseaux horaires.

Applesauce v6.1.0 ajoute les git casts NIP-34 et les relais de lookup NIP-51

Applesauce a publié v6.1.0 à travers ses packages avec un support significatif de NIP-34 (git-over-Nostr) : applesauce-common ajoute de nouveaux casts GitRepository, GitGraspList et FavoriteGitRepos plus des usines correspondantes, et expose les propriétés réactives User.favoriteGitRepos$, User.gitAuthors$ et User.graspServers$ afin que les applications puissent lister les dépôts git suivis d’un utilisateur, les mainteneurs de dépôts et les serveurs GRASP configurés directement depuis le même objet User. La même sortie ajoute le support des listes de relais de lookup kind 10086 NIP-51, un ajout récent à la famille de listes de relais utilisé pour découvrir où trouver des données spécifiques. applesauce-core gagne replaceableAddress sur EventCast pour la recherche d’adresse remplaçable NIP-01, plus pointer, kind, et un helper getReplaceableAddressForEvent, et ajoute une méthode timeline$() sur le cast User de base. PR #73 corrige les méthodes manuelles du pool qui abandonnaient silencieusement les relais hors ligne.

Sprout v0.0.16 livre le binaire Sprig et le protocole huddle v2

Sprout par Block, un espace de travail d’équipe basé sur des relais Nostr auto-hébergé où les humains et les agents IA partagent les mêmes salles et journal d’événements, a livré v0.0.16 de l’application de bureau aux côtés de builds continus du nouveau binaire tout-en-un Sprig (PR #605), qui rassemble le harnais ACP, l’agent et le MCP développeur dans un seul binaire de style busybox pour un déploiement facile. Le drapeau --no-memory ajouté dans PR #611 permet aux opérateurs de désactiver l’injection de mémoire centrale NIP-AE pour le harnais ACP. Côté temps réel, PR #609 étend le protocole vocal huddle à un en-tête de trame v2 supportant jusqu’à 10 pairs simultanés.

Nostrord v1.0.3 ajoute le trousseau OS et le multi-compte

Nostrord a publié v1.0.3 avec un stockage de clés locales durci utilisant le trousseau OS et une phrase de passe de secours, le support multi-compte, et un code QR bunker cliquable qui ouvre l’application signataire sur Android.

Angor migre vers NIP-44 et livre un durcissement de sécurité

Angor, l’application de crowdfunding Bitcoin construite sur Nostr et Taproot, a livré trois versions instables cette semaine (v0.2.24, v0.2.25, et v0.2.26) avec un ensemble de changements de durcissement de sécurité et d’intégration Nostr. PR #860 migre la messagerie chiffrée Nostr de NIP-04 vers NIP-44, remplaçant le schéma XOR déprécié par le chiffrement ChaCha20-Poly1305. PR #861 permet les uploads de médias Blossom sans portefeuille sélectionné en utilisant une clé d’auth Nostr éphémère, débloquant les uploads pour les utilisateurs qui n’ont pas encore connecté de portefeuille. La série de sécurité a abordé plusieurs catégories durcies : PR #854 ajoute la sécurité de type pour AngorKey et la protection mémoire des mnémoniques, PR #856 applique une validation au niveau protocole pour les timelocks, les taux de frais, les seuils dust et les règles de pénalité, et PR #851 applique un durcissement non-cassant à travers huit catégories de sévérité moyenne et basse. PR #859 corrige la compatibilité GrapheneOS en activant la compilation AOT et en supprimant la génération de code à l’exécution, et PR #855 empêche la perte de portefeuille sur swipe-kill Android en persistant l’état du portefeuille avant que l’OS ne termine le processus.

Alby js-sdk v8.0 livre la reconnexion multi-relais NWC

Alby js-sdk a publié la ligne v8.0 (v8.0.1 à v8.0.3) avec le support d’abonnement multi-relais NWC. PR #516 met à jour la dépendance nostr-tools et active la reconnexion automatique native à travers plusieurs relais, remplaçant l’approche de polling précédente par une logique de reconnexion native au relais. PR #542 remplace tous les appels console.debug par une interface de logger injectable afin que les développeurs d’application puissent router les diagnostics SDK à travers leur propre infrastructure de journalisation. La sortie abandonne le polyfill WebSocket, nécessitant Node.js 22 ou supérieur pour les consommateurs côté serveur. v8.0.2 a ajouté un correctif pour un bug d’import crypto utils qui cassait certains bundlers.

KeyChat v1.41.1 corrige la forward secrecy

KeyChat, une application de messagerie qui combine le protocole Signal avec le transport de relais Nostr, a publié v1.41.1+6513. Le correctif principal impose la forward secrecy en supprimant les préclés uniques Signal immédiatement après un déchiffrement réussi, fermant un trou où une préclé retenue pourrait être utilisée pour déchiffrer des messages passés si l’appareil était compromis plus tard. La sortie ajoute également un aperçu d’URL pour les messages consistant en un seul lien, centralise l’auto-téléchargement de médias sous un nouveau FileDownloadManager avec un seuil automatique de 20 Mo, et refactorise la récupération d’infos de relais NIP-11 pour forcer le rafraîchissement au démarrage à froid afin que les configurations de frais de relais payants se chargent toujours correctement.

En développement

Citrine a fusionné PR #151 implémentant l’application de NIP-70 : le relais Android bloque maintenant les reposts qui intègrent du contenu d’événement protégé, comme la spécification l’exige. PR #149 ajoute des actions d’affichage et de copie pour plusieurs adresses de connexion, localhost, Wi-Fi local et Tor, depuis l’écran des paramètres du relais. PR #141 ajoute la gestion des défis AUTH NIP-42 via l’intégration d’un signataire externe avec Amber.

Mostro a atteint la Phase 2 de son déploiement de caution anti-abus. PR #737 atterrit la logique de slash de caution dirigée par le solveur : les gestionnaires admin consomment maintenant la charge utile BondResolution de mostro-core, permettant à un admin de slasher la caution de l’une ou l’autre partie lors de la résolution d’un litige. Phase 1.5, fusionnée dans PR #736, a introduit une action PayBondInvoice dédiée et un statut WaitingTakerBond, séparant le paiement de la caution anti-abus du taker du paiement de l’acheteur. Le client mobile a ajouté l’UX complète de Phase 1.5 dans PR #592. Mostro est un protocole d’échange Bitcoin peer-to-peer construit sur Nostr.

Damus a fusionné PR #3773 restaurant l’indicateur de signal de relais, et PR #3775 corrige les relais qui refusaient de se reconnecter après un échec de connexion initial.

rust-nostr a fusionné PR #1358 ajoutant des traits de finalisation d’événements et des constructeurs d’événements spécifiques à NIP, rendant plus facile la construction d’événements correctement typés pour des fonctions de protocole spécifiques. PR #1363 rétroporte un correctif garantissant que le signataire NIP-46 s’abonne aux notifications avant d’envoyer la réponse de connexion, fermant une condition de course où les messages client arrivant immédiatement après la connexion pouvaient être manqués.

dart-nostr a fusionné PR #44 ajoutant un résolveur de relais .bit Namecoin et des enregistrements de pin TLSA, permettant aux applications Flutter de résoudre les URLs de relais wss://example.bit/ via DNS Namecoin vers leurs adresses WebSocket réelles.

Dart NDK (le kit de développement Nostr Dart/Flutter, maintenant à relaystr/ndk) a fusionné PR #464 implémentant NIP-77, le protocole de signature d’événement hors ligne. Côté signataire, PR #602 et PR #601 ajoutent un signataire d’événement spécifique au web et une abstraction PlatformEventVerifier, permettant aux applications Flutter web d’utiliser le signataire de plateforme sans chemin de code séparé ; PR #604 introduit une usine de signataire d’événement pour la sélection de signataire à l’exécution. PR #608 ajoute getDmRelays() pour récupérer la liste de relais DM NIP-17 d’un utilisateur (kind:10050), et PR #600 corrige la préservation des champs signés NIP-46 afin que les signataires distants ne perdent pas de champs sur l’aller-retour.

Pages by Form* (repo), l’application de document collaboratif nostr-native de Formstr hébergée à pages.formstr.app, a fusionné quatre PRs cette semaine resserrant les flux de pièces jointes chiffrées et de gestion de documents. PR #37 corrige les images manquantes dans les exports DOCX, HTML et PDF en incorporant les pièces jointes chiffrées : il récupère les blobs <encrypted-file> depuis les serveurs Blossom, les déchiffre avec AES-GCM 256 bits en utilisant la clé et le nonce stockés, valide le type MIME de l’image, et les convertit en URLs de données base64 afin que les exports préservent les images qui n’existent sur Blossom que sous forme chiffrée. PR #39 ajoute un mécanisme de recherche de document local, PR #38 nettoie le flux de renommage, et PR #40 corrige la gestion des sauvegardes partagées.

Zap Cooking a fusionné PR #396, la première phase d’une refonte du fil qui pose les primitives de rendu de fil sans aucun changement visible par l’utilisateur pour le moment. La PR introduit un analyseur de balises imeta NIP-92 qui lit les slots url, m (MIME), dim (dimensions), blurhash, alt, x (hash de fichier) et fallback, plus un décodeur blurhash canonique porté à la main (~200 LOC) qui produit des URLs de données PNG via canvas avec un fallback null SSR-safe. Quand les balises imeta sont absentes, l’analyseur revient à extraire les URLs d’images et vidéos brutes du contenu de l’événement en utilisant les mêmes heuristiques que le fil actuel utilise déjà.

Nurunuru (ぬるぬる, tami1A84/null--nostr), un client Nostr avec des variantes natives Android, iOS et Web partageant un moteur FFI Rust, a fusionné sa synchronisation Native → Web v1.5.0 dans PR #176. La synchronisation apporte plusieurs ajouts de fonctionnalités à la version Web qui ont déjà été livrés sur Android v1.4.9 et iOS 1.0.4 : le NotificationModal fait maintenant surface les notifications d’anniversaire, la détection de zap mutuel-suivi, et les notifications de réaction emoji personnalisée ; le sélecteur de réaction abandonne la ligne rapide de réactions Unicode par défaut et centre l’UX sur les emojis personnalisés ; le moteur de recommandation dans lib/recommendation.js filtre les utilisateurs sans icônes ou noms d’affichage et priorise les entrées Following avec chargement Recommended en arrière-plan. L’entrée vocale est la seule fonctionnalité qui va dans l’autre direction : la version Web utilise déjà le streaming ElevenLabs Scribe, et v1.5.0 synchronise partiellement le côté Natif vers le SpeechRecognizer standard OS (Android) et SFSpeechRecognizer + AVAudioEngine (iOS) tandis que l’intégration Scribe Natif complète est différée à v1.6.

Travail de protocole et de spécification

PR #2251 resserre la spécification des événements protégés NIP-70 : il déclare maintenant explicitement que les reposts intégrant le contenu complet d’un événement protégé doivent être rejetés par les relais. NIP-70 définit la balise - qui signale qu’un auteur de note ne consent pas à ce que sa note soit republiée. La spécification originale couvrait le comportement de filtrage du relais, mais laissait le cas de repost ambigu. Cette PR ferme cette lacune. PR #151 de Citrine implémente l’application côté relais cette même semaine.

PR #1653 propose un NIP Drafts pour sauvegarder et synchroniser les événements brouillons privés. La proposition utilise des événements remplaçables avec un statut draft et un chiffrement NIP-44 vers la propre clé de l’auteur, permettant aux clients de sauvegarder des travaux en cours sur les relais sans que ces événements soient visibles par qui que ce soit d’autre. L’événement brouillon porte l’événement complet destiné à la publication en tant que contenu chiffré, y compris son kind et ses balises éventuels.

Snapshots (PR #2279) est une proposition ouverte pour définir un événement de snapshot immuable pour préserver une version exacte d’un événement Nostr remplaçable. L’événement de snapshot porte le contenu complet de l’événement remplaçable à un moment donné, avec une balise a le liant à l’adresse de l’événement remplaçable afin que toutes les versions historiques soient interrogeables ensemble. Cela permet aux observateurs d’inspecter l’état historique même après que les relais aient cessé de retenir les anciennes versions.

Vague Namecoin NIP-05 : Cette semaine a vu une poussée coordonnée pour ajouter la résolution NIP-05 .bit aux clients Nostr. Le fil de discussion NIP a capturé des PRs open-source contre Aegis (#14, qui ajoute la vérification au moment de la signature au signataire), nostter (#2128), et dart-nostr (#44), aux côtés d’un projet de NIP upstream (PR #2349). La PR Aegis est notable pour placer la vérification côté producteur : le signataire vérifie la chaîne Namecoin avant de signer tout événement kind:0 qui revendique une identité .bit et avertit l’utilisateur en cas de non-correspondance, attrapant le problème avant que l’événement n’atteigne un relais.

NIP Deep Dive : NIP-07 (window.nostr pour les navigateurs web)

NIP-07 définit l’interface window.nostr que les extensions de navigateur exposent aux applications web. C’est l’interface de signataire la plus largement déployée sur le web, implémentée par des extensions incluant Alby, nos2x, Flamingo et horse.

L’interface a deux méthodes requises et plusieurs optionnelles. window.nostr.getPublicKey() retourne la clé publique de l’utilisateur sous forme de chaîne hex sans jamais exposer la clé privée à la page appelante. window.nostr.signEvent(event) prend un événement partiel avec created_at, kind, tags et content, et retourne l’événement signé complet avec id, pubkey et sig ajoutés. Le point clé est que la clé privée ne quitte jamais le contexte isolé de l’extension ; l’application web soumet un événement non signé et reçoit en retour un signé.

Les méthodes optionnelles couvrent le chiffrement : window.nostr.nip04.encrypt et window.nostr.nip04.decrypt pour l’ancien schéma NIP-04 (maintenant déprécié), et window.nostr.nip44.encrypt et window.nostr.nip44.decrypt pour le schéma NIP-44 actuel. Les extensions qui supportent NIP-44 peuvent donc gérer à la fois le chiffrement de messages directs et toute autre application qui a besoin de chiffrement par clé pubkey sans que la page appelante voie la nsec.

La spécification inclut également une recommandation aux auteurs d’extension : charger les scripts avec "run_at": "document_end" dans le manifeste de l’extension afin que window.nostr soit disponible de manière synchrone au chargement de la page, évitant les conditions de course où un client vérifie window.nostr avant que l’extension ne l’ait injecté.

Un exemple clé de NIP-07 en action est le projet Keycast couvert ci-dessus. Le frontend web Keycast utilise NIP-07 pour signer les événements d’auth HTTP NIP-98 : l’application SvelteKit ne gère jamais la nsec de l’utilisateur directement. Elle appelle window.nostr.signEvent pour produire l’en-tête d’auth, puis envoie cet en-tête à l’API Keycast. Cette architecture signifie que le matériel de clé reste dans l’extension du navigateur tout au long du flux complet de gestion des clés d’équipe.

{
  "id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
  "pubkey": "7f8e9d0c1b2a3e4f5d6c7b8a9f0e1d2c3b4a5f6e7d8c9b0a1f2e3d4c5b6a7f8a",
  "created_at": 1747785600,
  "kind": 1,
  "tags": [],
  "content": "Hello from a NIP-07 signed event",
  "sig": "0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2cdd"
}

NIP Deep Dive : NIP-39 (identités externes dans les profils)

NIP-39 définit comment un utilisateur Nostr peut déclarer le contrôle d’identités de plateformes externes dans son profil. Chaque déclaration utilise une balise i à l’intérieur d’un événement kind:10011, affirmant la propriété d’un compte spécifique sur une autre plateforme avec une preuve qui peut être vérifiée indépendamment.

Chaque balise suit le format ["i", "platform:identity", "proof"], où platform:identity combine le nom de la plateforme et le nom d’utilisateur avec un séparateur deux-points (github:semisol, twitter:semisol_public). proof pointe vers un artefact vérifiable sur la plateforme elle-même.

Pour GitHub, la preuve est un ID Gist. L’utilisateur crée un Gist public depuis son compte GitHub contenant le texte Verifying that I control the following Nostr public key: npub1.... Un client vérifiant la revendication récupère https://gist.github.com/<identity>/<proof> et vérifie que le Gist a été rédigé par le nom d’utilisateur GitHub revendiqué et contient le pubkey attendu. Pour Twitter, la preuve est un ID de tweet, pour Mastodon un ID de post, et pour Telegram une référence de message dans un groupe public.

Le nom du fournisseur d’identité ne doit contenir que a-z, 0-9 et les caractères ._-/, et ne doit pas contenir :. Les noms d’identité doivent être normalisés en minuscules, avec l’alias principal utilisé quand plusieurs existent.

La discussion Namecoin .bit NIP-05 qui se déroule cette semaine montre le rôle de NIP-39 dans la pile d’identité plus large : elle fournit un moyen standardisé, indépendant du relais, de croiser une clé Nostr avec une identité établie ailleurs, sans nécessiter d’autorité de vérification centrale. Un client peut vérifier indépendamment la preuve en récupérant un artefact public sur la plateforme nommée, et la preuve est liée au pubkey Nostr spécifique dans le texte du Gist ou du tweet, pas à un identifiant de plateforme générique.

{
  "id": "b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3",
  "pubkey": "7f8e9d0c1b2a3e4f5d6c7b8a9f0e1d2c3b4a5f6e7d8c9b0a1f2e3d4c5b6a7f8a",
  "created_at": 1747785600,
  "kind": 10011,
  "tags": [
    ["i", "github:semisol", "9721ce4ee4fceb91c9711ca2a6c9a5ab"],
    ["i", "twitter:semisol_public", "1619358434134196225"],
    ["i", "mastodon:bitcoinhackers.org/@semisol", "109775066355589974"]
  ],
  "content": "",
  "sig": "1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3eff"
}

C’est tout pour cette semaine. Si vous construisez quelque chose ou avez des nouvelles à partager, DM-nous sur Nostr ou trouvez-nous à nostrcompass.org.