Skip to content

Astraea 0.4.1 — NIP-46 bunker login, sync on launch, widget previews

Latest

Choose a tag to compare

@Lwb89dev Lwb89dev released this 10 Aug 20:59
· 0 commits to main since this release

Astraea is an offline-first, privacy-first calendar. Events live on your device, are end-to-end encrypted with your own Nostr key (NIP-44), and sync through relays you pick yourself — no account, no server of ours.

This release supersedes the unpublished 0.4.0 and carries everything since 0.3.1.


✨ Sign in without ever handing over your key

NIP-46 remote signer ("bunker") login, on Android and Linux.

Paste a bunker:// connection string and the account private key never reaches the device. Astraea stores only a throwaway client key that your signer authorizes by public key — and can revoke at any time.

On Linux this is a login and unattended background signing, with no key material on the machine at all. It replaces the old advice to provision a local delegated key:

astraea-service auth connect-bunker   # paste bunker://… on stdin
astraea-service auth status           # signer: remote_nip46, state: ready

In the apps it's a "Sign in with a remote signer" field in Settings → Account (and in first-run onboarding on Android).

Every reply from the signer is checked before it is trusted: kind, author, NIP-01 event id and Schnorr signature — and for a signed event, that every field still matches what Astraea asked to have signed.

Implemented on top of the already-audited NIP-44 and relay-pool code rather than pulling in a NIP-46 client crate, whose dependency subtree compiles deprecated NIP-04 AES-CBC in as a feature-flag side effect. Only the JSON envelope handling is ours. See docs/authentication.md.

🔄 Sync when the app opens

Every launch now reconciles with your relays before you touch anything, on mobile and through the Linux service alike.

Amber (NIP-55) sessions stay manual on purpose — signing there is an intent into another app, so an automatic cycle would throw you into Amber on every launch.

🖼️ Android widgets finally preview properly

The widget picker showed an empty placeholder grid instead of the widget. The three providers declared no preview at all, so the picker fell back to inflating the live layout — whose list/grid has no data source outside the app.

Each widget now ships a previewLayout (API 31+) with static sample content, plus a rendered previewImage for API 24–30. The sample data is fictional on purpose: binding your real calendar into a preview would put your event titles in the launcher's widget picker.


🔒 Security & hardening

Area Change
Relay responses Added a total memory budget. The existing per-event and per-count caps multiplied out to hundreds of megabytes a hostile relay could make the app hold.
Kairos local socket Now bounds its read buffer while reading instead of after the fact — a peer that never sent a newline could previously be buffered without limit. Adds a connection cap and per-connection backpressure.
Relay list Capped at 16 on both the service and the mobile store, on read as well as write. Every relay is an open socket, a publish fan-out target, and another operator learning your pubkey and IP.
Sign-out Now also clears the cached profile and on-disk avatar, drops the live remote-signer connection, and closes bunker sockets.
Logs No longer record the account public key, deep-link targets or full avatar URLs — each ties a device log to a specific identity.
External signers Signed events from any external signer are verified field by field against the request, not only checked for a valid signature. Previously this held for Amber only.

🐛 Fixed

  • Overlapping sync cycles: the start-up sync racing a manual tap could run two full pull-merge-push passes at once over the same store.
  • The automatic sync is a start-up action rather than a "calendar screen mounted" action, so returning to the calendar no longer re-triggers it.
  • Version numbers agree again across pubspec.yaml, both Rust crates, AppStream and the RPM/Arch packaging — 0.3.1 had bumped pubspec.yaml alone.

🧹 Removed

  • The placeholder RemoteSigner backend that reported "not configured in this build" for every operation.

📦 Install

Android

Download astraea-0.4.1.apk below and install it. Minimum Android 7.0 (API 24).

Linux (Debian / Ubuntu / Pop!_OS)

Download the .deb files plus install.sh into the same folder, then:

chmod +x install.sh
sudo ./install.sh                 # add --no-extension on KDE/COSMIC

The packages stay separate on purpose (astraea-service, astraea-desktop, astraea-gnome-shell-extension) so you can skip the GNOME extension and upgrade each part on its own. Passing them all to one apt install is what makes the dependency order correct.

Or, without cloning the repo:

curl -fsSL https://raw.githubusercontent.com/Lwb89dev/astraea/v0.4.1/scripts/install-release.sh | sh

🔑 Checksums

Verify before installing:

bfa55b04d4ba50bf1bb034ad7ea1c6d04462850cf52313585616b5f2df378bbb  astraea-0.4.1.apk
23f17e46a46a52bcd4d0a8d674e8d01aaa2d1249cccfe4ccf950b8b2de400b43  astraea-service_0.4.1_amd64.deb
ed61eceb39c55a88a0ca46604a1c13f6b03666a0a4f0cf9f9ae859af1538970e  astraea-desktop_0.4.1_amd64.deb
fe5b09ade229fb730b39f45f3b92444b41240dba3f901d371a0715b8da0413ff  astraea-gnome-shell-extension_0.4.1_all.deb
1e63a5f1e2f9ab991921cc384ec3b246a995fb1a58282de3ff790cf1e47223c2  astraea-all_0.4.1_all.deb

The APK is signed with the project release key:

SHA-256  E2:A9:EA:50:E0:BB:39:40:06:BD:A3:A0:10:AA:FD:C2:38:ED:06:9E:7A:A2:91:61:95:F2:55:2F:5F:7E:C0:18

Full changelog: CHANGELOG.md · Licence: GPL-3.0-or-later