Files
amethyst/geode/README.md
T
Vitor PamplonaandClaude Opus 5 dc866d3568 chore(release): bump to 1.16.0
app 1.15.2 -> 1.16.0, appCode 460 -> 461. That single edit drives Android's
versionName/versionCode, Desktop and CLI packageVersion, quartz's Maven version
and geode's RelayInfo.VERSION; verified by reading the version back out of
:amethyst, :quartz and :geode and from a built APK (versionCode 461,
versionName 1.16.0-DEBUG).

Roughly twenty substantive PRs since v1.15.2, written up in
docs/changelog/v1.16.00.md. The ones a user feels:

- My Fitness: a training dashboard built from both sources Amethyst has --
  Health Connect and the user's own kind 1301 events -- so it works with no
  health permission at all. Workouts gains a "Mine" filter in the top nav, and
  a workout that is already published no longer offers to post itself twice.
- BOLT12 offers move into the profile payment rail, where every other payment
  route already lived, and the zap picker finally shows a bolt for a recipient
  who publishes an offer and no lightning address. A refused offer falls back
  to BOLT11, retried only on codes that mean nothing was attempted.
- Blossom uploads work again. 1.15.0's unpadded base64url token is rejected by
  deployed servers, so about two uploads in three had been failing since then.
- A relay that sends a CLOSE frame is no longer counted as connected for up to
  four minutes with its REQs live, in both the shared and the Android socket.
- Arti 2.3.0 -> 2.6.0 for TROVE-2026-24 and TROVE-2026-27.
- amy ships ~40 MB lighter after the commonsUI split.

Changelog claims were checked against the final state of each series, not the
first commit: the BOLT12 retry set is the narrowed allowlist from the audit
follow-up (a PAYMENT_FAILED can still settle, so retrying it could pay twice),
the relay count comes from the connected flow rather than the removed members
snapshot, and the OkHttp dispatcher resize is absent because it was reverted.

NEEDS A MAINTAINER BEFORE THE TAG: RELEASE_NOTES_ID still points at the v1.15.0
note. RELEASE_OPS repoints it on every x.y.0, which this is, and it has to be
published from Amethyst's own account -- so it is not something this commit
could do.

Also left alone: docs/changelog/translators.json, whose sinceLastTag is seeded
with vitorpamplona credited for all 41 languages and ~50 users with no language
at all, so scripts/translators.sh output is unusable this cycle. The changelog
credits the three translators with real attribution. mstrofnone (the desktop
keychain fixes) has no npub in mappings and is credited by handle.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 13:33:54 -04:00

123 lines
4.4 KiB
Markdown

# geode
A standalone [Nostr](https://github.com/nostr-protocol/nips) relay for the JVM,
built on Quartz's relay-server code (Ktor CIO). It speaks the core relay
protocol plus NIP-11 (info doc), NIP-42 (AUTH), NIP-45 (COUNT), NIP-50
(full-text search), NIP-77 (Negentropy sync), and NIP-86 (relay management),
stores events in SQLite (or a filesystem backend), and can mirror upstream
relays strfry-router style.
geode depends only on `:quartz` — no Android, no Compose. `amy serve` (the
Amethyst CLI) embeds the same engine in-process.
## Install
Pick the channel that matches how you deploy. For a real relay, the **Docker
image** or the **`.deb`/`.rpm` + systemd** are the two production paths;
Homebrew and the portable tarball are handy for local testing.
### Docker (recommended for servers)
Images are published to GHCR on every release:
```bash
# Ephemeral — in-memory store, events vanish on restart:
docker run --rm -p 7447:7447 ghcr.io/vitorpamplona/geode:latest
# Persistent + configured:
docker run -d --name geode -p 7447:7447 \
-v $PWD/geode.toml:/etc/geode/geode.toml:ro \
-v geode-data:/var/lib/geode \
ghcr.io/vitorpamplona/geode:latest --config /etc/geode/geode.toml
```
with `in_memory = false` and `file = "/var/lib/geode/events.db"` in your
`geode.toml`. Pin a version (`:1.16.0`) instead of `:latest` for reproducible
deploys. To build the image yourself, from the repo root:
```bash
docker build -f geode/Dockerfile -t geode:local .
```
### Debian/Ubuntu (`.deb`) and Fedora/RHEL (`.rpm`)
Download `geode-<version>-linux-x64.deb` (or `.rpm`) from the
[release page](https://github.com/vitorpamplona/amethyst/releases) and install
it — a minimal JRE is bundled, so no system Java is required. It installs to
`/opt/geode/` with the launcher at `/opt/geode/bin/geode`.
```bash
sudo dpkg -i geode-1.16.0-linux-x64.deb # or: sudo rpm -i geode-1.16.0-linux-x64.rpm
```
To run it as a managed service, wire up the shipped systemd unit
(`/opt/geode/share/geode/geode.service`) — the unit file's header comment has
the copy-paste steps (create the `geode` user, drop your config in
`/etc/geode/geode.toml`, `systemctl enable --now geode`).
### Homebrew
```bash
brew install vitorpamplona/tap/geode-relay # from the tap, once published
```
The formula depends on `openjdk` and installs the no-JRE jar bundle. Reference
formula: [`packaging/homebrew/geode-relay.rb`](packaging/homebrew/geode-relay.rb).
### Portable tarball (any Linux/macOS, no system Java)
Download `geode-<version>-<os>-<arch>.tar.gz`, unpack, and run:
```bash
tar xzf geode-1.16.0-linux-x64.tar.gz
./geode/bin/geode --config geode/share/geode/config.example.toml
```
The tarball bundles a jlink'd JRE plus `share/geode/config.example.toml` and
`share/geode/geode.service`.
### From source
```bash
./gradlew :geode:run --args="--config /etc/geode.toml"
```
## Configure
geode runs with zero config (binds `0.0.0.0:7447`, in-memory SQLite). For
anything real, copy [`config.example.toml`](config.example.toml) and edit it —
the sections mirror nostr-rs-relay's `config.toml` so existing configs port
almost verbatim. Precedence is **CLI flags > TOML > built-in defaults**.
```bash
geode --config /etc/geode/geode.toml
geode --help # full flag list
geode --version
```
Key sections: `[info]` (NIP-11 doc), `[network]` (bind + thread pools),
`[database]` (SQLite path/tuning), `[options]` (AUTH / verify / search),
`[authorization]` (allow/deny lists), `[[mirror]]` (upstream mirroring), and
`[admin]` (NIP-86 management). See the example file for every knob.
## Verbs
```
geode [relay] [flags] serve the relay (default)
geode import [flags] [FILE…] bulk-load NDJSON events into the store
geode export [flags] dump the store as NDJSON to stdout
```
`import`/`export` are geode's `strfry import` / `strfry export` — one JSON event
per line, for seeding, migrating, or backing up a relay. Both stream, so a
multi-million-event corpus round-trips in roughly constant memory.
## Release process
geode ships on the same tag-driven pipeline as the rest of Amethyst: pushing a
`v*` tag runs `.github/workflows/create-release.yml`, whose `build-geode` job
produces the tarball + `.deb`/`.rpm` + Homebrew jvm bundle, `docker-geode`
builds and pushes the GHCR image, and `bump-homebrew-geode-formula.yml` syncs
the reference formula. Design notes:
[`plans/2026-07-24-geode-release.md`](plans/2026-07-24-geode-release.md).