Cette semaine a été particulièrement riche en travaux sur les signers, les protocoles d’échange P2P et les versions majeures de clients phares. Amethyst v1.12.0 rassemble plus de 170 PR et ajoute les portefeuilles Cashu NIP-60, les nutzaps NIP-61, les flux d’applications logicielles NIP-82, la prise en charge des podcasts NIP-F4, la vérification des zaps on-chain via CLINK, les phases 1 et 2 de la migration iOS vers KMP ainsi qu’un mécanisme d’auto-rétablissement de Tor. Clave v1.0.0 (build 102) a été soumis à l’App Store, avec la signature en arrière-plan réveillée par notification push et la vérification des signatures entrantes sur iOS. Mostro Core v0.13.0 livre Protocol v2, qui remplace les échanges d’ordres via relais par des messages directs emballés en gift wrap avec NIP-44, tandis que Mostro v0.17.5 rend la caution anti-abus côté opérateur facultative et configurable. Signet v1.11.0 corrige un contournement de signature dans les commandes d’administration NIP-17 (messages privés emballés en gift wrap), qui permettait à quiconque disposant d’informations publiques de forger des commandes de coupe-circuit. Chama a publié sept versions consacrées à l’escrow en six jours, transformant la salle d’échange d’un mur de commandes en une conversation propre à chaque rôle. Côté signers, Amber v6.2.1, Clave (builds 100, 101 et 102), ainsi que Nostur 1.29.0, implémentent tous la nouvelle méthode de déconnexion NIP-46 fusionnée cette semaine (PR #2373). Zeus v13.1.0-rc1 et Amethyst prennent tous deux en charge les noffers CLINK, proposition d’interface Lightning commune pour les clés Nostr. Les groupes de relais NIP-29 ont reçu cinq propositions ouvertes portant sur les tags de bannière, les codes d’invitation, l’épinglage de messages, le signalement de groupes via des DM NIP-17 et le contrôle d’accès fondé sur les rôles.

À la une

Amethyst est le principal client Nostr pour Android, créé par Vitor Pamplona. v1.12.0 regroupe les 93 PR présentées comme travaux non publiés dans la Newsletter #25 (étiquetage des hashtags NIP-32, écran de podcast NIP-F4, morceaux de musique, signers éphémères, zaps on-chain avec filtre NIP-05) et la Newsletter #26 (poursuite de NIP-F4, fondations du watchdog Tor), auxquelles s’ajoute une nouvelle tranche substantielle cette semaine. Ces nouveautés se concentrent sur l’interface Cashu/nutzap, un pilote CLINK pour les zaps on-chain, un ensemble d’auto-rétablissement de Tor et la migration iOS vers KMP.

La prise en charge des portefeuilles Cashu NIP-60 et le rendu des nutzaps NIP-61 arrivent dans la PR #3075, avec une vue du solde par mint (PR #3115) et une carte de paiement unifiée (PR #3191) qui réunit adresses Lightning, zaps on-chain, mints Cashu et NWC sur un seul écran de paiement de profil (PR #3185). Un pilote CLINK de vérification des zaps on-chain est livré dans les PR #3039, PR #3177 et PR #3182. CLINK, Common Lightning Interface for Nostr Keys, est la même interface noffer que livre Zeus v13.1.0-rc1 cette semaine ; Amethyst ajoute une machine à états de vérification, un pilote de revérification et un montant minimal pour les zaps on-chain (PR #3030). La PR #3201 introduit les notes privées en emballant en gift wrap les réponses kind 1 destinées à des utilisateurs identifiés par un tag p, conformément à NIP-17 : l’éditeur produit ainsi une note publique ou une réponse de groupe scellée selon les destinataires.

Un ensemble complet de fiabilisation de Tor permet son auto-rétablissement : la PR #3053 met Arti à niveau vers la v2.3.0 avec un watchdog et des tests d’intégration ; la PR #3223 retarde les connexions aux relais routées par Tor jusqu’à ce que celui-ci soit prêt ; la PR #3224 limite l’amorçage d’Arti à 60 secondes afin qu’un réseau hostile ne puisse bloquer la boucle ; enfin, la PR #3231 rétablit automatiquement le service lorsque Tor est actif mais que tous ses circuits sont morts. La pile Tor récupère ainsi des changements de réseau et des cycles veille-reprise sans intervention manuelle. Les phases 1 et 2 de la migration iOS vers KMP sont livrées dans les PR #3047 et PR #3050, débloquant la CI iOS pour les modules quartz et commons et posant les bases d’une version iOS d’Amethyst.

Mostro Core v0.13.0 élimine l’intermédiaire des relais avec Protocol v2

Mostro est une plateforme d’échange P2P de bitcoins réglée sur Lightning, qui utilise Nostr comme carnet d’ordres et couche de communication des échanges. v0.13.0 de mostro-core, la bibliothèque Rust qui définit le protocole filaire, remplace le modèle de messagerie routée par relais par ce que le changelog appelle Protocol v2 : un transport direct NIP-44 reposant sur des événements kind 14. Les actions propres aux échanges circulent désormais sous forme de messages kind 14 emballés selon NIP-44 et liés à la clé propre à l’échange générée par le participant lors de la création de l’ordre, sans faire transiter toute la conversation par des événements publics adressables.

Avec le modèle précédent, toute la surface de conversation de l’échange était exposée à chaque relais transportant les événements. Le transport direct kind 14 conserve la configuration de l’ordre, le traitement des litiges et les métadonnées de règlement entre les deux parties et le daemon Mostro ; les relais ne voient que des enveloppes chiffrées. Outre ce changement de transport, la v0.13.0 lie aussi la preuve d’identité v2 à la clé de l’échange (journal des commits), éliminant une catégorie de risques de rejeu contre le nouveau protocole. Côté daemon, Mostro v0.17.5 rend la caution anti-abus facultative et configurable par l’opérateur : avant certains échanges, chaque partie peut devoir verrouiller une petite caution, restituée à l’issue normale et perdue en cas de blocage, d’absence ou de nuisance. La caution est activée au niveau de l’opérateur du nœud et non imposée à tout le réseau ; Mostro reste ainsi non dépositaire et chaque opérateur choisit son compromis entre fluidité du marché et résistance aux abus. Côté client, Mostro Mobile v1.2.8 livre 17 fonctionnalités compatibles avec cette nouvelle voie, dont la découverte des relais d’amorçage en remplacement de relais par défaut figés (PR #610), la caution anti-abus du maker à la création de l’ordre, cinquième phase de son déploiement (PR #608), et la conservation contextuelle des annulations d’ordres dans l’historique des notifications (PR #602). v1.2.9 a suivi deux jours plus tard, exposant depuis l’événement d’information du nœud la politique de caution anti-abus afin que l’utilisateur puisse consulter les règles de l’instance Mostro avant d’ouvrir un ordre (PR #617).

Signet v1.11.0 corrige un contournement de signature des commandes d’administration NIP-17

Signet est un signer bunker distant doté d’un coupe-circuit permettant à un administrateur de mettre le signer en panique, de le réactiver ou de vérifier son état via Nostr sans toucher à la machine hôte. v1.11.0 corrige une faille de sécurité : le chemin des commandes d’administration emballées en gift wrap selon NIP-17 ne contrôlait que l’auteur déclaré de la rumeur interne non signée, sans jamais vérifier le sceau signé. Comme les clés de conversation NIP-44 sont symétriques, un attaquant ne disposant que d’informations publiques — pubkey du signer, npub de l’administrateur et relais d’administration — pouvait forger de l’extérieur un gift wrap et exécuter n’importe quelle commande de coupe-circuit, notamment panic, resumeall ou alive. Le correctif appelle verifyEvent sur le sceau et lie l’auteur de la rumeur à sa signature : les contrefaçons non signées sont désormais rejetées à l’entrée. Les opérateurs de Signet devraient mettre à niveau rapidement ; la spécification et l’ancien chemin de code fournissent ensemble une recette de reproduction claire à un attaquant.

De Chama v3.2.0 à v3.5.0, la salle d’échange est repensée et le parcours des fonds renforcé

Chama est un client d’escrow P2P natif Nostr qui associe l’ecash Fedimint à un partage de secret de Shamir 2-sur-3 pour régler les échanges sans serveur. La Newsletter #26 couvrait la série v2.0.0 à v3.1.0, qui avait franchi le cap de l’application autonome et ajouté une vitrine par vendeur. Les six versions suivantes de cette semaine commencent avec v3.2.0 et se terminent avec v3.5.0 le 15 juin. Elles repensent l’interface de la salle d’échange autour d’une seule question propre à chaque rôle — que dois-je faire maintenant ? — et renforcent le parcours des fonds contre les défaillances partielles. v3.2.0 donne à l’acheteur, au vendeur et à l’arbitre leurs propres invites d’action codées par couleur, afin que chacun voie sa prochaine étape dans tous les états de l’échange. v3.3.0 resserre deux règles de consensus du moteur d’échange et nécessite une adoption coordonnée des clients pour prendre effet. v3.3.1 adapte les prix et les moyens de paiement à la devise communautaire du trader. v3.4.0 ajoute cinq correctifs de robustesse au parcours des fonds afin qu’un incident, une course ou un onglet fermé ne puisse coûter silencieusement des sats à l’utilisateur. v3.5.0 ajoute deux garde-fous côté client autour du rôle d’arbitre, le seul qui pourrait autrement faire pencher discrètement un échange.

Clave 1.0 arrive sur l’App Store avec la signature en arrière-plan réveillée par push

Clave est un signer distant NIP-46 pour iOS qui conserve la clé privée Nostr de l’utilisateur dans le trousseau de l’iPhone. Les applications demandent des signatures via un canal chiffré de bout en bout et ne reçoivent jamais la clé elle-même. v1.0.0 build 102 a été soumis à l’App Store cette semaine, marquant le jalon 1.0 après huit mois de bêtas TestFlight. Cette version livre la signature en arrière-plan réveillée par push : Clave peut déchiffrer une demande, vérifier les autorisations, signer et répondre alors que l’application est fermée, supprimant l’obligation de premier plan d’iOS qui limitait jusque-là la réactivité du signer. La vérification des signatures entrantes applique Schnorr BIP-340 au format canonique de sérialisation des événements NIP-01 — spécification de base définissant le hachage de chaque événement Nostr signé — ainsi qu’un garde-fou de fraîcheur contre le rejeu ; une application malveillante ne peut donc pas faire passer un événement resigné par le canal de réponse.

La version intègre aussi la couche de chiffrement NIP-44 actualisée, avec un modèle d’autorisations par kind et trois niveaux de sensibilité ; elle corrige le cas limite de signature à faible confiance où une demande « demander à chaque fois » renvoyait une erreur avant que l’utilisateur puisse l’approuver ; enfin, elle ajoute l’association multicomptes pour faire passer plusieurs identités par une même association d’application. Les associations bunker affichent désormais l’identité réelle de l’application grâce à l’extension de métadonnées de connexion NIP-46 proposée par Clave dans la PR #2381. La déconnexion propre utilise la nouvelle méthode logout de NIP-46, fusionnée dans la PR #2373, afin qu’une application associée puisse clore sa session sans dissociation manuelle. Des niveaux de confiance par application (Full, Medium, Low), avec dérogations par kind d’événement, un journal d’activité de chaque signature et la possibilité d’utiliser son propre proxy push complètent l’ensemble ; la pile du proxy est sous licence MIT et la matrice d’interopérabilité par client est suivie dans docs/nip46-compatibility.md.

Versions

Amber v6.2.1 ajoute la déconnexion NIP-46 et réduit la consommation du signer

Amber est le principal signer Nostr pour Android. v6.2.1 réduit la consommation due aux reconnexions des relais et aux pings websocket, écarte les relais morts du pool d’abonnements et cesse de réveiller l’appareil lors de la mise à jour de la notification du relais. La version prend aussi en charge la méthode de déconnexion NIP-46, permettant aux clients de clore proprement les sessions de signer distant — la même méthode fusionnée dans la spécification cette semaine par la PR #2373 — et analyse les événements kind 39701 (signets web publics), de sorte que les utilisateurs puissent les signer directement depuis Amber. Les paramètres ont été reconstruits avec des cartes Material 3 regroupées et des icônes distinctes ; un plantage de navigation sur l’écran des autorisations de l’application a été corrigé ; enfin, une fuite de connexions à la base de données par compte a été résolue en construisant les bases de façon atomique.

Nostur 1.29.0 livre les réponses anonymes et la déconnexion du signer distant

Nostur est un client Nostr pour iOS créé par Fabian. 1.29.0-desktop permet de répondre aux reçus de zap et d’envoyer des réponses anonymes. Côté signer, la version améliore la connexion au bunker distant, envoie un logout NIP-46 au signer distant lorsque l’utilisateur se déconnecte d’un compte et corrige un indicateur de chargement bloqué après l’échec d’une connexion distante. Elle résout aussi des problèmes de chargement des DM causés par des conflits entre les relais de DM et ceux de l’application, corrige les publications dupliquées après ouverture puis fermeture d’une réponse et affiche une miniature de média dans les lignes de notification.

Citrine v3.0.0 livre Negentropy, AUTH NIP-42 et le filtrage des relais onion

Citrine est un agrégateur local de relais pour Android. v3.0.0 est une version majeure qui ajoute Negentropy NIP-77 pour les synchronisations par réconciliation d’ensembles, ainsi que la prise en charge des signers externes et d’AUTH NIP-42 dans l’agrégateur de relais, et respecte les listes de sourdine NIP-51 lors des récupérations. L’agrégateur limite la récupération à trois relais par auteur, avec des relais sources et indexeurs configurables ; réutilise les données de suivi, de sourdine et de métadonnées mises en cache après redémarrage ou changement de réseau ; se met en pause sur les réseaux limités ou restreints ; et filtre les URL de relais onion lorsque le proxy sortant est désactivé. Les reposts intégrant des événements protégés sont rejetés et, par défaut, les listes de sourdine sont préservées des suppressions fondées sur l’âge.

FIPS v0.4.0-rc1 ajoute un transport mixnet Nym et la découverte mDNS sur le LAN

FIPS est l’implémentation du protocole de synchronisation maillée FIPS. v0.4.0-rc1 est compatible sur le fil avec la v0.3.0 : les maillages mixtes interopèrent et aucune mise à niveau simultanée n’est requise. La version ajoute deux moyens pour les nœuds de se trouver et de se joindre : un transport sortant via le mixnet Nym, avec une démonstration dans un seul conteneur et un exemple de relais mixnet, et la découverte facultative mDNS / DNS-SD sur le lien local. Une nouvelle requête show_metrics, limitée aux compteurs, permet à un scraper Prometheus de fonctionner sans coût sur le chemin critique ; le renouvellement des clés FMP et FSP a par ailleurs été renforcé pour rester sans interruption en cas de perte de paquets dans les deux sens.

Calendar by Formstr v1.6.1 et v1.6.2 ajoutent les notifications par événement

Calendar by Formstr est un client de calendrier NIP-52. v1.6.1 ajoute des préférences de notification par événement (PR #109), permettant d’activer ou de désactiver les rappels pour chaque événement du calendrier. v1.6.2 corrige la connexion avec Amber (PR #185), de sorte que la nouvelle négociation NIP-46 d’Amber 6.2.x fonctionne de bout en bout.

Bitchat v1.5.2 et v1.5.3 renforcent le transport Nostr et BLE

Bitchat est un client de chat maillé Bluetooth et Nostr. v1.5.2 limite le débit des notifications des pairs iOS pour éviter les inondations (PR #972) et renforce la validation Nostr ainsi que les contrôles des annonces BLE (PR #1012) : le chemin d’ingestion Nostr côté relais rejette désormais les messages mal formés avant qu’ils n’atteignent le gestionnaire du maillage local. v1.5.3 corrige en urgence un plantage au lancement causé par un dispatch_once récursif entre NostrRelayManager et NetworkActivationService (PR #1343).

Keep v1.0.5 déplace la politique du signer dans le cœur Rust audité

Keep est un signer Android enveloppant le cœur Rust keep. v1.0.5 se fixe sur keep v0.4.8 et corrige une course à l’initialisation du bunker (PR #296), afin que la négociation ne perde plus le premier événement sous charge ; remplit l’écran Authorized Clients depuis le callback onConnect du bunker (PR #291) ; et centralise le coupe-circuit dans une source de vérité unique dans keep-mobile (PR #284). Le cœur Rust en amont a publié v0.4.9 le 13 juin : il déplace la politique des signers NIP-55 et NIP-46 — décision d’autorisation, plafonnement de durée pour les kinds sensibles, expiration, chaîne d’audit à HMAC indexé détectant les altérations, confiance au premier usage envers l’appelant et limiteur persistant du débit de signatures — dans le cœur Rust audité, alors que cette logique était auparavant dupliquée en Kotlin. Il ajoute aussi une implémentation du chiffrement v3 NIP-44 ; ce cœur sera livré dans la prochaine version de keep-mobile.

ants v0.4.5 ajoute des liens vers les portails d’articles et rétablit Habla

ants est l’outil de recherche et de lecture Nostr de dergigi. v0.4.5 ajoute aux cartes des publications longues des actions propres aux articles : liens vers des portails d’articles, partage de leur naddr, copie du nevent et accès au JSON brut. L’ensemble des portails a été actualisé en rétablissant Habla, en remplaçant les destinations disparues et en supprimant le portail imwald. La version rétablit aussi le rendu des notes de bas de page avec conservation de la navigation par ancres internes, et attend une connexion au relais avant de récupérer le profil lors du rétablissement de la session afin que l’avatar d’en-tête soit correctement résolu.

Morganite v0.0.3 livre un cache Blossom local pour Android avec Tor à la demande

Morganite est un nouveau cache Blossom local pour Android créé par greenart7c3, l’auteur d’Amber et Citrine. Ce cache fait office de miroir local BUD-08 et élimine les blobs les moins utilisés dès qu’il dépasse 1 Go. v0.0.3 démarre Tor à la demande et l’arrête lorsqu’il est inactif pour économiser la batterie ; déconnecte le relais Nostr après la recherche d’un auteur pour éviter la consommation en arrière-plan ; corrige la consommation causée par un flux logcat non filtré et des clients HTTP non libérés ; et libère hors du thread principal les clients OkHttp remplacés. La version récupère aussi les relais de boîte de réception de l’utilisateur avant d’interroger la liste de serveurs Blossom — la découverte de blobs suit ainsi le modèle outbox — et télécharge le blob lors d’une requête HEAD s’il n’est pas déjà en cache, liant le préchauffage du cache à la demande réelle des clients.

Coracle 0.6.34 et 0.6.35 corrigent la connexion NIP-46, les flux périmés et le basculement des réponses

Coracle est un client web Nostr créé par hodlbod. 0.6.34 corrige la connexion NIP-46, un état de flux périmé empêchant la timeline d’accueil de s’actualiser après un changement de vue, et un commutateur de réponses qui, une fois activé, filtrait tout le contenu. La version reconstruit aussi les vues de flux et de listes, corrige un problème de marge de zone sûre sur les toasts et améliore le chargement des images. 0.6.35 est une petite version de suivi qui corrige le masquage des reposts lorsque les réponses sont désactivées : le filtre des reposts n’applique plus abusivement celui des réponses.

Zeus est un portefeuille Bitcoin et Lightning en auto-garde, doté d’une surface Nostr pour Wallet Connect et les paiements noffer. v13.1.0-rc1 ajoute sur iOS les paiements Nostr Wallet Connect NIP-47 sans file d’attente, en collaboration avec Primal, afin qu’une facture NWC payée n’attende plus dans une file en arrière-plan. La version prend en charge les paiements noffer CLINK : Zeus Pay génère un noffer CLINK pour chaque compte, ce qui permet de payer n’importe quel utilisateur de Zeus avec sa seule clé Nostr. Elle permet aussi de désactiver les zaps Nostr dans Zeus Pay, afin qu’un destinataire puisse couper le chemin des reçus kind 9735 sans désactiver NWC.

Alby Extension v3.14.3 migre les piles cryptographiques noble/scure du signer NIP-07

Alby Extension est l’extension de navigateur qui fournit la signature NIP-07 et Nostr Wallet Connect en plus de ses fonctions Lightning. v3.14.3 migre les piles @noble/curves, @noble/hashes, @noble/ciphers, @noble/secp256k1, @scure/bip32 et @scure/base vers leurs versions majeures v2 et v3. Le chemin du signer NIP-07 s’appuie sur ces bibliothèques cryptographiques pour signer les événements et chiffrer selon NIP-44 ; une mise à niveau majeure touche donc le format filaire produit par l’extension pour chaque demande de signature provenant d’un client web Nostr.

Mostro Mobile v1.2.8 et v1.2.9 prennent en charge Protocol v2 et affichent la politique de caution

Mostro Mobile est le client mobile de Mostro. v1.2.8 apporte côté client la prise en charge de Protocol v2 de mostro-core v0.13.0, présenté plus haut, et ajoute 17 fonctionnalités au total, dont la caution anti-abus du maker lors de la création d’un ordre (PR #608), la découverte des relais d’amorçage (PR #610), la conservation des annulations d’ordres dans l’historique des notifications (PR #602) et les limites de montant fiat sur l’écran de création d’un ordre (PR #605). v1.2.9 affiche la politique de caution anti-abus issue de l’événement d’information du nœud (PR #617), afin que l’utilisateur puisse connaître les règles de l’instance Mostro avant d’ouvrir un ordre.

De ZapBook build 4 à build 27 : multicomptes, publication de clés Marmot et réinvitations dans les cercles

ZapBook est une application sociale de lecture native Nostr créée par codeswot pour iOS et Android, organisée en cercles de lecture de 1 à 100 personnes qui partagent leurs étapes et s’envoient des sats par zap pour s’encourager. Entre le build 4, le 11 juin, et le build 27, le 15 juin, le projet a publié 17 builds tagués et fusionné 7 PR. La prise en charge de plusieurs comptes avec basculement fluide arrive dans la PR #25, permettant de conserver plusieurs identités Nostr dans l’application et de migrer les sessions entre elles. La publication initiale du key package Marmot (kind 443) se déclenche désormais automatiquement à la fin de l’onboarding (PR #20), condition préalable à la messagerie de groupe sur invitation dans les cercles de lecture. La gestion des membres retirés d’un cercle traite désormais correctement les nouvelles invitations (PR #24), corrigeant les cas où des membres réajoutés ne recevaient pas de nouvelle invitation après leur retrait. La série de versions déporte aussi l’inférence d’embeddings ONNX vers un isolate d’arrière-plan (PR #19) pour la recherche sémantique dans le lecteur, et intègre le service NWC avec un APP_ID_SUFFIX pour les configurations propres à chaque environnement, afin qu’un hub unique puisse desservir plusieurs builds de ZapBook.

Alby Hub v1.23.0 corrige la publication NIP-47 des applications supprimées et fait passer Bitrefill à NWC

Alby Hub est un hub Lightning et Nostr auto-hébergé. La surface non Nostr de v1.23.0 est vaste — canaux Just-in-Time, page Cards pour recharger des cartes de débit, backend de paiement Ark expérimental et page d’accueil de stories — et sort du périmètre de Compass. Côté NIP-47, la version cesse de retenter la publication d’informations NIP-47 pour les applications supprimées, de sorte qu’une connexion retirée ne republie plus continuellement son événement d’information kind 13194 (PR #2391), et remplace l’entrée personnalisée Bitrefill par une connexion NWC standard (PR #2420). L’option en lecture seule pour les applications du store (PR #2415) resserre les périmètres d’autorisation des applications NWC publiées dans la boutique du hub.

Autres versions

Versions plus modestes cette semaine, avec du contenu pertinent pour Nostr mais peu de matière par publication : Nostria v3.1.48 à v3.1.50, qui poursuit le déploiement des Web Bookmarks avec une meilleure fiabilité des notifications et l’optimisation de la base de données des fils d’événements dans la v3.1.50 ; Deepmarks v0.7.0 à v0.7.5, qui itère sur le client de signets sociaux NIP-B0 — le site du projet a aussi été ajouté cette semaine dans la PR #96 ; Keep v1.1.1 à v1.1.4, qui apporte quatre correctifs de builds reproductibles F-Droid par-dessus la version v1.0.5 du signer présentée plus haut ; NoorNote v0.11.1, v0.12.0, v0.13.0 et v0.13.1 pour le client de notes de bureau ; Boris v0.12.2 pour le lecteur Boris ; Nostr Mail Client v0.13.0 ; Feeder 2.21.1 ; nak v0.19.13, simple version de maintenance vide de la CLI Nostr ; Hashtree v0.2.68 à v0.2.71, qui actualise les caches de racines mutables des passerelles du système de publication adressé par arbre de hachage ; NYM v3.72.501 et v3.72.502, qui mettent à niveau l’implémentation de relais fondée sur Nostrify ; swift-nostr-client 0.3.0, 0.4.0 et 0.5.0, trois versions mineures soutenues par 85 PR fusionnées sur le client Nostr iOS ; lawallet-nwc v0.11.0, avec 18 PR fusionnées sur le pont LaWallet Nostr Wallet Connect ; Astraea v5.35.59 à v5.35.62, qui poursuit les itérations du client Nostr Astraea ; enfin, les bots DM Nostr vérifiés par NIP-05 de BTC Recharge et giftcardshop, ajoutés au répertoire des projets dans une nouvelle catégorie Shops.

Changements non publiés

diVine fusionne 119 PR en vue de sa prochaine version de vidéos courtes

diVine est un client natif Nostr de vidéos courtes en boucle, qui restaure les archives de Vine sur une infrastructure Nostr. Le projet a fusionné 119 PR cette semaine sans publier de version taguée. Les travaux substantiels touchant Nostr couvrent un chemin de publication vidéo donnant la priorité à REST, afin que l’absence de OK d’un relais ne soit plus signalée comme un échec (PR #5221 et PR #5220) ; le refiltrage des grilles de contenus sélectionnés et aimés lorsque la liste générale de blocage change (PR #5208) ; la récupération de la liste des conversations DM après une régression liée à la réinstallation (PR #5202) ; le rétablissement du badge Nostr sur les profils (PR #5218) ; et la transformation en liens des références nostr: dans les citations de commentaires (PR #5225). La pile de montage vidéo ajoute la fusion ou la suppression multisélection de clips, un canevas à zoom par pincement avec cache letterbox suivant le zoom, ainsi que le recadrage, la rotation et le retournement des clips.

Pollerama fusionne 15 PR avec une refonte du signer et une vague de fonctionnalités

Pollerama (dépôt formstr-hq/nostr-polls) est le client natif Nostr de sondages et de flux de la famille Form*, apparenté à Calendar by Form*, qui a publié la v1.6.2 cette semaine. La dernière version taguée de nostr-polls est v1.6.4, datant de mars : les travaux de la période sont donc prévus pour le prochain tag et ne sont pas encore publiés. Le flux de fusions est néanmoins soutenu : quinze pull requests ont été intégrées du 9 au 16 juin, avec des contributions d’abh3po, geralt-debugs et SIDDHANTCOOKIE. Côté signer, le projet remplace l’interface de signature existante dans la PR #198 et met à niveau son remplacement dans la PR #201. La PR #200 empêche les mises à jour de métadonnées kind 0 de se déclencher à la connexion, afin qu’une nouvelle session ne publie plus un événement de profil non demandé. La vague de fonctionnalités comprend un éditeur de profil permettant de publier depuis cette vue (PR #205), un meilleur parcours de repost (PR #209) et une découverte plus facile des sujets (PR #202). La prochaine version taguée reprendra tous ces changements.

Travaux sur les bibliothèques et les outils

La PR #375 de NDK et les travaux fusionnés dans les dépôts rust-nostr et nostr-tools ont été calmes cette semaine, avec une ou deux PR fusionnées chacun et aucune version taguée. L’activité s’est poursuivie sans tag de version pendant la période sur ContextVM SDK (1 PR fusionnée), mesh-llm (37 PR fusionnées, 8 ouvertes), Zap Cooking (26 PR fusionnées) et Routstrd (2 PR fusionnées).

Mises à jour des NIP et travaux sur les spécifications de protocole

Les travaux de protocole de cette semaine se concentrent en deux endroits : le renforcement des signers et la gouvernance des groupes NIP-29.

Fusionné cette semaine :

  • NIP-46 (Nostr Connect). La PR #2373 ajoute une méthode logout permettant à un client de terminer proprement une session de signer distant. Amber, Clave et Nostur en ont tous livré la prise en charge la même semaine.
  • NIP-CC (Community Chat). La PR #2365 met NIP-CC à jour pour renvoyer à la spécification moderne NIP-GC (Group Chat) pour les mécanismes côté client, alignant la spécification des salons communautaires sur la primitive canonique de chat de groupe.

Propositions NIP-29 ouvertes (gouvernance de groupes fondée sur les relais) :

  • Tags de bannière. La PR #2383 ajoute un tag banner à l’événement de métadonnées de groupe kind 39000.
  • Suffixe de code d’invitation. La PR #2380 introduit un suffixe de code d’invitation dans l’identifiant du groupe, afin qu’une invitation à usage unique puisse être encodée directement dans l’ID du groupe.
  • Épinglage des messages. La PR #2379 ajoute une action de modération update-pin-list et un événement kind 39005 pour diffuser l’ensemble des messages épinglés.
  • Signalement de groupes via des DM NIP-17. La PR #2377 définit un parcours permettant aux membres de signaler les abus au contact administratif du relais par des DM emballés en gift wrap selon NIP-17, gardant le trafic de modération hors du flux public d’événements du groupe.
  • Contrôle d’accès fondé sur les rôles. La PR #2376 ajoute une surface RBAC au-dessus de la séparation existante entre administrateurs et membres.

Propositions de suivi NIP-46 ouvertes :

  • Métadonnées du client dans la demande de connexion. La PR #2381 permet au client qui se connecte d’envoyer des champs facultatifs name, url et icon, afin que le signer affiche l’identité de l’application sur l’écran d’association. Clave build 101 implémente cette proposition.
  • Éviter les expirations silencieuses. La PR #2375 resserre la spécification : un signer qui attend une saisie de l’utilisateur garde la demande ouverte jusqu’à sa décision, corrigeant le mode d’échec que Clave build 100 a traité côté implémentation.

Autres travaux ouverts :

  • NIP-100 Sovereign Agent Identity Network (SNIN). La PR #2378 propose un protocole agent-à-agent pour l’identité et la découverte des capacités d’agents autonomes. La proposition est vaste et sera probablement divisée en éléments plus petits lors de sa revue.

Spécification Blossom. La PR #108 de BUD-00 a été fusionnée le 15 juin, élargissant la définition des BUD aux conventions côté client et aux formats de données construits sur les blobs Blossom que les serveurs n’implémentent pas. Ce changement intègre à la numérotation canonique des BUD comme BUD-10 — le schéma d’URI blossom: — et BUD-08 — les conventions de cache local mises en œuvre par Morganite cette semaine — alors qu’ils étaient auparavant considérés comme des extensions hors bande.

Analyse approfondie : NIP-77 (Negentropy)

NIP-77 définit un protocole de réconciliation d’ensembles pour les relais Nostr. Deux parties — un client et un relais, ou deux relais dans un pont — détiennent chacune un ensemble d’événements correspondant à un filtre et souhaitent converger vers leur union sans tout retransmettre. L’approche naïve consiste à envoyer tous les ID d’événements sur le réseau puis à calculer la différence ; pour un filtre chargé, le coût croît avec la taille du plus grand ensemble, quelle que soit l’ampleur de l’écart. NIP-77 ramène ce coût à une valeur proportionnelle à la différence symétrique.

La spécification repose sur deux messages de relais, NEG-OPEN et NEG-MSG. Un client ouvre une session de réconciliation avec ["NEG-OPEN", <subscription_id>, <filter>, <initial_message>], où <initial_message> est une charge utile Negentropy encodée en hexadécimal qui décrit la vue de l’ensemble côté client. Les réponses arrivent dans des frames NEG-MSG et les deux parties échangent des messages jusqu’à atteindre un point fixe. Chaque NEG-MSG réduit le désaccord — en divisant une plage en sous-plages dotées de leurs propres empreintes — ou termine une feuille — en listant les ID d’une petite plage pour permettre au destinataire de calculer directement la différence. Lorsqu’une partie détermine que l’autre possède des événements qui lui manquent, elle envoie une requête REQ normale pour ces ID ; lorsqu’elle possède des événements qui manquent à l’autre, la spécification laisse leur envoi à une publication EVENT normale de l’autre côté.

La structure de données sous-jacente est une variante séquencée de l’arbre de Merkle. Chaque événement de l’ensemble local est indexé par (created_at, id) et réparti en plages ; chaque plage porte une petite empreinte calculée à partir des ID qu’elle contient. Quand l’empreinte correspond entre le client et le relais, la plage a convergé et est ignorée. Lorsqu’elle diffère, la partie qui répond divise la plage en moitiés — ou sous-plages — et envoie l’empreinte de chacune, puis poursuit récursivement dans la zone de désaccord. Les plages feuilles, situées sous un faible seuil d’événements, sont envoyées telles quelles. Propriété essentielle : confirmer une plage ayant convergé ne coûte presque rien, quel que soit le nombre d’événements qu’elle contient.

L’ordonnancement selon created_at importe pour deux raisons. Premièrement, la pagination existante de Nostr utilise until et since avec le même horodatage ; un mécanisme de réconciliation peut donc reprendre entre deux sessions sans resynchroniser toute l’archive : il met en cache la borne supérieure et commence la synchronisation suivante à cet endroit. Deuxièmement, les divisions de plage sont déterministes avec une clé triée ; client et relais s’accordent donc toujours sur la prochaine limite sans message de négociation distinct. Le coût d’une synchronisation est d’environ O(d log n), où d est la taille de la différence symétrique et n celle du plus grand ensemble : bien inférieur au coût O(n) d’un envoi naïf de tous les ID et aux O(n) allers-retours de N requêtes REQ.

Trois compromis d’implémentation méritent d’être signalés. La taille de l’empreinte — 32 octets par plage dans la spécification — arbitre entre probabilité de collision et bande passante : des empreintes plus petites économisent des octets mais augmentent le risque d’une fausse correspondance faisant perdre des événements. Le seuil des feuilles — le moment où l’on cesse de diviser pour envoyer directement les ID — arbitre entre allers-retours et bande passante par message : un seuil plus petit exige davantage de tours, un seuil plus grand produit des messages feuilles plus volumineux. Enfin, le protocole suppose que les deux parties calculent la même empreinte sur la même plage ; cela requiert une sérialisation stable des paires (created_at, id) acceptée par les deux implémentations, d’où la précision de la spécification sur l’ordre des octets dans la construction de l’empreinte.

Un relais qui annonce NIP-77 dans son champ supported_nips NIP-11 permet aux clients d’effectuer une réconciliation à la place — ou en complément — d’une synchronisation ordinaire fondée sur REQ. Le client choisit le protocole selon son besoin : un nouvel abonnement qui veut recevoir les événements à venir utilise REQ, car il n’existe aucun état antérieur à réconcilier ; un miroir durable qui veut rattraper son retard après une interruption utilise NEG-OPEN, car la différence symétrique est faible par rapport à l’archive. Les deux chemins se complètent selon les contextes de déploiement.

Exemple d’échange NEG-OPEN :

→ ["NEG-OPEN", "sync-1", {"kinds":[1],"authors":["abc..."]}, "<hex initial Negentropy message>"]
← ["NEG-MSG", "sync-1", "<hex relay response>"]
→ ["NEG-MSG", "sync-1", "<hex client refinement>"]
← ["NEG-MSG", "sync-1", "<hex leaf with IDs the relay has and client lacks>"]
→ ["REQ", "fetch-1", {"ids":[...]}]
← [...EVENT messages...]
← ["EOSE", "fetch-1"]
→ ["CLOSE", "sync-1"]

Citrine v3.0.0 prend en charge NIP-77 dans l’agrégateur de relais cette semaine : pour la première fois, le relais local Android peut se réconcilier avec des relais externes au lieu d’effectuer des récupérations REQ en masse.

Analyse approfondie : NIP-61 (Nutzaps)

NIP-61 définit des paiements ecash Cashu pair-à-pair transmis sous forme d’événements Nostr. L’expéditeur publie un token Cashu verrouillé sur la clé publique du destinataire dérivée de Nostr, puis celui-ci le réclame auprès du mint au moment qui lui convient. Contrairement aux zaps NIP-57, qui exigent que le destinataire soit joignable via Lightning au moment du paiement, un nutzap est un token ecash autonome que son destinataire peut réclamer quand il le souhaite.

La spécification compose trois kinds d’événements avec la primitive de verrouillage P2PK de Cashu. Le kind 10019 est la recommandation de mints du destinataire : un événement remplaçable qui énumère un ou plusieurs mints dont il accepte les nutzaps, ainsi que la clé publique Cashu utilisée pour verrouiller les proofs à son intention. Cette clé diffère de la clé d’identité Nostr du destinataire ; il s’agit d’une clé propre au portefeuille, dérivée pour recevoir les nutzaps afin que la clé d’identité n’ait jamais à toucher les secrets ecash. Les expéditeurs lisent le kind 10019 avant l’envoi, afin de construire un token que le destinataire pourra réclamer auprès d’un mint auquel il fait déjà confiance.

Le kind 9321 est l’événement de paiement. Il contient un ou plusieurs tags Cashu proof — chacun renfermant une proof verrouillée par P2PK et liée à la pubkey nutzap du destinataire issue du kind 10019 —, un tag u avec l’URL du mint, des tags facultatifs e et a identifiant une note zappée, ainsi qu’un tag p pour le destinataire. Celui-ci reçoit le kind 9321 via son abonnement Nostr normal, vérifie que les proofs sont verrouillées sur sa pubkey nutzap auprès d’un mint figurant dans son propre kind 10019, les déverrouille avec la clé privée correspondante, puis les conserve dans son portefeuille NIP-60 ou les convertit vers Lightning. Le kind 7375 enregistre les proofs réclamées dans la chaîne d’événements du portefeuille du destinataire, afin qu’un portefeuille se resynchronisant depuis les relais ne comptabilise pas deux fois des proofs nutzap provenant de la même source.

Le modèle de confiance est le prix explicite de cette conception. Les mints Cashu détiennent la valeur sous-jacente ; un mint malveillant ou saisi peut refuser le remboursement. NIP-61 hérite de ce risque de garde de NIP-60 et ne cherche pas à l’éliminer. En contrepartie, cette conception offre des micropaiements possibles hors ligne et à finalité instantanée : le token est le paiement, le destinataire n’a pas besoin d’exécuter un nœud Lightning ni d’accepter des HTLC entrants en temps réel, et un expéditeur détenant des proofs auprès du même mint peut payer sans aucun saut réseau vers un dépositaire. L’annonce kind 10019 sert de garde-fou social : les expéditeurs qui choisissent un mint en dehors de l’ensemble de confiance du destinataire risquent de produire un token impossible à réclamer, ce qui rend prévisible la surface de remboursement du destinataire.

Par rapport à NIP-57, le chemin de vérification est aussi plus simple. Un reçu de zap NIP-57 est un événement kind 9735 publié par le service LNURL du destinataire ; le vérificateur doit récupérer l’endpoint LNURL et confirmer que la clé de signature du reçu correspond à celle annoncée par cet endpoint. Un nutzap inclut directement la preuve cryptographique de paiement — les proofs verrouillées par P2PK — ; tout vérificateur disposant des clés publiques du mint peut donc confirmer leur validité sans aller-retour vers un tiers. En contrepartie, vérifier un nutzap exige de comprendre les keysets du mint, alors que la vérification NIP-57 ne nécessite qu’une infrastructure LNURL standard.

Les deux formats de zap coexistent et se complètent. Les zaps NIP-57 restent adaptés aux destinataires disposant d’un routage Lightning et aux expéditeurs qui veulent des montants libellés en sats avec la sémantique de règlement de Lightning. Les zaps NIP-61 conviennent aux destinataires hors ligne, aux flux riches en micropaiements où les frais Lightning dépassent la valeur transférée et aux clients visant des utilisateurs sans infrastructure Lightning.

Exemple d’événement nutzap :

{
  "id": "a5f87fe2d4c8b9a0e3f1c4d5e6a7b8c9d0e1f2a3b4c5d6e7f8091a2b3c4d5e6f",
  "pubkey": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
  "created_at": 1750162800,
  "kind": 9321,
  "tags": [
    ["proof", "{\"amount\":21,\"secret\":\"...\",\"C\":\"...\",\"id\":\"...\"}"],
    ["u", "https://mint.example.com"],
    ["e", "8b39f4e5d6c7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3"],
    ["p", "c5d8a4e3b2a1f0e9d8c7b6a5949382716050403020100ffeeddccbbaa99887766"]
  ],
  "content": "Great post!",
  "sig": "f1e2d3c4b5a6978869504132c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f80192a3b4c5d6e7f80192a3b4c5d6e7f80192a3b4c5d6e7f80192a3b4c5d6e7f80192a3b4c5"
}

Amethyst v1.12.0 livre cette semaine un rendu natif des nutzaps NIP-61 aux côtés de son interface de portefeuille NIP-60 (PR #3075), faisant d’Amethyst le premier client Android majeur à afficher les nutzaps reçus dans la timeline et les soldes par mint dans le portefeuille.