Skip to content

0.7.0

Latest

Choose a tag to compare

@yysskk yysskk released this 26 Jul 16:32
3e53677

An API-shape release: NostrClient's ~70 methods move onto eight feature namespaces backed by capability protocols, every client feature runs through the NostrSigning abstraction so a remote signer drives all of them, and the relay layer consolidates into NostrCore with normalized, string-based targeting and an injectable WebSocket transport. Two NIPs join the supported set — NIP-98 HTTP Auth and NIP-29 relay-based groups — and NIP-44 gains strict padding validation and the official vector suite.

Upgrading from 0.6.0 requires source changes. The full list is in the changelog.

Added

  • Client feature namespacesidentity, relays, events, subscriptions, routing, messages, groups, and lists, each a Sendable value conforming to a capability protocol (NostrMessaging, NostrEventPublishing, …), so a feature can depend on the slice it uses and be tested against a stub.
  • NIP-98 HTTP Auth — sign kind-27235 Authorization: Nostr headers with any signer via HTTPAuth and URLRequest.setNostrAuthorization(signer:), and run the full check chain server-side with HTTPAuth.validate(...).
  • NIP-29 Relay-based groups — join/leave, chat with timeline references, the eight moderation kinds, relay-signed state parsing, naddr share links with invite codes, and the NIP-51 kind-10009 simple group list.
  • Official NIP-44 vectors — the canonical paulmillr/nip44 suite runs in full, replacing the four hand-copied vectors it stood in for.
  • Transport injection — the designated RelayConnection(url:webSocketFactory:config:) is public and the shared RelayConnectionTransport takes a webSocketFactory: and a config:, so a single relay, a NIP-46 session, or a NIP-47 wallet connection can run on a platform-native socket or an in-memory fake.
  • Single importNostrClient, NostrWalletConnect, and NostrConnect re-export NostrCore.

Fixed

  • NIP-44 padding is validated strictly — a payload carrying a valid MAC over non-canonical padding no longer decrypts; the block must be the length prefix plus exactly calc_padded_len of the declared length.
  • Event deduplication is scoped per subscription — an event matching two subscriptions previously reached only whichever processed it first, and a repeated fetch of the same event returned it once and then nothing. maxDeduplicationCacheSize is now enforced as events are recorded rather than by a once-a-minute sweep.
  • One socket per relay, however it is spelled — the pool keys connections by normalized URL, and a relay listed for both reading and writing under different spellings no longer emits two conflicting NIP-65 r tags.
  • NIP-47 commands no longer race their own connection — a command issued while the wallet connection was still connecting could publish before the response subscription existed, losing the reply; both NIP-46 and NIP-47 sessions now share one setup task.

Changed

  • Breaking: every pre-namespace method and property on NostrClient is removed; most calls keep their name under a namespace (client.publishTextNote(…)client.events.publishTextNote(…)).
  • Breaking: a remote signer drives every feature — NostrError.localSignerRequired is gone, GiftWrap and the direct-message builder/parser take any NostrSigning in place of a KeyPair, and the direct-message sequences are throwing.
  • Breaking: relay targeting is string-based (to: [String]?), pool keys are normalized, and zero-relay operations throw noRelaysInPool / noMatchingRelays instead of silently succeeding.
  • Breaking: RemoteSignerTransport and WalletConnectTransport collapse into NostrCore.RelayTransport; Contact.relayUrl and every relayUrl: argument label become relayURL.