Nostr Compass #26
A organização Marmot Protocol abre três novos repositórios para um rascunho de protocolo v2 e uma linhagem de clientes nativos: um workspace Rust chamado darkmatter, um app SwiftUI iOS darkmatter-ios e um app Kotlin/Compose Android darkmatter-android. O Flutter Whitenoise original é arquivado. A Chama comprime dezessete lançamentos em uma semana e cruza a linha de app independente na v3.0.0 antes de entregar uma reescrita completa da UI da sala de negociação e vitrines por vendedor na v3.1.0, em cima de compartilhamentos Shamir apenas do titular, substituição de árbitros, roteamento de comunidade mundial e notificações de negociação de ponta a ponta. A Coracle lança um serviço pago de relay hospedado apoiado pela stack open source Caravel e zooid, com integração profunda com Flotilla planejada. Angor muda para mainnet por padrão na v0.2.30 e entrega um teste de financiamento UAT de 3 usuários na v0.2.29. Amethyst entrega 41 PRs não lançados continuando o trabalho de NIP-32 / NIP-F4 / Tor da semana passada. NIP-67 (dica de completude EOSE) e autocompletar de NIP-50 são mesclados, fechando duas lacunas de correção de longa data no protocolo de relay central. NIP-GART propõe um formato de fio de preservação de privacidade para alertas de emergência, e NIP-46 ganha um método de logout.
Destaques principais
Marmot v2 (Dark Matter): redraft do protocolo, clientes nativos, app Flutter arquivado
Três novos repositórios surgiram sob a organização GitHub marmot-protocol esta semana, juntos formando a forma de progresso inicial de um rascunho do protocolo Marmot v2 e uma linhagem de clientes nativos que substitui a linha do app Flutter. darkmatter (Rust, criado em 13 de maio, trinta e quatro commits nos últimos sete dias) mantém o rascunho do protocolo v2 em spec/, um motor CGKA baseado em OpenMLS em crates/cgka-engine, um simulador de conformidade com testes de propriedade, e um modelo formal Tamarin para provas de convergência. darkmatter-ios (Swift, criado em 25 de maio) é um cliente SwiftUI apoiado por um xcframework UniFFI MarmotKit vendorizado gerado a partir do workspace Rust. darkmatter-android (Kotlin/Jetpack Compose, criado em 25 de maio) fica sobre os mesmos bindings Rust. O Flutter Whitenoise original foi marcado como whitenoise-archive (“ARQUIVADO: Este era o app Flutter original do White Noise”); um novo repositório Dart whitenoise carrega a linha Flutter ativa em paralelo.
Leia isto como progresso inicial em direção a um Marmot mais confiável, não como uma virada terminada. O README do darkmatter se rotula como “Rascunho candidato do protocolo Marmot v2, motor CGKA e workspace de conformidade” e diz diretamente: “MDK permanece a implementação Rust do protocolo implantada até que este rascunho e motor sejam adotados”. Dentro do workspace, a crate cgka-engine está marcada como 0.1.0, “único consumidor interno, não estável em semver”. Cada página de spec traz “Status: rascunho para revisão interna”. Três estrelas no repositório do workspace e zero nos apps iOS e Android confirmam que o trabalho está pré-anúncio. Direção, escopo e disciplina são o sinal aqui; a prontidão para produção não é a alegação.
O rascunho do protocolo torna concretos os deltas de v1 para v2. A extensão MLS marmot_group_data monolítica do MIP-01, que carregava nome do grupo, descrição, pubkeys de admin, id de roteamento de grupo Nostr, lista de relays, dados de imagem do grupo e configurações de mensagens que desaparecem sob um único guarda-chuva desde o início do Marmot, é dividida em componentes de app versionados: marmot.group.profile.v1 para nome e descrição, marmot.group.admin-policy.v1 para pubkeys de admin, marmot.transport.nostr.routing.v1 para o nostr_group_id aleatório e a lista canônica de relays, marmot.group.blossom.image.v1 para hash da imagem, chave de criptografia, nonce e chave de upload, e marmot.group.message-retention.v1 para segundos de mensagens que desaparecem. Cada componente é dono dos seus bytes exatos e do seu próprio caminho de versionamento, então um recurso futuro pode revisar um componente sem forçar o resto do estado do grupo a repisar o consenso da extensão MLS. As credenciais MIP-00 também ganham um novo documento fundamental account-identity-proof-v1.md, chamado como “novo em v2 e disruptivo”. A prova de identidade agora vive na sua própria superfície, separada da construção do KeyPackage.
Os deltas de biblioteca sustentam a retrabalho do spec. cgka-engine é a nova máquina de estado local do grupo: ela envolve OpenMLS, é dona dos estados de época Stable, PendingPublish, Merging e Recovering, traduz intenções em commits MLS, retorna valores tipados IngestOutcome e GroupEvent para cada envelope de transporte de entrada, e explicitamente não entrega nem transporte nem persistência. Uma trait TransportPeeler separa Nostr do motor, e uma trait StorageProvider separa SQLite (via storage-sqlite, apoiado por SQLCipher) do motor. O MDK de hoje empacota tudo isso junto; dividir as camadas permite que um motor fique sob um transporte de relay Nostr agora e sob os também entregues transportes de fluxo QUIC e broker mais tarde, sem reescrever o modelo de convergência. A convergência em si é documentada como distributed-convergence.md e provada em um modelo Tamarin que cobre seleção determinística de branch, elegibilidade fechada por política, reprodução de âncora retida, rejeição de branch obsoleto, reordenação de entrega, duplicação, invalidação de saída de app, transferência welcome/commit, consumo de proposta e limitação de saída durante sincronização. Testes de propriedade em Rust então verificam que o motor segue as mesmas regras com objetos OpenMLS reais e a estrutura do simulador. Trabalho de confiabilidade em métodos formais desta escala está ausente da stack Marmot atual.
Ambos os clientes nativos abandonam Flutter por toolkits de UI nativos da plataforma. darkmatter-ios é puro SwiftUI com uma Notification Service Extension que descriptografa despertares de push MIP-05 no dispositivo, vendoriza um pacote Swift MarmotKit gerado construído a partir do workspace Rust, e se registra sob o bundle ID dev.ipf.darkmatter e grupo de app. darkmatter-android é Kotlin e Jetpack Compose, com uma build orientada por just que produz um APK arm64-v8a assinado e lê endpoints de telemetria de local.properties. O README do Android declara o princípio arquitetural diretamente: “Dark Matter é dona dos dados do protocolo e os armazena em SQLite. O app Android deve renderizar esses dados, gerenciar o comportamento da plataforma Android e manter o estado do ciclo de vida da UI. O app Android não deve se tornar uma segunda base de dados para dados de Dark Matter”. Isso espelha a disciplina de fronteira que o README do cgka-engine impõe na camada Rust, aplicada à camada de UI.
Clientes nativos importam para Marmot porque a fraqueza mais citada do protocolo tem sido a confiabilidade móvel sob condições de entrega irregulares: despertares de notificação de prazo perdido, corridas de commit MLS durante flaps de rede, limites de busca em segundo plano que encalham avanços de época. SwiftUI e Compose dão aos clientes acesso direto a primitivos de processamento em segundo plano da plataforma que o Flutter alcança através de uma ponte de plugin, e o caminho de binding UniFFI mantém a lógica do protocolo em um único workspace Rust entregue como uma biblioteca estática em ambas as plataformas. A linha do Flutter Whitenoise continua no repositório whitenoise não arquivado, então o anúncio é aditivo: uma nova linhagem de cliente nativo roda ao lado do app Flutter enquanto o spec v2 converge. A troca de produção do MDK ou do app Whitenoise atual espera pelo rascunho, motor e clientes atingirem lançamentos prontos para produção.
Chama v2.0.0 até v3.1.0: escrow P2P independente em uma semana
O cliente de escrow P2P nativo do Nostr introduzido na Newsletter #25 na v1.3.0 entregou dezessete lançamentos taggeados nos últimos sete dias, terminando na v3.1.0 em 9 de junho com uma reescrita da UI da sala de negociação e vitrines por vendedor. A trilha de versões conta a história: v2.0.0 é a base DISRUPTIVA, então v2.0.1, v2.0.2 e v2.0.3 fecham as lacunas do trilho de financiamento Fedi WebView; v2.1.0, v2.2.0, v2.3.0 e v2.3.1 reforçam a camada de árbitros; v2.4.0, v2.5.0 e v2.6.0 adicionam superfícies de auto-custódia e roteamento de comunidade mundial; v2.7.0, v2.8.0, v2.9.0 e v2.10.0 camadam cópia de chave em inglês simples, aplicações de grupo, arbitragem de prazo de disputa e reputação. v3.0.0 amarra o pacote com notificações de negociação de ponta a ponta, e v3.1.0 em 9 de junho redesenha a tela de negociação em torno de uma espinha de progresso Reservado → Bloqueado → Liquidado, cartões de ação coloridos por papel e uma classe de listagem de vitrine por vendedor (swaps curados, livros de empréstimos e faturas).
O pivô arquitetural vive na v2.0.0. O formato LOCK de escrow mudou para que cada compartilhamento de uma divisão Shamir 2-de-3 seja criptografado apenas para seu titular (sharePolicy holder-only-v1). O ecash ao portador da federação não reconstrói mais a partir de um único participante sozinho, fechando um caminho onde uma parte maliciosa com seu próprio compartilhamento e um compartilhamento mantido pela federação poderia completar a negociação sem consentimento. Clientes pré-2.0 falham em voz alta com “não consegue encontrar seu compartilhamento”; a negociação não pode completar em um cliente obsoleto, e nenhum fundo é perdido no processo. Um bloqueio v2.0 requer que cada parte na v2.x liquide. A v2.0.0 também adicionou vitrines multi-unidade e uma visualização de Mercado apenas em sats.
A v2.1.0 introduziu a substituição de árbitros: o compartilhamento do árbitro no índice 2 de Shamir agora é criptografado para uma ordem de prioridade determinística sobre o pool de árbitros da comunidade, então um árbitro ausente pode ser substituído sem encalhar a negociação. A v2.2.0 provou que a substituição funcionou em campo em uma negociação de ₿121 e adicionou backups de substituição de cura. A v2.3.0 fechou a última lacuna de front-running de árbitros verificando a associação do árbitro à comunidade da listagem no momento do bloqueio, e a v2.3.1 fechou a corrida irmã onde um slot de árbitro auto-atribuído era uma prévia até o bloqueio os assentar.
As superfícies de auto-custódia chegaram na v2.4.0 (frase de recuperação BIP-39 para a carteira ecash Fedimint, armazenada criptografada no Nostr) e v2.5.0 (backup master nsec que é dono da identidade Nostr e da semente da carteira). A v2.6.0 retrabalhou o onboarding em torno de um seletor de comunidade global para que usuários em países sem uma Chama local sejam roteados para a federação mais próxima; builds anteriores rebatiam o usuário sem fallback. A v2.7.0 reescreveu a tela de chave de recuperação em inglês simples (“a única chave para sua conta e o dinheiro nela; Chama nunca a vê e não pode redefini-la; se você perder, ninguém pode recuperar sua conta”). A v2.8.0 adicionou aplicações de grupo, tema escuro/claro, e adicionou dois novos kinds de evento (38120 roster, 38121 aplicação). A v2.9.0 mudou a resolução de disputas no prazo: negociações contestadas que atingem o vencimento agora resolvem por decisão do árbitro; comportamento anterior fazia reembolso automático. O lançamento é marcado COORDINATED para que todas as partes em uma disputa devem atualizar. A v2.10.0 adicionou classificações de polegar para cima/polegar para baixo por negociação como um novo kind de evento 38123.
A v3.0.0 é o marco onde o app para de precisar de uma comunidade de coordenação para operar. Notificações de negociação de ponta a ponta pingam o usuário apenas em transições de estado acionáveis: contraparte bloqueou os sats, pagamento pronto para reivindicar, disputa requer a decisão do usuário como árbitro, ou negociação liquidada ou expirada. Um toggle na tela Eu liga ou desliga as notificações, e o prompt de permissão dispara apenas quando o toggle está habilitado. O dedup fire-once impede que uma recarga de estado dispare uma tempestade de alertas. Um bug de guardrail chama-errada também foi fechado no PR #103, onde versões anteriores podiam carimbar uma listagem com o rótulo de uma chama mas a federação de outra chama. Bundles desktop para Windows e Linux são entregues com o lançamento; o dmg macOS é retido até que assinatura e notarização cheguem.
Chama agora se junta a Mostro e Shopstr como um marketplace nativo do Nostr, distinguido por arquitetura sem servidor, escrow Shamir 2-de-3 apoiado por Fedimint, criptografia de compartilhamento apenas do titular, e o único dos três que entrega um cliente desktop e móvel autocontido sem uma comunidade de coordenação.
Coracle Hosting: serviço de relay pago mais stack Caravel open source
Em 3 de junho, Hodlbod anunciou o Coracle Hosting em hosting.coracle.social, um serviço de relay de comunidade hospedado que aceita pagamentos lightning recorrentes por NWC ou cartão. O serviço é alimentado por Caravel, o frontend de cobrança e provisionamento da Coracle, e zooid, um runtime de relay que hospeda muitos relays virtuais em uma única máquina. Ambos são open source no gitea auto-hospedado da Coracle. Caravel entrega com integração opcional livekit e Blossom que operadores podem alternar por relay. Um tier gratuito com limites de contagem de membros permite que operadores avaliem o serviço antes de comprometer detalhes de pagamento.
Hodlbod é sincero sobre o modelo de negócio: monetizar open source vendendo uma versão hospedada de uma stack que qualquer outra pessoa também pode rodar. O fosso competitivo é a integração Flotilla, que é o próximo passo planejado. Flotilla é dona da superfície do usuário, então a opção hospedada servida de dentro da Flotilla se torna o caminho padrão para qualquer usuário que prefira infraestrutura gerenciada. Hodlbod ofereceu adicionar outros operadores Caravel ao seletor de hospedagem alternativa da Flotilla se eles entrarem em contato, mantendo a porta aberta para um mercado de hospedagem federado.
Caravel se junta a relay.tools como uma plataforma pública de provisionamento de relay Nostr com tiers de membros pagos. relay.tools precede Caravel e entrega como o serviço criador de relay dominante hoje, com seu próprio diretório de relays de comunidade e fluxos de entrada de membro pago ou moderador. O recurso distintivo do Caravel é a stack coordenada: o runtime de relay (zooid), o frontend de cobrança e provisionamento (Caravel em si), e o seletor do lado cliente (integração Flotilla, ainda em voo) entregam como um design. O outro recurso distintivo é a densidade de muitos-relays-por-processo do zooid, onde relays de clientes compartilham um único processo host para que o operador amortize custos de hospedagem em muitas pequenas comunidades. Este é o mesmo argumento de densidade que tornou hospedagem web compartilhada viável nos anos 2000 iniciais, aplicado à camada de relay do Nostr.
Lançamentos
Angor v0.2.29 e v0.2.30: padrão mainnet e teste de financiamento UAT de 3 usuários
Angor v0.2.29 em 4 de junho e v0.2.30 em 8 de junho são os dois lançamentos desta semana para o protocolo descentralizado de financiamento Bitcoin-e-Nostr. A mudança de destaque da v0.2.30 é o PR #893, que muda a rede padrão para mainnet. Angor ainda entrega como um lançamento alpha instável, mas a mudança de padrão-mainnet sinaliza que o protocolo passou da fase apenas-testnet para os clientes desktop e móvel. A v0.2.30 também entrega um fluxo móvel de criar-projeto de único toque com upload de imagem e reset de scroll (PR #889) e resolve uma condição de corrida onde o spinner de fatura lightning podia travar (PR #890).
A v0.2.29 adicionou um teste UAT de ponta a ponta no PR #881 cobrindo envio de fundos de 3 usuários em 10 rodadas com gastos não confirmados, o primeiro teste de fluxo de financiamento multi-usuário na suíte de testes do Angor. O lançamento também adicionou um plano de implementação para um CLI Angor e servidor MCP (PR #792), com melhorias no CLI para o fluxo de teste MCP no PR #880. O PR #885 por DavidGershony corrigiu uma fatura lightning Boltz que usava a rede errada após uma troca de rede em runtime, um bug que teria aparecido em produção após o padrão mainnet da v0.2.30. Configurações agora oferecem uma purga opcional de arquivo de carteira de recuperação durante limpeza de dados (PR #883).
Sprout v0.3.15: atualização de TTL de canal efêmero e comandos slash ACP
Sprout v0.3.15, lançado em 10 de junho, é o oitavo lançamento em uma sequência que começou com a v0.3.7 em 2 de junho. Newsletter #25 cobriu a sequência v0.3.1 a v0.3.6 com o trabalho de integração mesh-llm e seções de canal; v0.3.7 até v0.3.15 são a jusante disso, focados em polimento e algumas adições voltadas ao usuário. A mudança mais visível ao usuário é uma atualização de TTL para canais efêmeros no PR #902: quando um usuário desarquiva um canal efêmero, Sprout estende o time-to-live do canal para que o desarquivamento não re-arquive imediatamente sob o timer de expiração original. Emojis customizados móveis chegam no PR #906 junto com um redesign de configurações, e contagens de reação agora animam em mudança (PR #904).
O PR #905 corrige uma lacuna de longa data onde nomes de exibição de múltiplas palavras quebravam e a extração de menção NIP-27 nostr:npub era silenciosamente dropada. Uma UI de equipe suportada por diretório para desktop entrega no PR #912 com comandos de instalar, sincronizar e revelar. Comandos slash agora passam através para conectores ACP no PR #919, permitindo que Sprout encaminhe comandos estilo /help diretamente para runtimes de agente enquanto a UI Sprout fica fora do caminho.
Wisp v1.1.1: integração com carteira Spark e guarda de colagem nsec
Wisp v1.1.1, lançado em 5 de junho, entrega uma tela de conexão de carteira de duas camadas com sub-tela Spark no PR #548 e paridade de dashboard com a UI de carteira iOS no PR #549. O lançamento inclui uma guarda de colagem nsec para todo o sistema que detecta uma colagem prefixada com nsec1 em qualquer lugar do app e bloqueia o campo de aceitá-la, fechando um dos footguns mais citados em UX Nostr. Login com scan de QR mais um modo somente visualização para npub e nprofile entrega no PR #552, permitindo que um usuário navegue em um perfil somente leitura. Mensagens de Zap agora renderizam como mini-posts na gaveta de engajamento (PR #559) para que notas de zap carreguem seu texto ao lado do valor em sats. Um filtro de rede de confiança em respostas de thread entrega no PR #583, permitindo que usuários escondam spam de resposta de contas fora do seu grafo de follow.
Nostria v3.1.46 e nospeak 1.1.3: retrabalho de notificações e reinicialização ICE
Nostria v3.1.46 em 7 de junho termina uma sequência de três lançamentos que retrabalhou o contador de notificações para contar apenas novas notificações desde a última visualização, eliminando uma inflação de longa data onde carregar notificações antigas através de scroll aumentava a contagem do badge. Nostria v3.1.45 corrigiu um bug de pagamento dividido afetando pagamentos lightning e código QR e abandonou uma UI translúcida previamente planejada como inviável no compositor do Android.
nospeak v1.1.3 em 4 de junho adiciona reinicialização ICE em estado FAILED para chamadas de voz 1 para 1. Comportamento WebRTC padrão dropa uma chamada quando candidatos ICE dão timeout sem um caminho alternativo; o caminho de reinicialização ICE renegocia candidatos para que a chamada se recupere de mudanças transitórias de NAT ou rede. Chamadas Android agora mantêm a tela ligada durante chamadas de vídeo.
Mudanças não lançadas
Amethyst: 41 PRs continuando a trilha NIP-32 / NIP-F4 / Tor
Amethyst mesclou 41 PRs esta semana sem cortar uma tag de lançamento, em cima dos 52 PRs da semana passada e do trabalho de rotulagem de hashtag NIP-32 e podcast NIP-F4 coberto na Newsletter #25. A branch ativa continua a acumular recursos para o próximo lançamento taggeado, camando polimento sobre as adições de destaque da semana passada: descoberta de rotulador de hashtag, tela de podcast, faixas e playlists de música, watchdog de auto-cura Tor, assinantes efêmeros para uploads anônimos, e zaps onchain com filtragem NIP-05. O throughput de PRs do Amethyst permanece o mais alto de qualquer cliente Nostr, e a fila não lançada é o roadmap de facto para o que outros clientes Nostr Android precisarão igualar.
Damus: rastreamento de relay a partir de mensagens OK e changelog v1.17
Damus PR #3786, mesclado em 3 de junho, adiciona mensagens OK bem-sucedidas de um relay à lista de relays pós-post. Builds anteriores do Damus populavam a lista de relays vistos apenas ao receber uma mensagem genérica do relay, o que significava que um relay que reconheceu o post mas não entregou nenhum evento de volta era invisível para o usuário. A mudança importa para usuários que querem confirmar que seu post chegou no seu relay de outbox preferido. O PR #3796 corrige um ciclo AttributeGraph na Visualização de Perfil, e o PR #3725 entrega o changelog v1.17 antes do próximo lançamento taggeado.
Shopstr: dupla publicação NIP-34
O repo shopstr da Shopstr no ngit foi anunciado no Nostr esta semana como um repo git NIP-34, juntando-se aos repos rastreados do ngit. O repo GitHub do cliente da loja permanece a superfície primária de desenvolvimento; o anúncio NIP-34 torna disponível um caminho paralelo de colaboração git-sobre-Nostr. Este é o segundo grande projeto marketplace Nostr a publicar duplamente no NIP-34 depois do Mostro, e continua a migração gradual de metadados de projeto para o transporte git do Nostr.
Hermes-Marmot: gateway de agente IA sobre MLS
hermes-marmot, um plugin para o Hermes Agent, conecta a superfície de mensagens de um agente IA a grupos Marmot (MLS-sobre-Nostr) usando mdk-python, os bindings Python para o Rust Marmot Development Kit. O plugin permite que um usuário envie DM a um agente IA de qualquer cliente Nostr que fale mensagens MLS kind 445, incluindo o Whitenoise. DMs de entrada usam desembrulho de gift wrap NIP-59 via bindings Python nostr-sdk, e welcomes de entrada fluem através de UnwrappedGift.from_gift_wrap para mdk.process_welcome e mdk.accept_welcome. Controle de acesso roda através de MARMOT_ALLOWED_USERS (uma lista de permissão npub separada por vírgulas) ou MARMOT_ALLOW_ALL_USERS=true para acesso de dev aberto.
O repo é novo (última atualização em 27 de maio) e pequeno. Sua significância é arquitetural: é a primeira ponte pública entre um runtime de agente LLM e um canal de mensagens Nostr criptografado com MLS, e o primeiro uso em produção de mdk-python além do próprio Whitenoise. O padrão aponta para comunicação agente-para-agente onde ambos os endpoints seguram chaves MLS e o relay vê apenas o texto cifrado.
Atualizações NIP e trabalho em specs de protocolo
NIP-67 dica de completude EOSE (PR #2317) mesclada
O PR #2317 por mattn foi mesclado em 6 de junho, adicionando NIP-67 ao protocolo. O NIP estende a mensagem de relay EOSE com um terceiro elemento opcional: ["EOSE", <subscription_id>, "finish"] sinaliza que todo evento armazenado correspondente ao filtro foi entregue, enquanto um ["EOSE", <subscription_id>] nu não carrega alegação de completude. Um relay que omite a dica está dizendo ao cliente que pode haver mais; um relay que omite o anúncio NIP-67 no NIP-11 mantém o comportamento de hoje sob a heurística legada existente. A mudança é retrocompatível em ambas as direções: clientes legados ignoram o elemento de array final, e relays legados o omitem.
A motivação no spec mesclado é dupla. Primeiro, perda silenciosa de dados: um cliente pede as últimas 500 notas contra um relay com um cap interno de 300 eventos, o relay retorna 300 eventos, e o cliente (usando a heurística padrão received < limit) conclui que o resultado está completo. As notas de correspondência de 201 até N mais antigas ficam no relay não lidas, com o cliente cego para esse fato. Segundo, viagens de ida e volta obrigatoriamente desperdiçadas: quando um relay limita respostas em 300 eventos, qualquer subscrição que exaure o cap requer um segundo REQ com until=<oldest_created_at> puramente para confirmar completude, mesmo quando o filtro por acaso corresponde exatamente a 300 eventos. Ambos os modos de falha são pagos por cada cliente em cada subscrição com cap exaurido. A dica "finish" é uma string opcional em uma mensagem existente e elimina ambos os custos.
Extensão de autocompletar NIP-50 (PR #2357) mesclada
O PR #2357 por Alex Gleason foi mesclado em 6 de junho, adicionando um token autocomplete:true/false à busca NIP-50. A extensão permite que um cliente marque uma consulta como uma busca typeahead para que o relay use correspondência de prefixo, com busca de texto completo como padrão para consultas sem o token. O relay Ditto o implementa para pacotes de follow, listas, e qualquer evento com uma tag title, retornando correspondências contra o prefixo do título; o caminho de busca padrão executa pontuação de texto completo. Sem este token, UIs estilo autocompletar não tinham maneira de comunicar a intenção de busca de prefixo e relays tinham que adivinhar da forma da consulta. O token é uma dica por-busca, não uma capacidade de todo o relay, então um relay pode implementá-lo para uma classe de eventos (títulos) sem alegar suporte geral de autocompletar.
NIP-GART alertas de emergência e broadcasts de localização (PR #2374)
O PR #2374 por disinqa, aberto em 9 de junho, define um formato de fio de preservação de privacidade no Nostr para alertas de emergência e broadcasts de localização endereçados a um grupo de destinatários confiáveis. O objetivo de design declarado é esconder identidade do remetente, associação ao grupo e payload dos operadores de relay enquanto mantém os eventos seguros contra replay e verificáveis por assinatura de ponta a ponta. Número NIP ainda TBD, proposta em rascunho inicial. Caso de uso é o padrão de alerta de emergência padrão: um usuário sob ameaça transmite um ping de localização que apenas um grupo pré-compartilhado de contatos confiáveis pode descriptografar, com o relay cego para remetente, conjunto de destinatários e payload. Detalhes do formato de fio vivem no PR e provavelmente evoluirão à medida que os mantenedores revisem.
Método logout NIP-46 (PR #2373)
O PR #2373 por hzrd149, aberto em 8 de junho, adiciona um método logout ao NIP-46 para que um cliente possa dizer a um bunker explicitamente que a sessão terminou. Até agora, a única forma de terminar uma sessão bunker era esperar o timeout da sessão ou parar de usar a conexão, ambos os quais deixam o bunker segurando estado de sessão para um cliente que se foi. A proposta é curta (um novo método) e é o tipo de mudança de manutenção que torna integrações bunker de longa duração mais limpas.
Proposta híbrida relay-P2P NIP-95 circulada como longform
Uma especificação NIP-95 longform circulou como um post kind:30023 do npub 91bea5cd9361504c409aaf459516988f68a2fcd482762fd969a7cdc71df4451c em 4 de junho sob o título Protocolo Híbrido Relay-P2P via WebRTC. O documento em português define um protocolo relay híbrido peer-to-peer onde clientes Nostr se conectam uns aos outros diretamente via WebRTC para mensagens ao vivo enquanto continuam a usar relays para recuperação de eventos armazenados e entrega offline. O autor explicitamente enquadrou o spec como “pronto para LLM”, provendo definições de mensagem, fluxos lógicos, esquemas de dados e regras de estado em um nível de detalhe que permite que um modelo IA gere código de cliente ou servidor funcional. A proposta ainda não chegou como um PR NIP; a circulação via kind:30023 é o precursor habitual de um pull request formal nostr-protocol/nips.
NIP-44 v3 pega um segundo assinante: Clave porta o spec
O rollout NIP-44 v3 da Amber v6.2.0 da semana passada entregou antes de qualquer PR NIPs mesclado, deixando v3 como uma extensão específica da Amber que outros clientes tinham que espelhar para interoperar. Esse enquadramento de implementação única mudou esta semana. Clave, o assinante remoto NIP-46 iOS baseado em push, entregou uma porta NIP-44 v3 independente em 3 e 4 de junho em oito commits. Primitivos criptográficos entregam em três commits: camada de chaves HKDF + ECDH, o algoritmo de padding v3, e uma API pública de nível superior mais Contexto de criptografia. Em cima desses, a superfície NIP-46 segue no cabeamento de despacho RPC dentro do LightSigner e um esquema PendingRequest que carrega o contexto v3 (kind mais scope), para que o assinante possa registrar para qual kind de evento e caso de uso o payload v3 foi aprovado.
Clave diverge da Amber na superfície voltada ao usuário. Um esquema de concessão de permissão com tiers de sensibilidade permite que usuários concedam criptografia v3 para um kind de evento e scope particulares em um nível de sensibilidade escolhido. No primeiro encontro, prompts de aprovação cientes do contexto v3 com um cartão explicativo de uma vez introduzem v3 aos usuários. O trabalho está no main e está cabeado no projeto Xcode mas não lançado; a build taggeada mais recente é a v0.2.0-build79 de 12 de maio.
Duas implementações independentes entregam NIP-44 v3 em caminhos de produção antes do PR NIPs mesclar, o que fortalece o caso para o formato de fio subjacente que o PR do protocolo formalizará. Testes de interoperabilidade cross-implementação agora se tornam o caminho para a convergência do spec, com a superfície de aprovação Android da Amber e o modelo de tier de sensibilidade iOS da Clave como os dois pontos de referência. Outros assinantes remotos cabeando v3 (o noauth do nsec.app está dormente desde maio de 2025, e outros bunkers não anunciaram trabalho v3) fortaleceriam o consenso ainda mais.
Atividade NIP-34: Iris adota a stack com um novo transporte hashtree
Iris publicou anúncios de repo NIP-34 para hashtree em 8 de junho e iris-apps, iris-drive e iris-chat-rs em 9 de junho, anunciando URLs de clone sob um novo esquema htree:// servido de wss://temp.iris.to. O transporte hashtree é uma alternativa endereçada por conteúdo aos clones roteados por GRASP, e esses quatro anúncios são seus primeiros usos públicos. Os repos carregam descrições vazias e os detalhes arquiteturais ainda estão emergindo, mas a escolha de publicar via anúncio NIP-34 (sobre um manifesto Iris-interno customizado) sinaliza que Iris está se comprometendo com a stack NIP-34 git-sobre-Nostr mais ampla.
NIP em profundidade: NIP-67 (Dica de Completude EOSE)
NIP-67 fecha uma das lacunas de correção mais antigas em NIP-01. O spec original define EOSE como o limite entre eventos armazenados e eventos de subscrição ao vivo para um REQ, mas nunca especificou se o relay tinha terminado de entregar todas as correspondências armazenadas ou tinha parado no meio do caminho por causa de um cap interno. Cada relay impõe um cap por subscrição (comumente 300 a 1000 eventos) independente do limit do cliente, e clientes não tiveram maneira de observar esse cap.
A solução alternativa padrão era comparar a contagem recebida contra o limit solicitado. Se received < limit, tratar o resultado como completo; caso contrário paginar com until=<oldest_created_at>. Ambos os ramos estão quebrados. O ramo received < limit silenciosamente trunca: um cliente pedindo 500 notas contra um relay capado em 300 vê 300 eventos, conclui que o resultado está completo porque 300 < 500, e nunca busca o resto. Eventos retidos no relay não podem sinalizar “mais disponível” através de nenhuma mensagem existente. Paginação como o segundo ramo é desperdício: um filtro que corresponde exatamente ao cap requer um segundo REQ para confirmar completude, retornando zero eventos enquanto consome uma varredura completa de filtro no relay.
A correção do NIP-67 é uma string opcional na mensagem EOSE:
["EOSE", "<sub_id>", "finish"] // explícito: todos os eventos armazenados entregues
["EOSE", "<sub_id>"] // nenhuma alegação de completude
Um relay que anuncia NIP-67 no NIP-11 supported_nips e emite um EOSE nu está dizendo ao cliente que há mais. Um relay que omite o anúncio mantém o comportamento de hoje, e o cliente recorre à heurística existente. Clientes legados ignoram o elemento de array final. Compatibilidade retroativa se mantém em ambas as direções, sem novos verbos ou kinds de evento.
O que torna NIP-67 digno de examinar é o escopo que ele deliberadamente restringe. O spec não define nenhum cursor ou token de paginação, então paginação baseada em until permanece o mecanismo. Caps de relay ficam onde estão, e o NIP não requer nenhuma exposição deles. NIP-67 preserva o significado de EOSE como o limite armazenado-para-ao-vivo e apenas adiciona um sinal sim-ou-não no limite: “eu tenho mais para você” versus “isso é tudo”. Esta superfície minimalista é por que o PR foi mesclado após um período de revisão relativamente curto para uma extensão NIP-01, e por que mattn nota explicitamente no PR que tradução IA foi usada para o texto em inglês. A mudança é pequena o suficiente para que a incerteza de tradução não importe.
Exemplo de troca ciente de NIP-67 entre um cliente e um relay que impõe cap. Anúncio NIP-11 do relay:
{
"id": "a5f87fe2d4c8b9a0e3f1c4d5e6a7b8c9d0e1f2a3b4c5d6e7f8091a2b3c4d5e6f",
"pubkey": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"created_at": 1781136000,
"kind": 11,
"tags": [],
"content": "{\"supported_nips\":[1,11,50,67]}",
"sig": "f1e2d3c4b5a6978869504132c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f80192a3b4c5d6e7f80192a3b4c5d6e7f80192a3b4c5d6e7f80192a3b4c5d6e7f80192a3b4c5"
}
A troca a nível de fio que segue:
→ ["REQ", "abc", {"kinds":[1],"limit":500}]
← [...300 mensagens EVENT...]
← ["EOSE", "abc"] // sem "finish": cap atingido, mais disponível
→ ["REQ", "def", {"kinds":[1],"limit":300,"until":1780900000}]
← [...178 mensagens EVENT...]
← ["EOSE", "def", "finish"] // explicitamente completo
A resposta de 178 eventos previamente teria disparado um terceiro REQ para confirmar completude. Com NIP-67 o cliente para ali.
NIP-67 também é notável como uma emenda NIP-01 chegando com consenso raro. A maioria das mudanças NIP-01 atrai longas threads de debate porque a pequena superfície do protocolo é carga-suporte para cada implementação. NIP-67 mesclou após um período de revisão estendido (aproximadamente sete semanas do aberto ao mesclado), sugerindo que quando uma mudança NIP-01 é pequena o suficiente e o modo de falha é concreto o suficiente (perda silenciosa de dados, viagem de ida e volta desperdiçada obrigatória), os mantenedores do protocolo estão dispostos a estender o vocabulário de mensagem central.
NIP em profundidade: NIP-50 (Busca)
NIP-50 define o campo de filtro search em mensagens REQ, permitindo que clientes peçam a um relay para filtrar eventos por correspondência de texto completo contra uma string de consulta. O spec base mesclado é deliberadamente minimalista: o campo search é uma string, cada relay decide sua própria semântica de busca (quais campos são indexados, como pontuação funciona, se stemming se aplica), e relays anunciam suporte NIP-50 em seu documento NIP-11. Clientes controlam o algoritmo de busca apenas através da string de consulta em si.
Este minimalismo é tanto a força quanto a restrição do NIP-50. A força é que qualquer relay pode implementar busca em qualquer nível de qualidade: uma varredura de substring básica satisfaz o spec, e um relay rodando Elasticsearch ou Meilisearch o satisfaz igualmente. A restrição é que clientes carecem de uma maneira de expressar intenção de busca. Uma UI typeahead de menção de perfil quer correspondência de prefixo contra nomes de exibição; uma busca de conteúdo de texto completo quer pontuação de texto completo tokenizada através do corpo da nota. O mesmo campo search carrega ambos, e o relay deve adivinhar da forma da consulta.
O PR #2357 adiciona o primeiro token de extensão NIP-50: autocomplete:true ou autocomplete:false embutido na consulta de busca sinaliza qual modo o cliente quer. O relay Ditto implementa o token para pacotes de follow, listas, e qualquer evento com uma tag title, mudando para correspondência de prefixo quando autocomplete:true está presente. O token vive inline na consulta (campos de filtro separados ficam intocados), então ele viaja com a string de busca e não requer nenhum bump de protocolo de fio:
search: "fiat autocomplete:true"
Dicas em forma de token como esta são como NIP-50 sempre tratou dialetos específicos de relay. Relays já suportavam tokens como language:en e domain:example.com. Cada um permanece específico de relay, com cada relay documentando seu próprio dialeto. O PR #2357 do NIP-50 eleva autocomplete de um token privado de relay para um abençoado pelo spec, pavimentando o caminho para busca ciente de typeahead através de relays.
Exemplo de REQ NIP-50 com o token autocomplete, mirando um relay que indexa títulos de perfil kind 0:
{
"id": "b7c9d0e1f2a3b4c5d6e7f8091a2b3c4d5e6f7081a2b3c4d5e6f70819a2b3c4d5",
"pubkey": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"created_at": 1781136000,
"kind": 1,
"tags": [
["client", "example-mention-picker"]
],
"content": "Sent search: kinds=[0], search=\"fiat autocomplete:true\", limit=10",
"sig": "12d3e4f5061728394a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8091a2b3c4d5e6f7081a2b3c4d5e6f70819a2b3c4d5e6f7081a2b3c4d5e6f708192"
}
O REQ real a nível de fio:
["REQ", "mention-picker", {"kinds":[0],"search":"fiat autocomplete:true","limit":10}]
Um relay que não reconhece o token trata autocomplete:true como parte da string de busca literal e recorre a correspondência de texto completo, retornando resultados corretos (se classificados diferentemente). A degradação graciosa torna o token seguro para incluir incondicionalmente para clientes que preferem correspondência de prefixo quando disponível.
A próxima extensão provável do NIP-50 é controle de classificação por-kind: uma dica que diz “classificar por created_at descendente” versus a pontuação de relevância padrão. Vários relays já aceitam sort:newest como um token privado de relay, e o mesmo caminho de elevação que trouxe autocomplete para o spec se aplica. Busca permanece um dos poucos primitivos Nostr onde relays competem em qualidade de resultado; confiabilidade de entrega é a mesma através de todos os relays conformes. Tokens incrementais permitem que clientes explorem essa competição de qualidade sem forçar relays a entregar um novo spec de peso pesado.