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

The webmail app

A plain-browser webmail client: the folder rail, a newest-first message list with per-folder search, a sandboxed reader, and a compose pane — plus the same wallet login and settings panes the Thunderbird and Outlook clients carry, because all three hosts run the same shared core (webclients/shared/). Everything that must be signed is signed in the page by a WebAssembly module compiled from this workspace’s own crates; the server only relays already-signed transactions and never holds your key.

Navigation is hash-only — #/mail (the three-pane mail view) and #/settings (the shared dashboard panes). There is no build framework and no CDN: the bundle is static files served by account-api itself.

What the operator must run

The app is served same-origin from account-api’s [static] section, so the API base URL is simply the page’s own origin and no CORS setup exists at all. Reading mail rides the /v1/mail surface, which needs only the shared [store]. Compose (POST /v1/mail/send) routes recipients the way sithbitd’s submission port does, so its reach follows the API’s config:

  • No extra config — bare base58 wallet addresses deliver locally; anything else answers 503 (alias resolution needs the chain).
  • [chain] — aliases and user@your-domain addresses resolve through the gateway, with the frombox postage precheck applied before the message is accepted.
  • [mail] (local_domains, [mail.dkim]) — mirrors sithbitd’s submission settings: which domains are yours (everything else is relayed) and the DKIM keys relayed mail is signed with.

As with the other clients, the aliases/balances/keys settings panes also need [chain]; login, mail reading, and the account settings work without it.

Building and serving

cd webclients/webmail
./build.sh    # wasm-pack build + stages shared/ into staging/

staging/ is the deployable bundle. Point account-api at it:

[static]
route = "/mail"
root = "webclients/webmail/staging"

then open http://127.0.0.1:8180/mail/index.html (or your deployment’s origin). First run: paste your Solana keypair file and choose a passphrase — the key is encrypted with that passphrase before it lands in the browser’s localStorage, and the passphrase is asked for again each time you open the app.

Using it

The #/mail view is three panes. The folder rail lists your folders with unseen counts; the middle column stacks per-folder search over the message list (keyset-paged, newest first); the reader marks messages read on open, toggles text/HTML/raw views (HTML render in a fully sandboxed iframe that blocks scripts and remote loads), downloads attachments, flags, moves, and deletes. Compose floats bottom-right: To/Cc take comma-separated addresses — aliases, user@domain, or bare wallet addresses — and the reader’s Reply action opens it prefilled (sender as To, Re: subject, threading header). A successful send files an already-read copy in Sent and refreshes the folder counts; recipient problems (unknown alias, no stamps on your frombox) surface on the pane with your draft intact.

The #/settings view is the shared dashboard: mail password, timezone, do-not-disturb, aliases, balances, and delegated encryption-key management, exactly as documented for the Thunderbird extension.

The compose loop is exercised headlessly by the env-gated live suite webclients/webmail/test/e2e-webmail.test.js — the bundle served from a real account-api, a real send to a throwaway wallet, and the message read back from the recipient’s INBOX (the runbook lives in webclients/README.md).