diff --git a/app/structured-data.js b/app/structured-data.js index 0772ebd..86e1eed 100644 --- a/app/structured-data.js +++ b/app/structured-data.js @@ -46,8 +46,8 @@ const byPage = { library, ], 'getting-started': [library], - deed: [app('deed', 'deed', 'deed', 'The nostr command line: keys, events, NIP-19, NIP-44, relay queries, publishing, and a local store that later runs read without a network.')], - plaza: [app('Plaza', 'plaza', 'plaza', 'A fast, local-first Nostr client for macOS and Linux, rendered from its own store and reconciled with relays in the background.', { applicationCategory: 'SocialNetworkingApplication' })], + deed: [app('deed', 'deed', 'deed', 'The nostr command line: keys, events, NIP-19, NIP-44, relay queries, publishing, and a local store that later runs read without a network.', { operatingSystem: 'macOS, Linux, Windows' })], + plaza: [app('Plaza', 'plaza', 'plaza', 'A fast, local-first Nostr client for macOS and Linux, rendered from its own store and reconciled with relays in the background. It reads long-form articles, searches for people by name and uploads pictures to Blossom servers.', { applicationCategory: 'SocialNetworkingApplication' })], notary: [app('Notary', 'notary', 'notary', 'A native NIP-46 remote signer for macOS and Linux: the key stays in a local daemon on a machine you control.', { applicationCategory: 'SecurityApplication' })], } diff --git a/content/architecture.mdx b/content/architecture.mdx index 82506d8..2c17114 100644 --- a/content/architecture.mdx +++ b/content/architecture.mdx @@ -24,7 +24,8 @@ official BIP-340 test-vector suite. On top of it: - **RFC 6455 WebSocket** framing and handshake, and a stream-generic relay connection state machine with NIP-01 subscriptions. -- A live **TCP/TLS dialer** that resolves hostnames through the system resolver. +- A live **TCP/TLS dialer**. Hostnames resolve through libc `getaddrinfo` on macOS and Linux and through std's own resolver on Windows, and an IP literal is parsed first so it never reaches a resolver. `dialDiagnosed` is `dial` that also records the HTTP status the relay answered the upgrade with, so a relay that says 503 when busy, 401 or 429 can be told apart from one that is down. +- **NIP-50 search** on the filter: `Filter.search` is sent to relays as `"search"`, and the local store applies it as a case-insensitive substring of the content. - **NIP-65 outbox model**: relay lists with read/write routing and *zero* hardcoded relays, so events are published and fetched where they actually live. @@ -36,8 +37,9 @@ A zero-copy, memory-mapped **LMDB** event store (`store.zig`): - A compact binary event record with secondary indexes (author, kind, `created_at`, tag). - A **bounded, newest-first query planner**: it walks the indexes via reverse - cursors and a k-way merge, stopping at `limit`, so feed latency stays flat as - the store grows (see [Performance](/performance)). + cursors and a k-way merge that takes the newest candidate from a binary heap, + stopping at `limit`, so feed latency stays flat as the store grows (see + [Performance](/performance)). - Validate-on-insert ingestion: dedup, replaceable / parameterized-replaceable upserts, and NIP-09 deletions. - A direct-message conversation index, local-first reconciliation, and a @@ -56,3 +58,15 @@ The layer the native signer is built on: access behind auth. The native signer built on this layer is **[Notary](/notary)**. + +## Platforms + +The library builds for macOS, Linux and Windows, on x86_64 and aarch64, and CI builds and tests it on all three. On Windows the dialer waits for write room with a poll request to the AFD driver, because std opens its sockets on that driver and never registers them with Winsock, and a key file takes its directory's default access list because there are no mode bits. macOS and Linux keep `getaddrinfo` and `poll`. + +## How it is tested + +Tests sit beside the code and `zig build test` runs them all. The cryptography is checked against the official vectors (the BIP-340 suite, the NIP-44 v2 vectors, and the NIP-19, NIP-49 and RFC 6455 worked examples). The transport is driven by a scripted in-memory relay, with a few tests on a real loopback socket for the parts a fake cannot show. The store runs on a real LMDB file in a temporary directory. + +The parsers that read bytes someone else wrote have fuzz targets: WebSocket frames and handshake responses, relay messages, events, bech32 and NIP-19, NIP-44 payloads, NIP-46 messages and URIs, relay lists and URLs, mnemonics, `ncryptsec` files and filters. Each asserts that nothing crashes or leaks and, where one exists, an invariant, such as an event parsed, serialized and parsed again being the same event. `zig build test` runs each target over a seed corpus, and `zig build test --fuzz -Doptimize=ReleaseSafe` fuzzes them until stopped. + +The repository's [`ARCHITECTURE.md`](https://github.com/zig-nostr/nostr/blob/main/ARCHITECTURE.md) goes through the modules file by file, how an event travels from a key to a relay to the store, and the threading and cancellation rules. diff --git a/content/deed.mdx b/content/deed.mdx index a2997db..2a55af0 100644 --- a/content/deed.mdx +++ b/content/deed.mdx @@ -1,16 +1,26 @@ # deed: the nostr command line -**deed** is a command line for nostr, built on `zig-nostr`. It makes keys, builds and signs events, reads and writes NIP-19 codes, encrypts and decrypts with NIP-44, checks signatures, asks relays for events and publishes to them, and keeps what it fetches in a local store that later runs can read without a network. One binary of under 3 MB for macOS and Linux, Intel and ARM, statically linked on Linux. +**deed** is a command line for nostr, built on `zig-nostr`. It makes keys, builds and signs events, reads and writes NIP-19 codes, encrypts and decrypts with NIP-44, checks signatures, asks relays for events and publishes to them, and keeps what it fetches in a local store that later runs can read without a network. One binary of under 3 MB for macOS, Linux and Windows, Intel and ARM, statically linked on Linux. A deed is two things at once: a signed instrument, and a thing done. So is a nostr event. ## Install +macOS and Linux: + ```sh curl -fsSL https://raw.githubusercontent.com/zig-nostr/deed/main/scripts/install.sh | bash ``` -The installer works out which build the machine wants, checks the download against the SHA-256 published beside it, and installs into `~/.local/bin`, so nothing needs root. If the digest does not match, it installs nothing and says so. +Windows, in PowerShell: + +```powershell +irm https://raw.githubusercontent.com/zig-nostr/deed/main/scripts/install.ps1 | iex +``` + +Each checks the download against the SHA-256 published beside it, and if the digest does not match it installs nothing and says so. On macOS and Linux deed goes into `~/.local/bin`. On Windows it goes into `%LOCALAPPDATA%\deed`, which is added to your `PATH`, so `deed version` works in a new terminal. Neither needs root or administrator rights. + +`--version ` installs a particular release and `--prefix ` puts it somewhere else; on Windows they are `-Version` and `-Prefix` when the script runs as a file, and `$env:DEED_VERSION` and `$env:DEED_PREFIX` for the piped line. Windows on ARM gets the x86_64 build, which Windows 11 runs under emulation. The Windows binary is not code-signed, so Windows may show a warning the first time it runs. ## What it does @@ -51,6 +61,10 @@ deed req -k 1 -l 50 --store ~/.deed/db --local # again, dialling n The second command opens no socket, and the events it prints are the same events: what is stored is what was signed, so they still verify. Every event is checked before it is stored or printed, so a relay cannot put a forgery, or an event nobody asked for, into the store or the output. +A store is one file. `--store` creates it the first time, and the directories above it as `mkdir -p` would, and a leading `~` is your home directory even when it was quoted. `--local` only reads, so it opens a store that already exists and says "there is no store at" a path that has none, rather than leaving an empty one behind. When a store will not open, the message says why: a directory in the way, no permission, a read-only file system, a full disk, or a file that is not a store. On Windows the file takes 1 GiB of disk from the first run, because LMDB sizes it to its whole map up front there; on macOS and Linux it grows with what is kept. + +NIP-19 codes are read the way a QR code carries them: `deed decode NPUB1...` and `NOSTR:NPUB1...` work as the lowercase forms do, and a code that mixes cases is refused. + ## Judging what it fetches deed's output is one verified event per line, which makes it a clean first stage for anything that classifies text. The [Jev example](https://github.com/zig-nostr/deed/tree/main/examples/jev) fetches the newest thousand notes from five relays, drops the app data some clients publish as notes, and has [Jev](https://docs.typesafe.ai), TypeSafe's classification model, answer three questions about each: what it is about, how much substance it carries, and whether it is spam. The thresholds that decide what to keep are plain constants in the script. @@ -66,10 +80,12 @@ On one run, 629 of 1,000 notes were text worth judging, 157 of those were droppe A one-shot command runs in about 2.3 ms and under 2 MB of memory. deed signs and verifies about 31,000 events a second each, stores 100,000 events from a relay at about 17,000 a second, and answers a lookup from that store in about 3 ms, start to finish. The full numbers, and how to reproduce them, are on the [performance page](/performance#deed). +## How it is built + +[`ARCHITECTURE.md`](https://github.com/zig-nostr/deed/blob/main/ARCHITECTURE.md) explains how deed is put together: where each command lives, how a run flows, the store, the exit codes and how it is tested. CI builds deed and runs its tests on Linux, macOS and Windows, and on Windows it also makes a key, signs an event and verifies it through a pipe with the binary it built. + ## What is missing **Relay selection.** A code with no relay hints is not looked up yet: `deed fetch npub1...` asks you to name a relay rather than finding the author's relay list first. -**Windows.** deed does not build there yet. - Source, releases and the full reference live at [`zig-nostr/deed`](https://github.com/zig-nostr/deed). diff --git a/content/ecosystem.mdx b/content/ecosystem.mdx index efeb26e..187ea57 100644 --- a/content/ecosystem.mdx +++ b/content/ecosystem.mdx @@ -8,7 +8,8 @@ apps, so every layer benefits from the same well-tested foundation. **[`zig-nostr/nostr`](https://github.com/zig-nostr/nostr)**: secp256k1 keys and BIP-340 signing, the NIP-01 event model, relay transport with the outbox model, a -zero-copy local-first store, and the NIP-46 signer protocol. It's the credibility +zero-copy local-first store, and the NIP-46 signer protocol. It builds for macOS, +Linux and Windows, and its parsers are fuzzed. It's the credibility anchor for everything else, and it keeps growing: more NIPs and capabilities land with each milestone. See [NIP support](/nips) and the [architecture](/architecture). @@ -26,26 +27,26 @@ and the reason the ecosystem exists. A native NIP-46 signer for macOS and Linux: Zig, no Electron, no WebView. Your key lives in a local daemon, nothing gets signed quietly, and your `nsec` never leaves it -unless you ask for it. +unless you ask for it. On macOS it waits in the menu bar and shows its window only when a request needs a decision. → [`zig-nostr/notary`](https://github.com/zig-nostr/notary) · [read more](/notary) ### Plaza: shipped The flagship client: read without an account, post in four clicks, with the feed -rendered from disk and reconciled in the background. Your key lives in Notary, a separate +rendered from disk and reconciled in the background. It opens long-form articles, searches for people by name, adds pictures from a file and covers notes marked sensitive. Your key lives in Notary, a separate process, or in your own signer. → [`zig-nostr/plaza`](https://github.com/zig-nostr/plaza) · [read more](/plaza) ### deed: shipped -The nostr command line: keys, events, NIP-19 codes, NIP-44, signature checks, relays, and a local store that later runs read without a network. One binary of under 3 MB for macOS and Linux. +The nostr command line: keys, events, NIP-19 codes, NIP-44, signature checks, relays, and a local store that later runs read without a network. One binary of under 3 MB for macOS, Linux and Windows. → [`zig-nostr/deed`](https://github.com/zig-nostr/deed) · [read more](/deed) ### On the roadmap Both apps are downloadable and both keep growing. What comes next lands inside -them rather than as new apps: private messages, zaps and a wallet, groups, search -and media all belong to the client people already have. +them rather than as new apps: private messages, zaps and a wallet, groups, searching +notes and playing video all belong to the client people already have. See the [roadmap](/roadmap) for the order, and for what is deliberately not being built. diff --git a/content/getting-started.mdx b/content/getting-started.mdx index 637d6ec..8eef7f1 100644 --- a/content/getting-started.mdx +++ b/content/getting-started.mdx @@ -1,14 +1,14 @@ # Getting Started `zig-nostr` is a Nostr protocol library for [Zig](https://ziglang.org). It -targets Zig **0.16** and is in **active development** (`v0.14.1`). +targets Zig **0.16** and is in **active development** (`v0.14.9`). ## Install Fetch the library into your project's `build.zig.zon`: ```sh -zig fetch --save https://github.com/zig-nostr/nostr/archive/refs/tags/v0.14.1.tar.gz +zig fetch --save https://github.com/zig-nostr/nostr/archive/refs/tags/v0.14.9.tar.gz ``` Then wire the module in `build.zig`: @@ -21,6 +21,10 @@ your_module.addImport("nostr", nostr.module("nostr")); The library vendors and compiles bitcoin-core's libsecp256k1 and LMDB from source, so no system packages are required. +## Platforms + +The library builds for macOS, Linux and Windows, on x86_64 and aarch64, and CI builds it and runs the tests on all three systems. To check a Windows build from another system, `zig build test -Dtarget=x86_64-windows-gnu` compiles the test binary and then stops with an error, because a non-Windows host cannot run it. A store takes its full map size on disk on Windows (1 GiB by default) from the first open, where on macOS and Linux it grows with what is kept. + ## Quickstart: sign and verify an event ```zig @@ -81,7 +85,7 @@ The `nostr` module re-exports focused namespaces: - `nip44`: v2 payload encryption - `nip46`: remote signing ("bunker") protocol - `nip42`: client authentication to relays -- `relay` / `websocket` / `message` / `filter`: live transport & subscriptions +- `relay` / `websocket` / `message` / `filter`: live transport & subscriptions, with NIP-50 `search` on the filter - `nip65`: relay lists and outbox routing - `liveness`: when a relay connection has gone quiet, and what to do about it - `store`: the local-first, memory-mapped event store @@ -95,3 +99,5 @@ git clone https://github.com/zig-nostr/nostr cd nostr zig build test # run the suite ``` + +To fuzz the parsers that read bytes from outside (frames, relay messages, events, NIP-19, NIP-44, NIP-46 and more) until you stop it, use `zig build test --fuzz -Doptimize=ReleaseSafe`. diff --git a/content/index.mdx b/content/index.mdx index 779caa1..abab6d8 100644 --- a/content/index.mdx +++ b/content/index.mdx @@ -30,7 +30,7 @@ title: The Nostr protocol, natively in Zig
📦

Core library

-

The foundation, keys, events, transport, the outbox model, and a local-first store. Actively growing toward full Nostr coverage, milestone after milestone.

+

The foundation, keys, events, transport, the outbox model, and a local-first store. It builds on macOS, Linux and Windows, and it is actively growing toward full Nostr coverage, milestone after milestone.

🧩
@@ -87,7 +87,7 @@ title: The Nostr protocol, natively in Zig

Notary

Shipped
-

A native NIP-46 signer for macOS and Linux: Zig, no Electron. Your nsec stays in a local daemon, and nothing gets signed quietly.

+

A native NIP-46 signer for macOS and Linux: Zig, no Electron. Your nsec stays in a local daemon, and nothing gets signed quietly. On macOS it waits in the menu bar until a request needs you.

Learn more →
@@ -95,7 +95,7 @@ title: The Nostr protocol, natively in Zig

Plaza

Shipped
-

A fast, local-first client: read without an account, post in four clicks, with the feed rendered from disk. A downloadable app for macOS and Linux.

+

A fast, local-first client: read without an account, post in four clicks, with the feed rendered from disk. It reads long-form articles, finds people by name and adds pictures from a file. A downloadable app for macOS and Linux.

Learn more →
@@ -103,7 +103,7 @@ title: The Nostr protocol, natively in Zig

deed

Shipped
-

The nostr command line: sign, verify, encode, encrypt, query relays and publish, with a local store that answers without a network. One small binary for macOS and Linux.

+

The nostr command line: sign, verify, encode, encrypt, query relays and publish, with a local store that answers without a network. One small binary for macOS, Linux and Windows.

Learn more → @@ -117,7 +117,7 @@ title: The Nostr protocol, natively in Zig

```sh -zig fetch --save https://github.com/zig-nostr/nostr/archive/refs/tags/v0.14.1.tar.gz +zig fetch --save https://github.com/zig-nostr/nostr/archive/refs/tags/v0.14.9.tar.gz ``` ```zig diff --git a/content/nips.mdx b/content/nips.mdx index 61b3339..0e13d7a 100644 --- a/content/nips.mdx +++ b/content/nips.mdx @@ -10,12 +10,13 @@ official specification vectors. | [01](https://github.com/nostr-protocol/nips/blob/master/01.md) | Basic protocol: events, signatures, subscriptions, `kind:0` profiles and `kind:1` notes | ✅ done | | [06](https://github.com/nostr-protocol/nips/blob/master/06.md) | Key derivation from a BIP-39 mnemonic, path `m/44'/1237'/'/0/0` | ✅ done | | [09](https://github.com/nostr-protocol/nips/blob/master/09.md) | Event deletion, `kind:5` (ingestion) | ✅ done | -| [19](https://github.com/nostr-protocol/nips/blob/master/19.md) | bech32-encoded entities: `npub`, `nsec`, `note`, `nprofile`, `nevent`, `naddr` | ✅ done | -| [21](https://github.com/nostr-protocol/nips/blob/master/21.md) | `nostr:` URI scheme | ✅ done | +| [19](https://github.com/nostr-protocol/nips/blob/master/19.md) | bech32-encoded entities: `npub`, `nsec`, `note`, `nprofile`, `nevent`, `naddr`. A code is read in all lowercase or all uppercase, and one that mixes the two is refused | ✅ done | +| [21](https://github.com/nostr-protocol/nips/blob/master/21.md) | `nostr:` URI scheme, with the scheme matched in any case, so the `NOSTR:` a QR code carries decodes | ✅ done | | [42](https://github.com/nostr-protocol/nips/blob/master/42.md) | Client-to-relay authentication | ✅ done | | [44](https://github.com/nostr-protocol/nips/blob/master/44.md) | Encrypted payloads (v2) | ✅ done | | [46](https://github.com/nostr-protocol/nips/blob/master/46.md) | Nostr Connect, remote signing over `kind:24133` | ✅ done | | [49](https://github.com/nostr-protocol/nips/blob/master/49.md) | Private key encryption (`ncryptsec`) | ✅ done | +| [50](https://github.com/nostr-protocol/nips/blob/master/50.md) | Search: the `search` field of a filter, sent to relays as `"search"`. Relays decide what matches, so the library's own matching ignores it, and the local store applies it as a case-insensitive substring of the content | ✅ done | | [65](https://github.com/nostr-protocol/nips/blob/master/65.md) | Relay list metadata, `kind:10002`, what people call the outbox model | ✅ done | That is the library surface, and all of it is done. What the roadmap commits to @@ -30,15 +31,21 @@ rather than library surface. | NIP | Title | Where | |----|----|----| | [02](https://github.com/nostr-protocol/nips/blob/master/02.md) | Contact lists, `kind:3` | reading and writing your follows | -| [05](https://github.com/nostr-protocol/nips/blob/master/05.md) | DNS identifiers, `/.well-known/nostr.json` | the `name@domain` handle on a profile, checked against the domain | -| [10](https://github.com/nostr-protocol/nips/blob/master/10.md) | Reply threading, marked `e` tags | threads, and replies you post | -| [18](https://github.com/nostr-protocol/nips/blob/master/18.md) | Reposts, `kind:6` and `kind:16` | counted on a note, and a row in notifications | +| [05](https://github.com/nostr-protocol/nips/blob/master/05.md) | DNS identifiers, `/.well-known/nostr.json` | the `name@domain` handle on a profile, checked against the domain, and the search field resolves one to the person it names | +| [19](https://github.com/nostr-protocol/nips/blob/master/19.md) | bech32-encoded entities, `nostr:` links | opens `npub`, `nprofile`, `note`, `nevent` and `naddr`. An address Plaza copies carries up to two relay hints, and the account menu copies an `nprofile` that names the relays you write to | +| [10](https://github.com/nostr-protocol/nips/blob/master/10.md) | Reply threading, marked `e` tags | threads read by their markers, and replies you post with a `root` marker and a relay hint when Plaza knows one | +| [18](https://github.com/nostr-protocol/nips/blob/master/18.md) | Reposts, `kind:6` and `kind:16` | reposts are read and shown in the feed as the note itself, counted on a note, and a row in notifications. A repost Plaza publishes carries the note's relay hint, and a quote is published as a `q` tag | | [22](https://github.com/nostr-protocol/nips/blob/master/22.md) | Comments, `kind:1111`, the other way to write a reply | read in threads, on a profile, and as a notification | | [24](https://github.com/nostr-protocol/nips/blob/master/24.md) | The `t` tag: a hashtag is a lowercase `t`, and NIP-01 single-letter indexing is what makes `#t` queryable | pressing one opens the notes carrying it, read from this machine first and then asked of relays. Written onto notes you post, so yours are findable too | | [25](https://github.com/nostr-protocol/nips/blob/master/25.md) | Reactions, `kind:7` | likes, in the feed and notifications | -| [27](https://github.com/nostr-protocol/nips/blob/master/27.md) | `nostr:` mentions in content | names instead of raw base32 | +| [27](https://github.com/nostr-protocol/nips/blob/master/27.md) | `nostr:` mentions in content | a reference to a person is shown as the name, and the first reference to a note or an article becomes a quote card. A quote you write is composed as one | +| [23](https://github.com/nostr-protocol/nips/blob/master/23.md) | Long-form content, `kind:30023` | an article opens in a reader, from a press or from an `naddr`. A draft (`kind:30024`) is not opened, and Plaza does not write articles | +| [36](https://github.com/nostr-protocol/nips/blob/master/36.md) | Sensitive content, the `content-warning` tag | a note that carries the tag is covered until you press Show, with nothing in it fetched, and the composer adds the tag when you ask | +| [42](https://github.com/nostr-protocol/nips/blob/master/42.md) | Relay authentication | Plaza answers a relay's AUTH challenge only after the relay has refused something for want of one, and only once you have allowed it for that relay and account | +| [50](https://github.com/nostr-protocol/nips/blob/master/50.md) | Search | three search relays are asked for people by name, and each result says which relay returned it. Profiles only, not notes | +| [Blossom](https://github.com/hzrd149/blossom) | Media servers: BUD-02 upload, BUD-03 server list (`kind:10063`), BUD-06 preflight, BUD-11 authorization (`kind:24242`) | a picture goes to the first server in your list that takes it, or to one of two built in when you have none. Plaza checks a server first with BUD-06, signs the BUD-11 token, and reads and edits your list | | [89](https://github.com/nostr-protocol/nips/blob/master/89.md) | Application handlers | the `client` tag on notes you post | -| [92](https://github.com/nostr-protocol/nips/blob/master/92.md) | Media attachments, `imeta` | dimensions read off the tag, so an image reserves its box before it loads | +| [92](https://github.com/nostr-protocol/nips/blob/master/92.md) | Media attachments, `imeta` | dimensions and placeholder read off the tag, so an image reserves its box before it loads, and written onto a picture Plaza uploads (url, type, hash, size, dimensions, blurhash and description) | | [51](https://github.com/nostr-protocol/nips/blob/master/51.md) | Lists: bookmarks (`kind:10003`) and mutes (`kind:10000`) | bookmarks public or private, and a mute list that is read before it is ever written | | [57](https://github.com/nostr-protocol/nips/blob/master/57.md) | Zaps, `kind:9735` receipts | receipts are read and shown. Sending is a milestone away | | [71](https://github.com/nostr-protocol/nips/blob/master/71.md) | Video events, `kind:21` and `kind:22` | a video is recognised as one and drawn as one. Playing it in place is still to come | @@ -54,11 +61,6 @@ it. | Spec | Title | Milestone | Status | |----|----|----|----| | [NIP-24](https://github.com/nostr-protocol/nips/blob/master/24.md) | Extra `kind:0` fields (`display_name`, `website`, `banner`, `bot`, `birthday`), carried through untouched when I rewrite a profile | Your identity, and your key | 🚧 planned | -| [NIP-50](https://github.com/nostr-protocol/nips/blob/master/50.md) | Search, which is a relay-side feature: a `search` string on an ordinary filter | Find anything, and keep it clean | 🚧 planned | -| [Blossom BUD-02](https://github.com/hzrd149/blossom/blob/master/buds/02.md) | Blob upload, `PUT /upload`. This is the step that puts the bytes of a picture on a server | Media worth looking at | 🚧 planned | -| [Blossom BUD-03](https://github.com/hzrd149/blossom/blob/master/buds/03.md) | User Server List, `kind:10063`: which servers hold your blobs, most trusted first | Media worth looking at | 🚧 planned | -| [Blossom BUD-11](https://github.com/hzrd149/blossom/blob/master/buds/11.md) | Authorization for those requests: a signed `kind:24242` event carrying the verb and an expiry | Media worth looking at | 🚧 planned | -| [NIP-92](https://github.com/nostr-protocol/nips/blob/master/92.md) | `imeta` written onto a note I post, not only read off one. It is what makes the picture render in someone else's client | Media worth looking at | 🚧 planned | | [NIP-B7](https://github.com/nostr-protocol/nips/blob/master/B7.md) | Finding a blob again: when a media URL ends in a sha256, retry it against the author's `kind:10063` servers and check the hash | Media worth looking at | 🚧 planned | | [NIP-57](https://github.com/nostr-protocol/nips/blob/master/57.md) | Zaps you can send: a `kind:9734` request to the recipient's LNURL callback, and the `kind:9735` receipt that follows the payment | Money, carefully | 🚧 planned | | [NIP-47](https://github.com/nostr-protocol/nips/blob/master/47.md) | Nostr Wallet Connect, so that invoice is paid in the app: a `nostr+walletconnect://` link, over kinds 13194, 23194 and 23195 | Money, carefully | 🚧 planned | @@ -70,9 +72,8 @@ it. **Blossom is not a NIP.** It is a separate protocol with its own repository, [hzrd149/blossom](https://github.com/hzrd149/blossom), and its documents are -called BUDs rather than NIPs. It sits in this table because it is where file -upload actually happens. A media list without it would be a list that cannot -post a picture. +called BUDs rather than NIPs. It sits in the apps table above because it is where +file upload actually happens, and Plaza uploads a picture through it today. NIP-B7 is the Nostr side of the same story, and it is easy to mistake for the upload spec. It is not one. It only says how to find a blob again, so a client diff --git a/content/notary.mdx b/content/notary.mdx index 1093576..675f918 100644 --- a/content/notary.mdx +++ b/content/notary.mdx @@ -6,6 +6,21 @@ the NIP-46 "bunker" protocol, so your `nsec` lives in a local daemon on a machin you control. Nothing gets signed quietly: you see what a client is asking for before it happens, and the key never leaves the daemon unless you ask for it. +## Install + +```sh +curl -fsSL https://raw.githubusercontent.com/zig-nostr/notary/main/scripts/install.sh | bash +``` + +That works on macOS (Apple Silicon) and Linux (x86_64 and aarch64). It downloads the latest release for your system, verifies its SHA-256, installs it and starts it: `Notary.app` in `/Applications` on macOS, and everything under `~/.local` on Linux, so nothing needs root. One download brings up both halves: the window, and the daemon it spawns, which is where your key actually lives. + +- Linux needs GTK 4 and a recent distribution: Ubuntu 23.10+, Debian 13+ or Fedora 39+. Ubuntu 22.04 and Debian 12 are too old. The installer checks both before it downloads anything. +- The macOS build is ad-hoc signed, not notarized, on purpose: Notary holds your key, so the trust anchor is a build you can reproduce rather than an Apple signature. +- On macOS, choose **Quit Notary** in the menu bar before you install over a running copy. +- Options go after `bash -s --`: `--version `, `--archive `, `--prefix ` and `--no-open`. The [README](https://github.com/zig-nostr/notary#install) explains each. + +Source, releases, and build instructions live at [`zig-nostr/notary`](https://github.com/zig-nostr/notary). +