Nostr Compass #36
Bentornati su Nostr Compass, la vostra guida settimanale a Nostr.
Questa settimana: Amber rafforza l’autenticazione relay e cifra i segreti memorizzati, Cambium firma per i siti web sotto carico di relay-auth, Citrine ospita gruppi e siti statici su un relay telefonico, Vector mette in coda la moderazione sotto spam e sincronizza i mute tra dispositivi, Sonar aggiunge risposte mesh annidate, Nostria pubblica podcast e Nail collega l’email come eventi gift wrap. Le release coprono lo stato di gruppo MDK, la coniazione di badge, l’accoppiamento QR del firmatario, la firma browser su Android e una libreria wallet-connect condivisa. Il lavoro di protocollo tocca patch sui commenti, metadati di file criptati, formattazione dei thread, garanzie di riavvio Marmot e liste di appartenenza Concord. Approfondimenti: badge e commenti.
Storie principali
Amber 6.5.0 chiude un confused deputy nell’autenticazione relay e cifra i segreti memorizzati
Amber è un firmatario Android NIP-55 (intent del firmatario Android) e NIP-46 (firma remota mediata da relay). La versione 6.5.0 chiude quattro lacune divulgate: un confused deputy nell’autenticazione relay che permetteva a qualsiasi chiamante di ottenere un evento kind 22242 NIP-42 (autenticazione client-relay) per relay che l’utente non aveva mai approvato; una lacuna di replay NIP-46; segreti di connessione e chiavi locali in chiaro ora cifrati a riposo con envelope; e un pacchetto di hardening in otto punti che copre l’autorizzazione del chiamante prima della decifratura, parsing dei permessi fail-closed, avvisi su ws:// in chiaro, schermate QR sicure, redazione dei log, azzeramento lazy delle chiavi al logout e uso opzionale del Keystore con dispositivo sbloccato.
La versione 6.5.1 ricifra i segreti NIP-46 memorizzati quando la chiave Keystore ruota dopo l’attivazione del requisito di dispositivo sbloccato e corregge un crash nell’editor dei permessi. La versione 6.5.2 smette di decifrare colonne che l’elenco applicazioni non renderizza mai, mette in cache l’handle Keystore, precarica la cache account all’avvio e debounce le notifiche di stato relay.
La 6.4.0 della scorsa settimana ha reso esplicite le decisioni di firma raggruppate; la serie 6.5.x cambia ciò che Amber autorizzerà in assoluto.
Cambium 0.4.0 firma per i siti web e alleggerisce i burst di relay-auth
Cambium è un proxy Android NIP-55 verso un firmatario hardware Heartwood tramite NIP-46. Sei release in due giorni.
La versione 0.4.0 estende la firma ai siti web. Una pagina può richiedere una firma tramite callback nostrsigner: convalidato senza ereditare i permessi concessi alle applicazioni native, così una scheda del browser non può prendere in prestito l’approvazione di un’altra app. La stessa release corregge la forma minima dell’evento prevista dalla specifica: un evento con solo kind e content ora firma correttamente, con Cambium che fornisce l’identità NIP-46 abbinata, il timestamp corrente e un array di tag vuoto prima di passare l’evento a rust-nostr. L’instrumentazione nativa rust-nostr è diventata un gate obbligatorio di integrazione continua nella stessa modifica.
La versione 0.3.6 ripara l’accoppiamento con firmatari conformi alla specifica. La build rust-nostr più vecchia di Cambium accettava solo la stringa letterale ack come risultato di una chiamata connect NIP-46, quindi un firmatario che risponde facendo eco al segreto dell’URI bunker — come chiede la specifica attuale e fa il firmware Heartwood — terminava l’accoppiamento con un errore di risposta inattesa. Il passaggio da rust-nostr 0.44.2 a 0.44.8 rende accettabili entrambe le forme, verificate contro hardware live e contro nak bunker, che continua a rispondere ack.
Le release da 0.4.1 a 0.4.3 riguardano il controllo di ammissione sotto carico. La versione 0.4.1 riserva uno slot in coda a reazioni, post, cancellazioni e cifratura prima dell’autenticazione relay e della decifratura in background, limita le chiamate in coda, le scarta una volta scaduto il chiamante e restituisce un risultato terminale di indisponibilità in caso di sovraccarico invece di aprire una schermata di firma in primo piano. La versione 0.4.2 scarta sessioni NIP-46 scadute o inattive da tempo prima della richiesta successiva e lascia che copie concorrenti dello stesso evento di autenticazione kind 22242 condividano una firma hardware. La versione 0.4.3 ammette al massimo una sfida di autenticazione distinta per identità nel worker hardware, non ritenta mai l’autenticazione internamente e apre un cooldown di sessanta secondi per identità dopo un timeout rispondendo comunque ai duplicati esatti in cache. Le misure nelle note di release provengono da un telefono GrapheneOS che guida Amethyst: un burst a freddo ha prodotto trentatré risposte immediate di sovraccarico e tredici richieste completate senza timeout del firmatario, e un login fresco durante un burst di autenticazione è tornato 1,254 secondi dopo l’approvazione.
Citrine 3.1.0 trasforma un relay telefonico in host di gruppi e di siti
Citrine è un relay Android on-device. La versione 3.1.0 aggiunge tre capacità che cambiano ciò che il relay può ospitare.
Il supporto per NIP-29 (gruppi gestiti da relay), la specifica di gruppo basata su relay in cui il relay stesso detiene appartenenza e stato di moderazione, significa che un telefono può ospitare un gruppo invece di unirvisi. Il supporto per NIP-86 (API di gestione relay), l’API di gestione relay che espone azioni amministrative via JSON-RPC autenticato, arriva con una schermata impostazioni, così allowlist e ban possono essere gestiti dall’API come dall’app. Il supporto per NIP-5A siti web statici permette al relay di servire nsite ai client web, con un elenco di navigazione modernizzato che include icone, ricerca, ordinamento per ultimo aggiornamento, progresso di installazione, descrizioni e un insieme configurabile di relay per il recupero, predefinito su nsite.run, nos.lol e nostr.land.
La superficie di moderazione è cresciuta parallelamente nella stessa release. Il ban locale di una chiave pubblica offre ora di eliminare gli eventi memorizzati di quell’autore, un elenco configurabile REJECTED_KINDS blocca i kind che l’operatore non vuole memorizzare e il controllo accessi può importare da elenchi esistenti. Uno strumento di rebroadcast spinge gli eventi memorizzati verso relay selezionati, dando a un archivio tenuto sul telefono un modo per reseme la rete. La release rimuove anche l’estensione WebSocket permessage-deflate, stringe il percorso caldo delle query, corregge Tor che non si avvia o non si ferma quando cambia l’impostazione di esposizione via Tor e sposta i log in un database locale con logcat limitato alle build di debug.
Vector 0.4.2 fa sopravvivere la moderazione di community a un’ondata di spam
Vector è un messenger desktop e Android Concord. La versione 0.4.2 si concentra sulla moderazione sotto carico.
I ban rapidi si sovrascrivevano a vicenda. Ora si mettono in coda, si accumulano e si risolvono come un’unica operazione, così bannare un’ondata di account costa una rotazione di chiave invece di una per account. Accettare un invito a una community sciolta nel frattempo spiega perché e rimuove l’invito da ogni dispositivo dell’utente, e sciogliere una community posseduta la elimina dall’elenco community ovunque — una correzione arrivata nella versione 0.4.3. I messaggi di community che arrivano durante un catch-up in background non fanno più suonare le notifiche come se fossero appena stati inviati, e l’indicatore di digitazione scade dal momento dell’invio così un segnale ritardato non può restare in un canale.
L’elenco di community shardato definito da Concord ha avuto un passaggio di revisione cross-client con Armada, l’altro client Concord. I rename non gonfiano più l’elenco, i pareggi si risolvono identicamente su entrambi i client e i dati invariati non vengono più ripubblicati sui relay. Il mute è uscito dal percorso dei messaggi diretti: un utente può silenziare qualcuno direttamente da una community senza cronologia precedente, e il mute si applica a notifiche e badge su canali e messaggi diretti lasciando visibili i messaggi stessi. I messaggi fissati sono diventati una superficie condivisa del canale con link cliccabili, e le modifiche a un messaggio fissato lo seguono ovunque appaia. Elenchi di blocco, mute e nickname ora si sincronizzano tra i dispositivi dell’utente, così come le chat fissate. La versione 0.4.3 smette anche di annunciare che l’utente sta digitando quando un altro client Nostr è connesso con la stessa identità, e sblocca il bootstrap Tor su Windows, che si bloccava al quindici percento su x64 e ARM64.
Sonar porta risposte annidate a un messenger mesh con NIP-C7
Sonar è un messenger mesh Bluetooth e Nostr. La versione 0.1-alpha.13.1 aggiunge risposte in stile Signal sulla chat kind 9 NIP-C7, più menzioni, riassemblaggio Bluetooth limitato, limiti di backup, verifica delle firme del percorso mesh e fallback push FCM. Le versioni 0.1-alpha.13.2 e 0.1-alpha.13.3 correggono i crash all’apertura della chat su Android e la sovrapposizione della tastiera su iOS.
Nostria inizia a pubblicare podcast e chiede ai relay di contare
Nostria è un client web. Le versioni 4.1.70 e 4.1.71 aggiungono la pubblicazione di podcast per abbonati premium, con episodi come eventi Nostr firmati. La versione 4.1.69 usa COUNT NIP-45 (richieste di conteggio relay) per totali di reazioni, risposte e zap nei feed e completa la localizzazione. La 4.1.67 della scorsa settimana ha ampliato l’amministrazione delle community criptate.
Release
MDK 0.9.14: cronologia di gruppo fail-closed tramite creazione di gruppi più rapida
MDK è il kit di sviluppo Rust per Marmot, un protocollo di messaggistica di gruppo criptata trasportato su Nostr. La versione 0.9.12 rende fail-closed diversi percorsi di stato di gruppo invece di indovinare. Un’ancora di fork mancante è ora un errore fatale (PR #1329), una proposta di uscita viene persistita atomicamente così un crash non lascia una partenza applicata a metà (PR #1360), e il replay degli incidenti rifiuta di indovinare un formato su stream JSON delimitati da newline senza manifest (PR #1140). I test di convergenza si sono ampliati parallelamente, con recupero cross-route della cronologia conservata (PR #1350), garanzia di convergenza cross-adapter (PR #1372) e campagne di convergenza isolate generalizzate (PR #1357). Le diagnostiche di rifiuto relay vengono conservate invece di collassare in un errore generico (PR #1361).
La versione 0.9.13 è arrivata il 18 agosto con formato di storage v2 (PR #1421), binari di migrazione e scritture delta che sostituiscono gli snapshot live dell’account (PR #1435), più catch-up degli inviti più rapido (PR #1444) e binding macOS (PR #1402). La versione 0.9.14 ha seguito il 19 agosto con rifiniture alla creazione di gruppi: immagini fondative precaricate (PR #1498), batching KeyPackage (PR #1494), conservazione atomica del messaggio iniziale (PR #1497) e pubblicazione del profilo con relay di proprietà dell’account (PR #1495). MarmotKit 0.9.14 e wn-agent 0.9.14 partono con il crate principale.
Divine Mobile 1.0.20: coniare un badge senza uscire dall’app
Divine Mobile è un client di video brevi che pubblica e recupera video tramite Nostr. La versione 1.0.20 permette a un utente di coniare un badge NIP-58 (eventi di premiazione firmati descritti nel primo approfondimento di questo numero) e consegnarlo a qualcuno senza uscire dall’app. Toccare un badge su un profilo spiega cosa era richiesto per guadagnarlo, la parte della specifica di solito non implementata perché l’evento di definizione e quello di premio sono memorizzati separatamente.
Il resto della release è lavoro client: tema chiaro, ritaglio, rotazione e capovolgimento nell’editor stop-motion, bozze a un tocco dal registratore, tempistica dei sottotitoli rispetto al video, un feed che deprioritizza il materiale già visto, supporto screen reader su editor, registratore e schede profilo, gestione del movimento ridotto e impostazioni account che gestiscono email e password Divine e collegano o scollegano account. I video eliminati lasciano ora lo stato locale e i segnalibri persistono. La 1.0.19 della scorsa settimana ha rafforzato l’isolamento degli account e la validazione dei messaggi privati; l’emissione di badge è una nuova superficie di pubblicazione sopra tutto ciò.
ClipRelay 0.2.0: accoppiare un firmatario con una fotocamera
ClipRelay sincronizza gli appunti tra dispositivi tramite Nostr. La versione Android 0.2.0 aggiunge login QR nostrconnect://, così un utente può accedere con un’app firmataria su un altro telefono, e la scansione con fotocamera degli URL bunker, eliminando l’abitudine di incollare una stringa contenente segreti tramite un messenger. La connessione bunker ora scade dopo sessanta secondi invece di restare appesa, e il pulsante di retry dopo un login Amber fallito funziona. La versione desktop 0.2.0 porta timeout e correzioni alla scheda di login.
La versione 0.1.4 ha aggiunto sincronizzazione degli appunti sensibili con scadenza breve sui relay, relay di sessione del firmatario fissati e una sonda di liveness che richiede un round trip reale invece di un EOSE sintetizzato localmente. La 0.1.3 della scorsa settimana ha ripristinato le connessioni dopo periodi di inattività.
Bark 1.3.9: un firmatario browser che gira su Android
Bark è un’estensione browser che fornisce l’interfaccia NIP-07 window.nostr, l’oggetto che una pagina web chiama per richiedere firma o cifratura. La versione 1.3.9 dichiara il supporto Android per la build Firefox, così l’elenco add-on si installa su un telefono. Firefox su Android non implementa alcuna API windows, quindi ogni approvazione che apriva una finestra popup sarebbe stata rifiutata; la superficie di approvazione ora ricade su una scheda in primo piano dove la chiusura nega, un’azione di revisione la porta avanti e lo sfondo la chiude una volta risolta la richiesta. Le note di release registrano la verifica su Pixel 10 Pro XL con GrapheneOS e Firefox 153.0.4, e affermano chiaramente che Chromium su Android compila fuori il sottosistema delle estensioni, quindi nessun browser Android derivato da Chromium può eseguire Bark.
La versione 1.3.8 ha corretto un difetto di interoperabilità NIP-46 nella direzione opposta. Bark sondava un dialetto compatto di firma Heartwood inviando l’evento come oggetto JSON, che i firmatari tipizzati rigorosamente inclusi nak e bunker basati su rust-nostr non possono analizzare e scartano silenziosamente, quindi la firma restava appesa. La sonda viene ora inviata solo ai firmatari che si identificano come Heartwood, e ogni altro firmatario riceve una chiamata standard sign_event dalla prima firma in poi.
Bray 3.0.0 e Toll Booth 6.0.0 passano a una libreria wallet-connect condivisa
Bray e Toll Booth pagano entrambi tramite NIP-47 Nostr Wallet Connect, la specifica che permette a un’applicazione di richiedere pagamenti a un wallet tramite eventi Nostr criptati. Bray 3.0.0 e Toll Booth 6.0.0 dichiarano ciascuno un breaking change nell’adozione di nwc-kit per i pagamenti wallet, e Toll Booth rimuove il flusso di credenziali del pagatore nella stessa modifica. Entrambi pubblicano build riproducibili il cui output era byte-identico su due runner indipendenti, con l’hash del tarball stampato nelle note di release così un lettore può verificare l’artefatto del registry.
Tre patch Toll Booth sono seguite: 6.0.1 fissa la chiave host del deploy negoziata, 6.1.1 fissa cashu-ts alla versione che il suo patch targetta, e 6.1.2 ripristina una build di immagine.
NoorNote 1.3.4: unirsi a community criptate da un link di invito
NoorNote è un client Nostr per desktop, web e Android. La versione 1.3.4 aggiunge community Armada e Concord criptate come addon: un utente entra tramite link di invito, vede le community unite elencate nelle impostazioni e riceve notifiche di attività. La stessa release aggiunge un controllo per nascondere i post di citazione esterni, gli highlight che citano un paragrafo di un articolo web, globalmente o per autore, con i repost di essi nascosti e i propri highlight mantenuti visibili. Anche la risoluzione del profilo è stata riparata, così i profili non vengono più renderizzati come chiave pubblica troncata o segnaposto anonimo.
La versione 1.3.5 aggiunge un espansore per note lunghe e corregge il layout dell’input del link di invito Armada. La 1.3.2 della scorsa settimana ha spostato la scoperta degli articoli nel grafo sociale; l’appartenenza alle community è una superficie separata.
Mostro sposta la chat delle dispute fuori dal gift wrap
Mostro è un daemon di trading peer-to-peer i cui ordini e messaggi viaggiano come eventi Nostr, con mostro-core come libreria condivisa e Mostro Mobile come client. Mobile 1.3.2 migra la chat delle dispute dal gift wrap NIP-59 (involucro che nasconde i metadati) a un envelope di chat kind 14 e sostiene il backlog con cursori duraturi per conversazione. mostro-core 0.14.5 serializza l’identificatore rumor dentro il gift wrap (PR #164), 0.14.4 corregge un bug nella media dei rating (PR #163), e Mobile 1.3.1 passa a server Blossom che conservano allegati di chat criptati. Usare il daemon 0.18.2 o 0.18.4.
NYM 3.73.522: chat di gruppo criptate e store locale criptato
NYM è un client Nostr con integrazione assistant propria. La versione 3.73.522 cifra lo store SQLite locale dopo che 3.73.521 ha raffinato la chat di gruppo criptata, e 3.73.520 corregge una rottura della content-security-policy e la presentazione duplicata dei nuovi messaggi.
Morganite 0.0.4: verificare un blob prima di metterlo in cache
Morganite è un server Android Blossom (protocollo media in cui un file è indirizzato dall’hash SHA-256 del contenuto e servito da qualsiasi host che lo detiene). La versione 0.0.4 verifica l’hash di un blob durante il download in un unico passaggio prima di metterlo in cache, il controllo che rende significativo il content addressing sul lato ricevente. La release traccia anche la dimensione della cache incrementalmente invece di riscansionare la directory a ogni salvataggio, sposta le chiamate di rete bloccanti su thread di input e output, riusa istanze Tika per il rilevamento MIME e persiste i log in un database locale.
Nuovi scoperti
Nail porta l’email su Nostr come eventi gift wrap
Nail è un bridge email e client web con licenza MIT del team Formstr, il gruppo dietro Formstr e nostr-calendar. È andato live il 18 agosto con PR #7, una modifica di 22 file che ha aggiunto tag k agli eventi mail, recupero chiavi nelle impostazioni e un messaggio di benvenuto. Il deployment gira su mailstr.app, che serve il record NIP-05 (schema DNS che mappa un nome di dominio a una chiave pubblica Nostr) _smtp del bridge.
La mail stessa è un evento Nostr. Le costanti del client definiscono un rumor mail kind 1301 trasportato dentro un gift wrap kind 1059 NIP-59, così un messaggio raggiunge il destinatario tramite lo stesso involucro che nasconde i metadati usato per i messaggi diretti privati. I relay di consegna provengono da un elenco inbox kind 10050 NIP-17 (messaggi diretti privati) con un elenco relay kind 10002 NIP-65 dietro, le cartelle sono etichette kind 1985 NIP-32 (eventi etichetta) sotto un namespace mail, e le impostazioni client vivono in un evento dati applicazione kind 30078 NIP-78. Gli allegati più grandi di 60.000 byte vanno su Blossom invece che nell’evento, perché NIP-44 (cifratura) limita il plaintext cifrato a 65.535 byte. Un indirizzo è un npub su un dominio, e un dominio locale senza record NIP-05 è trattato come una casella inesistente.
La metà bridge è un server Node LMTP che gira accanto a un deployment mailcow senza patcharlo: Postfix instrada i domini corrispondenti al bridge, e il bridge reinietta le risposte via SMTP. Questo design impone una risposta onesta alla domanda più difficile in un bridge email: cosa prova un header From. Il percorso di ricezione di Nail classifica ogni messaggio in uno di quattro stati di provenienza: il bridge configurato l’ha sigillato e rifiuta di inoltrare un mittente non verificato a monte, l’utente l’ha sigillato personalmente, il record NIP-05 dell’indirizzo risolve sulla chiave di sigillatura, o nulla corrobora l’header. In questo ultimo caso l’interfaccia ricade sulla chiave pubblica di sigillatura, l’unica identità che l’evento può effettivamente provare. Le chiamate API del bridge sono autenticate con eventi HTTP firmati NIP-98 (autenticazione HTTP tramite eventi firmati).
Glow memorizza etichette wallet sui relay sotto un’identità derivata da passkey
Glow è un wallet Lightning self-custodial Breez. Il login passkey deriva un’identità Nostr, e l’elenco delle etichette wallet viene caricato e salvato sui relay sotto quell’identità, con duplicati byte-identici collassati attraverso copertura relay parziale.
Modifiche non rilasciate
Amethyst ricostruisce il flusso decisionale di autenticazione relay
Amethyst è un client Nostr Android. Un blocco di lavoro unito rimodella come gestisce l’autenticazione client-relay NIP-42. L’interfaccia dei permessi e il flusso decisionale sono stati ridisegnati (PR #3899), l’autenticazione ora attende la risoluzione di una sfida invece di andare in timeout (PR #3905), i nuovi account autenticano sempre con i relay per impostazione predefinita (PR #3931), e una scelta «accedi sempre» vale anche per relay che l’account non usa direttamente (PR #3937). L’autenticazione riconosce anche gruppi NIP-29 e community Concord come luoghi a cui ci si è uniti (PR #3906), così un gruppo ospitato su relay non sembra un relay sconosciuto ogni volta che viene aperto.
Altre due modifiche toccano superfici di protocollo. Il mining proof-of-work sotto NIP-13 (nonce PoW) aggiorna created_at mentre mina e ottiene un’analisi del percorso GPU (PR #3911), e gli host napplet a schermo intero gestiscono gli inset della tastiera (PR #3932). Anche un backup guidato delle chiavi al primo avvio con punto d’ingresso nelle impostazioni è stato unito (PR #3909), insieme alla possibilità di silenziare chat pubbliche (PR #3939).
nostrord implementa una proposta non unita di chiave di cifratura
nostrord è un client chat Nostr organizzato attorno a gruppi con scope relay. Ha unito un’implementazione di NIP-4e, una proposta non unita per disaccoppiare la cifratura dei messaggi dalla chiave d’identità che Compass ha descritto l’ultima volta nel numero del 15 luglio. L’account annuncia la propria chiave di cifratura kind 10044, tiene la metà privata localmente e decifra i messaggi diretti in arrivo in processo, togliendo bunker o estensione browser dal percorso di lettura (PR #261). L’accoppiamento dispositivo sui kind 4454 e 4455 sposta quella chiave su un secondo dispositivo, e un auto-archivio ripubblica la cronologia indirizzata alla nuova chiave. L’invio indirizzava prima la chiave annunciata (PR #247), e un follow-up ha corretto l’accoppiamento che negoziava con successo senza consegnare la chiave (PR #271). La pull request afferma che il formato wire segue l’implementazione Jumble già deployata dove diverge dalla proposta aperta, collocando la definizione operativa di questa specifica nel codice spedito invece che nel documento.
L’identità di gruppo è stata ristretta nello stesso batch. Un identificatore di gruppo è ora unico solo all’interno del suo relay (PR #269), quindi lo stesso identificatore su due relay è trattato come due gruppi (PR #272), e i post dei thread vengono renderizzati come post di forum (PR #274). Anche il churn di connessione che produceva ripetute richieste di firma kind 22242 è stato fermato (PR #268), la stessa classe di pressione sul firmatario su cui Cambium ha lavorato per tre release questa settimana.
nostream aggiunge un monitor relay e conia codici invito
nostream è un’implementazione relay TypeScript. Ha unito un cluster worker e uno scheduler di probe che pubblicano eventi di monitoraggio relay NIP-66 (specifica di discovery che permette a un monitor di annunciare liveness e dati di capacità su altri relay) (PR #724), con schema impostazioni e default (PR #689) e test di integrazione (PR #733). Uno strumento da riga di comando conia ora codici invito NIP-43 (schema metadati di accesso relay) (PR #732), e il relay annuncia finalmente proof of work NIP-13 nella sua lista supportata (PR #680), che aveva implementato senza annunciare. I job data vending machine hanno anche ottenuto migrazione di persistenza e repository (PR #727), e il relay intercetta ora NIP-90 (richieste job data-vending-machine) e le registra tramite il repository job (PR #729).
rust-nostr corregge un identificatore gift wrap e rifiuta repost protetti
rust-nostr è la libreria Rust e l’SDK dietro gran parte del lavoro client Rust e mobile di questo numero. Ora garantisce che l’identificatore rumor sia calcolato prima che il sigillo gift wrap venga cifrato (PR #1444), la stessa classe di difetto che Mostro ha corretto nella propria libreria questa settimana. Il relay locale rifiuta un repost di un evento protetto NIP-70 (PR #1445), la protezione per cui quella specifica esiste, e il parsing delle risposte NIP-47 tollera importi mancanti e null (PR #1450) invece di fallire su un wallet che li omette. Il parsing degli URL relay è stato rafforzato (PR #1451).
NDK aggiunge messaggi diretti post-quantum e rimuove una dipendenza GPL
NDK è un kit di sviluppo Dart per Nostr. Ha unito cifratura ibrida post-quantum per i messaggi diretti usando ML-KEM-1024, il meccanismo lattice key-encapsulation standardizzato come FIPS 203 (PR #713), affiancandolo all’accordo di chiavi classico invece di sostituirlo. Una modifica separata ha sostituito un’implementazione Dilithium solo GPL-3.0 con fips204, lo standard di firma ML-DSA (PR #712), rimuovendo un vincolo di licenza per le applicazioni che incorporano il kit. Le connessioni sono passate a un’identità ciascuna (PR #710).
Nostter aggiunge liste segnalibri, badge profilo e upload Blossom
Nostter è un client web. Ha unito il supporto per entrambe le forme standard e legacy delle liste segnalibri NIP-51 (PR #2311), aggiornato la gestione dei badge profilo NIP-58 (PR #2281), aggiunto un uploader media Blossom (PR #2298), e ora mostra un identificatore NIP-05 (nome di verifica DNS) nell’autocompletamento delle menzioni (PR #2303).
Zap Cooking lega le route admin a richieste firmate e cifra le connessioni wallet memorizzate
Zap Cooking è un sito di ricette costruito su eventi long-form Nostr. Un batch di sicurezza cifra le stringhe di connessione Nostr Wallet Connect memorizzate a riposo dentro un envelope NIP-44 (PR #622), sostituisce un confronto di chiave pubblica spoofabile sulle route amministrative con autenticazione HTTP NIP-98 (schema che firma un evento per autorizzare una richiesta HTTP) (PR #626), e cancella i dati account al logout limitando i record NIP-46 pendenti (PR #627).
Aggiornamenti NIP e lavoro di specifica del protocollo
NIP
Nessuna pull request è stata unita in nostr-protocol/nips in questa finestra. Sei proposte sono state aperte dopo la chiusura del numero precedente, tre il 18 agosto dopo che la bozza aveva circolato per la prima volta.
NIPs PR #2438 propone NIP-9A, patching basato su commenti. Una patch è un commento kind 1111 che referenzia l’evento patchato come parent il cui content inizia con l’etichetta letterale PATCH, seguita da righe di patch. Una riga che inizia con un numero modifica il content del target nella forma <index> -<deleted> +<inserted> <caratteri inseriti>, contati in caratteri Unicode invece che byte, e una riga che inizia con t sostituisce un tag leggibile come title, description, subject o picture. Il design è deliberatamente retrocompatibile: un client che non capisce il formato mostra la patch come un commento etichettato ordinario, e un client che lo capisce applica la patch e nasconde il commento. La proposta nomina i kind 1, 11, 1111, 24 e 1621 come patchabili e chiede a scrittori e lettori di rifiutare patch troppo grandi, troppo numerose o pubblicate molto dopo l’evento originale, un tentativo esplicito di evitare che la funzione diventi un canale generale di modifica per eventi immutabili.
NIPs PR #2437 propone la cifratura file per NIP-94, la specifica di metadati file che descrive un file caricato in un evento kind 1063. Aggiunge tre tag opzionali: encryption-algorithm, con aes-gcm come unico valore elencato, più decryption-key e decryption-nonce codificati in hex. Le semantiche dei tag cambiano di conseguenza, con m che descrive il MIME type prima della cifratura, x che tiene l’hash del file cifrato e ox quello dell’originale, e qualsiasi sorgente thumb, image e fallback cifrata con la stessa chiave e nonce. Lo scopo dichiarato è che un operatore Blossom pubblico che ospita i byte non possa capire cosa siano, e l’autore inquadra la modifica come copiare le proprietà di cifratura dei messaggi diretti NIP-17 nei metadati file così lo stesso trattamento funziona dentro un tag imeta.
NIPs PR #2436 emenda NIP-7D, la specifica di thread forum costruita su eventi thread kind 11 con commenti kind 1111 NIP-22 come risposte. Aggiunge una sezione di formattazione che afferma che un post di thread può essere formattato come una nota kind 1, con immagini inline, link e riferimenti NIP-27, e potrebbe anche supportare Djot, un linguaggio di markup leggero con grammatica non ambigua. L’argomento dell’autore è che lasciare la formattazione non specificata invita a un’implementazione Markdown by default, e la pull request indica squalk come implementazione Djot esistente.
NIPs PR #2439 aggiunge i metodi assign e unassign a NIP-86 (comandi di gestione relay), così un amministratore relay può concedere permessi admin a un’altra pubkey senza condividere la chiave master.
NIPs PR #2442 succede alla proposta audio track che Compass ha trattato a gennaio mentre quella bozza restava aperta; la pull request precedente da allora si è chiusa e questa è in produzione su lightning.fm come eventi track kind 31337, con oggetti release kind 31339, profili band, contributor per traccia e split zap NIP-57 opzionali mantenendo le vendite in NIP-99. Il contratto di interoperabilità è pubblicato su lightning.fm/interop, e il publisher desktop e il daemon seller self-hosted sono open source.
Marmot
Marmot PR #416 è stata unita il 13 agosto e aggiunge un contratto di durabilità e riavvio al core del protocollo. I documenti adottati definivano già convergenza deterministica, materiale parent candidato conservato, ordine publish-before-apply e comportamento fail-closed su cronologia mancante, senza una regola univoca su cosa succede quando un processo viene interrotto alle giunture tra loro. La modifica definisce fatti logici recuperabili, equivalenza di riavvio, confini di interruzione di publish e convergenza, transizioni observer-atomiche, gestione di materiale mancante o corrotto e recupero degli effetti applicativi, poi aggiunge scenari di conformità crash e riavvio per ciascuno. Lascia transazioni, journal, snapshot, strategia di replay, scheduler e formati di storage definiti dall’implementazione, e afferma che non richiede cambiamenti di wire encoding. Il fallimento specifico che esclude è una pubblicazione accettata esternamente ma non confermata localmente, o un branch selezionato parzialmente applicato, che produca risultati di protocollo dipendenti dall’implementazione dopo un riavvio.
Concord e CORD
Concord PR #18, trattata in precedenza nel numero scorso come proposta aperta, è stata unita il 15 agosto. Shardizza l’elenco di community criptate attraverso eventi kind 33302, rimuove il limite di cinquanta appartenenze e pota le voci ritirate così l’elenco resta entro i limiti di dimensione relay. Le note di release di Vector questa settimana registrano la metà client di quella modifica, inclusa la risoluzione dei pareggi e la decisione di smettere di ripubblicare dati invariati.
Concord PR #22 propone broker audio e video di proprietà della community. L’entità metadati CORD-02 porterebbe un elenco opzionale av_brokers accanto ai relay, evolvendo per edizione come il resto di quell’entità, e il rendezvous CORD-07 attingerebbe da quell’elenco, o dal broker del membro quando la community non ne pubblica nessuno, ordinato dal tie-break esistente keyed per stanza. Il tag broker sulla presenza resta leggibile e utile per segnalare uno split residuo, e l’argomento della proposta per declassarlo dal routing è diretto: instradare su di esso lascia che l’input non fidato di un altro membro superi l’istruzione della community.
Concord PR #23 rende normativo un comportamento implementativo esistente in CORD-05. Prima di persistere un join, l’edizione metadati genesis del proprietario deve aprirsi sotto le chiavi consegnate, con piani ruotati ancorati alla coppia di compaction. La pull request afferma fin dall’inizio che non è mai stata una vulnerabilità live: l’accettazione bundle di Vector rifiuta già un bundle la cui root consegnata non può aprire la genesis del proprietario e non parcheggia mai un invito per una community già detenuta, e Armada scarta già qualsiasi bundle che sposterebbe la base di una community detenuta. La lacuna era che nessuno dei due comportamenti era richiesto dalla specifica, quindi un client conforme alla lettera avrebbe potuto spedire la versione vulnerabile.
I documenti di upgrade Blossom, le proposte applicazione Napplet e la specifica Gamma Markets non hanno registrato modifiche in questa finestra.
Approfondimento NIP
Badge (NIP-58)
NIP-58, definito dalla specifica primaria, dà a un’identità Nostr un modo per conferire un token nominato a un’altra, e al destinatario controllo su se appare sul profilo. Il problema che affronta è che ogni affermazione su una persona su Nostr altrimenti è solo una nota: non c’è struttura che dica chi ha emesso un’affermazione, come si chiama, come appare o se il soggetto l’ha accettata. I badge danno a quell’affermazione tre eventi firmati separati con tre intenzioni di autori separati codificate in essi.
Le meccaniche sono costruite da una definizione indirizzabile, un premio e un elenco di visualizzazione. Una definizione badge è un evento kind 30009 pubblicato dall’emittente, indirizzabile tramite il suo tag d, così l’emittente può rivedere i tag name, description, image e thumb del badge più tardi senza cambiare l’identificatore a cui punta altro. Il premio è un evento kind 8 pubblicato dallo stesso emittente, con un tag a che tiene la coordinata 30009:<issuer-pubkey>:<d-identifier> della definizione e uno o più tag p che nominano i destinatari. L’elenco di visualizzazione è un evento kind 30008 pubblicato dal destinatario con il valore fisso d profile_badges, che elenca coppie di tag a e e dove il tag a è la coordinata di definizione e il tag e l’evento premio specifico. Quelle coppie sono ordinate e lette come coppie: un tag a il cui premio corrispondente è assente, o un tag e la cui definizione corrispondente è assente, viene ignorato, così un badge referenziato a metà non viene renderizzato silenziosamente.
I compromessi di design sono visibili in ciò che la specifica rifiuta di fare. Non c’è meccanismo di revoca né scadenza, quindi un premio è un’affermazione permanente dell’emittente su un momento nel tempo, e un emittente che cambia idea può solo cambiare la definizione a cui punta il premio. Non c’è trasferimento, quindi un badge non circola come token. Non c’è nozione di registry di emittenti fidati, il che spinge l’intera questione della fiducia sul client e sul lettore: un badge vale esattamente quanto vale la chiave pubblica del suo emittente per chi lo guarda. La specifica concede anche ai client la latitudine di mostrare meno badge di quelli elencati dal destinatario e di scegliere quale dimensione immagine renderizzare, così un profilo non diventa un muro di grafica scelto interamente da terzi.
La specifica adiacente più vicina è NIP-51, la specifica liste, e confrontare le due mostra perché i badge hanno bisogno di tre eventi invece di uno. Una lista è un autore che cura riferimenti; l’autore della lista è l’autore dell’affermazione. Un badge divide l’autorialità a metà, con l’emittente che firma che il premio è avvenuto e il destinatario che firma di accettarne la visualizzazione. Nessuna delle due parti può produrre il risultato visibile da sola, ed è ciò che separa un badge da un’etichetta auto-applicata.
Un premio kind 8 live recuperato da nos.lol e relay.primal.net questa settimana:
{
"id": "08504dec368939bd63849a349cab83dea0ac199a852129dbf68cf35fe5c64e96",
"pubkey": "bef514bd58c8ceea4beb9e6b84a8d983935f7be26f49e14df68098f1ba64156e",
"created_at": 1787051248,
"kind": 8,
"tags": [
["a", "30009:bef514bd58c8ceea4beb9e6b84a8d983935f7be26f49e14df68098f1ba64156e:blocks_orange_league"],
["p", "92dfa05d915196a7a09152fa3f57871debfd422e1d278ac5af266a70c3350b1f", "wss://relay.damus.io"]
],
"content": "Badge awarded!",
"sig": "5bf0218dfec5e56b47339b0b4b992cceedd2e18798fb3d47cafea51850c00827f66251e4a3e08190370e04a5e1d4d092eeb441141b7219acdd18b80290a022f8"
}
Le implementazioni attuali coprono emissione, visualizzazione e lettura. Divine Mobile 1.0.20 conia e conferisce un badge dentro l’app e spiega un badge guadagnato quando un lettore lo tocca, Nostter PR #2281 aggiorna la gestione dei badge profilo in un client web, e Amethyst pubblica eventi premio con il proprio tag client, uno dei quali appare nei dati relay accanto all’esempio sopra.
Commenti (NIP-22)
NIP-22, definito dalla specifica primaria, fornisce un evento commento generale per rispondere a cose che non sono note di testo breve. Il threading delle note brevi aveva già NIP-10 (convenzioni tag di risposta), le cui convenzioni tag sono cresciute attorno al kind 1 e alle sue catene di risposta. NIP-22 esiste perché un video, un articolo, un evento calendario, una pagina wiki o un URL ha bisogno di una struttura di risposta che identifichi che tipo di cosa viene risposta, e che funzioni quando il target è indirizzabile o è una risorsa esterna senza alcun evento Nostr.
Le meccaniche ruotano attorno a una distinzione di maiuscole/minuscole. Un commento è un evento kind 1111 che porta due insiemi di tag: tag maiuscoli che descrivono la radice della discussione e tag minuscoli che descrivono il parent immediato. E, A e I nominano un evento radice, una coordinata indirizzabile radice o un identificatore esterno radice, K nomina il kind della radice e P l’autore della radice. I minuscoli e, a, i, k e p nominano gli stessi fatti sul parent, che è la radice stessa per un commento di primo livello e un altro commento kind 1111 per una risposta annidata. Separarli significa che un client può recuperare un’intera discussione con un filtro sui tag radice maiuscoli, senza percorrere la catena di risposte, mentre renderizza correttamente l’annidamento dai tag parent minuscoli. Le varianti I e i portano identificatori esterni nel formato NIP-73, ed è ciò che permette a un thread di commenti di attaccarsi a una pagina web, un episodio podcast o un libro.
I compromessi riguardano soprattutto ciò che NIP-22 rifiuta di assorbire. La specifica afferma che i commenti non devono essere usati per rispondere a note kind 1, il che evita che due modelli di threading competano sugli stessi oggetti e lascia NIP-10 dove già funziona. L’annidamento è permesso ma la radice resta fissa, quindi un thread profondo non perde mai il suo ancoraggio anche quando eventi intermedi non sono disponibili. I tag kind sono la parte portante: un client che recupera un commento senza il suo target può comunque capire a cosa sta guardando da K e k, e decidere se può renderizzare quel kind. Ciò che la specifica non fornisce è alcun modello di ordinamento o moderazione, quindi ordine di visualizzazione, collasso e nascondimento sono interamente policy del client.
Rispetto a NIP-10, la differenza sta nel typing. NIP-10 assume che il target sia una nota e codifica la posizione in un thread; NIP-22 codifica esplicitamente identità e kind del target e non assume altro su di esso. Quel typing esplicito è il motivo per cui le proposte più recenti in questo numero puntano al kind 1111: un commento porta già un’affermazione machine-readable su a cosa è attaccato.
Un commento kind 1111 live recuperato da nos.lol e relay.primal.net questa settimana, in risposta a un altro commento sotto un video:
{
"id": "c8d335f8bfea58ecd1a943d6000fb2045f4bddf4a36c67df53eb661671f7ab45",
"pubkey": "3e911baba55ae247339cf805dd6ff49ad2cd6bee84ac44e088ce66450c49104f",
"created_at": 1787062681,
"kind": 1111,
"tags": [
["E", "1c492f2bac17b79d66934a340fa43d8d30d0aea4c9fa329346c05573ef912d70", "", "482d024b8acfde50e7429e5ac561d764f3a53a8b4fb0b6975369d9f0926ef839"],
["A", "34236:482d024b8acfde50e7429e5ac561d764f3a53a8b4fb0b6975369d9f0926ef839:e64ba9ea157b1a315caff51dbca656ed73ce817d4494e3966adf24055a86f5c5", ""],
["K", "34236"],
["P", "482d024b8acfde50e7429e5ac561d764f3a53a8b4fb0b6975369d9f0926ef839"],
["e", "7a14723b9ef999e74b1757a0fb74942cb6c121138d4ddafe096a57a67ed0a442", "", "8b69e548402afa997343d73e8088224a440f256350f6257b61acc4bb1fa4af4f"],
["k", "1111"],
["p", "8b69e548402afa997343d73e8088224a440f256350f6257b61acc4bb1fa4af4f"],
["client", "Divine", "31990:d95aa8fc0eff8e488952495b8064991d27fb96ed8652f12cdedc5a4e8b5ae540:divine-mobile", "wss://relay.divine.video"]
],
"content": "niiice",
"sig": "a5517fdea07647efa7ab1730fbea8df882690bba667e93ea5aeba4a73be6a49af1ee17c045535483650caf41dbbcb0897d5803fa39b59f395fd6f9bb193bb789"
}
I tag maiuscoli tengono il video e il suo autore mentre i minuscoli e e k puntano al commento parent, che è la forma descritta dalla specifica. Implementazioni che leggono e scrivono kind 1111 includono Divine Mobile, il cui tag client appare nell’evento sopra, Amethyst, i cui commenti appaiono negli stessi risultati relay, e nostrord, che renderizza i post dei thread come post di forum questa settimana. Il formato patch proposto in NIPs PR #2438 si costruisce sullo stesso kind.
Inviate un DM NIP-17 per condividere un progetto o una notizia tramite il progetto Nostr Compass.