You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today the core nostr-mail capabilities (NIP-44/NIP-04 encryption, hybrid attachment encryption, Nostr key/profile/DM handling, SMTP/IMAP email delivery, and the glossia wire format) live inside the Tauri backend crate (tauri-app/backend, lib name nostr_mail_lib) and are tightly coupled to the desktop app. There is no clean, documented way for another application to reuse this logic.
We should extract and package the core functionality as a standalone SDK so developers can integrate nostr-mail-style encrypted email into their own apps without depending on the full Tauri desktop application.
Motivation
Reuse: The encryption + Nostr key registry bridge + glossia wire format is the valuable, reusable part of nostr-mail. Other clients (web, mobile, bots, server-side integrations) should be able to send/receive nostr-mail-encrypted messages.
Adoption: A documented SDK lowers the barrier for the ecosystem to adopt the nostr-mail message format, which is the project's stated goal of bridging Nostr and email for the average person.
Maintainability: Forcing a clean SDK boundary separates core protocol logic from app/UI/storage concerns, making the core easier to test and evolve.
Proposed scope
Expose the core building blocks behind a stable, well-documented API:
Crypto: derive shared secret from a sender private key + receiver public key; encrypt/decrypt with NIP-44 (default) and NIP-04 (legacy); hybrid encryption for attachments (AES-256 for files, NIP-44 for keys); sign/verify.
Glossia encoding (wire format): encode/decode of NIP-04/NIP-44 ciphertext as natural-language prose (Latin, Bip39-english, …) carried as ordinary text/plain. This is what gives nostr-mail emails a wire format that survives replies, forwards, and inline quoting, and is what lets subject lines be encrypted (the subject is glossia-encoded ciphertext, not armor). The SDK should expose:
encode/decode (transcode) ciphertext ↔ glossia prose, with selectable dialect/wordlist;
dialect detection (detect_dialect_best) and raw base-N encode/decode;
subject-line encrypt/decode helpers;
the Cap'n Proto armor/structure (tauri-app/backend/schema/nostr_mail.capnp, nostr_mail_capnp.rs) that frames body / signature / seal blocks and supports nested quoted blocks so each quoted section in a reply chain remains independently decodable/verifiable.
Existing surface to draw from: the Tauri commands glossia_transcode, glossia_detect_dialect, glossia_encode_raw_base_n, glossia_decode_raw_base_n, glossia_get_default_wordlist, and per-field encoding settings (glossia_encoding_body / _signature / _pubkey).
Email: compose, encrypt (incl. glossia-encoded subject + body), and send via SMTP; fetch, de-glossia, and decrypt via IMAP; parse the nostr-mail message format including nested armor in reply/forward chains.
Message format: a documented, versioned spec for how an encrypted nostr-mail email is structured on the wire (glossia prose + Cap'n Proto armor + signature/seal nesting), so non-Rust clients can interoperate. See docs/nostr-mail-spec.md and docs/glossia-design.md.
Out of scope for the first cut: UI, local SQLite caching, and app-specific settings — those stay in the Tauri app and consume the SDK.
Note on glossia packaging
Glossia currently lives in a separate git submodule (asherp/glossia). The SDK should depend on it as a normal crate/dependency (and ship the wordlist data) rather than via the desktop app's submodule wiring. Decide whether glossia is published as its own crate the SDK depends on, or vendored into the SDK.
Possible approaches
Rust crate — refactor the core out of nostr_mail_lib into a dependency-free (no Tauri) nostr-mail-core / nostr-mail-sdk crate published to crates.io, depending on the glossia crate. The Tauri app depends on it. Lowest-effort, highest-fidelity reuse of existing code.
WASM bindings — compile the Rust core to WebAssembly with a JS/TS wrapper so web and Node integrations can use it directly. (Note: a prior ~38MB glossia WASM blob + wasm-pack hook were removed; revisit size/strategy for the WASM target.)
Language bindings — expose the core via FFI / a thin C ABI (the crate already builds staticlib/cdylib) for use from other languages, or via uniffi for Swift/Kotlin/Python.
A reasonable path: start with (1) to establish a clean core crate + glossia integration + message-format spec, then layer (2)/(3) on top.
Acceptance criteria
Core encryption / Nostr / email / glossia logic extracted into a Tauri-independent SDK package.
SDK exposes glossia encode/decode (with dialect selection + detection), encrypted-subject helpers, and Cap'n Proto armor framing with nested-quote support.
Documented, versioned nostr-mail message-format spec covering glossia prose, the Cap'n Proto armor, and signature/seal nesting across reply/forward chains.
Public API documentation with usage examples (encrypt+glossia-encode+send, fetch+de-glossia+decrypt, encrypted subject round-trip, key/profile management).
Summary
Today the core nostr-mail capabilities (NIP-44/NIP-04 encryption, hybrid attachment encryption, Nostr key/profile/DM handling, SMTP/IMAP email delivery, and the glossia wire format) live inside the Tauri backend crate (
tauri-app/backend, lib namenostr_mail_lib) and are tightly coupled to the desktop app. There is no clean, documented way for another application to reuse this logic.We should extract and package the core functionality as a standalone SDK so developers can integrate nostr-mail-style encrypted email into their own apps without depending on the full Tauri desktop application.
Motivation
Proposed scope
Expose the core building blocks behind a stable, well-documented API:
text/plain. This is what gives nostr-mail emails a wire format that survives replies, forwards, and inline quoting, and is what lets subject lines be encrypted (the subject is glossia-encoded ciphertext, not armor). The SDK should expose:detect_dialect_best) and raw base-N encode/decode;tauri-app/backend/schema/nostr_mail.capnp,nostr_mail_capnp.rs) that frames body / signature / seal blocks and supports nested quoted blocks so each quoted section in a reply chain remains independently decodable/verifiable.glossia_transcode,glossia_detect_dialect,glossia_encode_raw_base_n,glossia_decode_raw_base_n,glossia_get_default_wordlist, and per-field encoding settings (glossia_encoding_body/_signature/_pubkey).docs/nostr-mail-spec.mdanddocs/glossia-design.md.Out of scope for the first cut: UI, local SQLite caching, and app-specific settings — those stay in the Tauri app and consume the SDK.
Note on glossia packaging
Glossia currently lives in a separate git submodule (
asherp/glossia). The SDK should depend on it as a normal crate/dependency (and ship the wordlist data) rather than via the desktop app's submodule wiring. Decide whether glossia is published as its own crate the SDK depends on, or vendored into the SDK.Possible approaches
nostr_mail_libinto a dependency-free (no Tauri)nostr-mail-core/nostr-mail-sdkcrate published to crates.io, depending on theglossiacrate. The Tauri app depends on it. Lowest-effort, highest-fidelity reuse of existing code.wasm-packhook were removed; revisit size/strategy for the WASM target.)staticlib/cdylib) for use from other languages, or via uniffi for Swift/Kotlin/Python.A reasonable path: start with (1) to establish a clean core crate + glossia integration + message-format spec, then layer (2)/(3) on top.
Acceptance criteria
Open questions
asherp/glossiaas its own crate the SDK depends on, or vendor it? How are wordlists shipped, and how is WASM size handled?1.0.8).