Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

account-api: the account service

Standard port(s): bind 8180, health 8191.

Wallet-challenge login (issuing a JWT), plus mail passwords, timezone, and do-not-disturb schedule management.

With a [chain] section configured, the API additionally serves the authenticated /v1/chain surface — an on-chain read proxy (SOL balance, mailbox, published encryption key, aliases, per-sender stamp balances) plus a relay for transactions the client built and signed itself. This is the browser-reachable surface the Thunderbird extension rides: mail-grpc holds a hot signing key and speaks raw gRPC, so browsers never talk to it directly. Reads always answer for the JWT’s wallet; the relay never signs anything. Without [chain], those routes answer 503.

The API also serves the /v1/mail surface — the user-facing mail routes (folders and folder CRUD, message pages with parsed summaries, full rendering, raw/part downloads, flags, move/delete, and a capped scan search with a resume cursor) over the same store the IMAP/POP servers serve. No IMAP bridge is involved: webmail and the Outlook add-in read the rows and blobs directly through these routes, authenticated by the same JWT as the account surface. It needs no configuration beyond [store].

The one write route that leaves the store is compose (POST /v1/mail/send): the API builds the RFC822 message and spools it through the same core sithbitd’s SMTP sink uses — local recipients get mailbox rows and background chain jobs, foreign domains get relay jobs the spooler’s relay worker drains (the two binaries share the store, so no extra wiring), and the composer gets an already-read Sent copy. Routing is configured by the [mail] section: local_domains names the domains whose recipients live in this store (mirror sithbitd’s local_domains; aliases and the stamp precheck resolve over the [chain] gateway — without one, only literal wallet addresses resolve locally), and [mail.dkim] (same one-or-many shape as [spooler.dkim]) signs composed mail. Both default off: with no local domains everything relays — mail addressed to this deployment’s own domain then loops back through its MX, which is correct, just slower — and with no keys relayed mail goes unsigned.

Two semantics worth knowing when these routes mutate mail:

  • Move settles the source’s chain copy. Exactly like IMAP MOVE, a move is copy + expunge: the surviving copy is server-local, and the original’s on-chain message and IPFS pin are torn down in the background. Deleting does the same teardown directly.
  • IMAP IDLE sees API changes with a delay. The API and sithbitd are separate processes, so a webmail mutation reaches an idling IMAP client via sithbitd’s change poller ([imap] watch_poll_seconds), not instantly. Flag-only changes on a SQLite store don’t bump the change sequence at all — they surface with the next real mailbox event.

With a [static] section configured, the API also serves a static directory (default route /addin) on its own origin — this is how the Outlook add-in’s built bundle (webclients/outlook/staging) is hosted, so the add-in’s pages call /v1/… same-origin with no CORS configuration. Office requires the add-in over https: either front the API with a TLS-terminating reverse proxy (the production recommendation) or enable the built-in [tls] listener. A dev certificate for sideloading is one command —

openssl req -x509 -newkey ed25519 -keyout key.pem -out cert.pem \
  -days 365 -nodes -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost"

— then trust cert.pem in the OS store (Office rejects untrusted certificates even on localhost).

When you need it: only if you’re exposing self-service account management — for example, the Thunderbird extension, the Outlook add-in, or a webmail UI — rather than administering accounts purely through the CLI.

Quickstart:

cargo run -p account-api

Config file account_api.toml, or point ACCOUNT_API_CONFIG at an alternate path. It shares sithbitd’s [store] — point both at the same database so account state and mail state stay consistent.

See the Configuration reference for the full key/default table.