# LxmfEx
LXMF (Lightweight Extensible Message Format) for Elixir, interoperable with [markqvist/LXMF](https://github.com/markqvist/lxmf) and Reticulum. Provides message packing/unpacking, propagated store-and-forward, and a router with pluggable transport (works with `reticulum_ex`).
## Status
- Direct delivery uses Reticulum link-layer encryption (ECDH + AES-128).
- Propagated delivery is supported via destination-layer encryption (ECDH + Fernet-based token) in `reticulum_ex` NIF.
- Paper/QR support and full auto-peering to be completed.
## Installation
Add to your `mix.exs`:
```elixir
def deps do
[
{:lxmf_ex, "~> 0.1.0"},
{:reticulum_ex, "~> 0.1.0"}
]
end
```
## Quick start
Start a router with the Reticulum transport and an identity for decrypting propagated messages:
```elixir
{:ok, id} = ReticulumEx.Identity.new_from_rand()
{:ok, router} = LxmfEx.Router.start_link(
transport_mod: LxmfEx.Transport.Reticulum,
storage_dir: "/tmp/lxmf_store",
identity_ref: id,
on_inbound: fn lxm -> IO.inspect({:inbound, lxm.title, lxm.content}) end
)
# Build a direct message
msg = LxmfEx.Message.new(
destination_hash: <<dest::128>>, # 16-byte destination hash
source_hash: <<src::128>>, # 16-byte source hash
title: "Hello",
content: "World",
method: :direct
)
hasher = fn iodata -> :crypto.hash(:sha256, IO.iodata_to_binary(iodata)) end
signer = fn data -> :crypto.hash(:sha512, data) |> binary_part(0, 64) end
{:ok, _} = LxmfEx.Router.send_message(router, msg, hasher, signer)
```
To send a propagated message, set `method: :propagated` on the message. Inbound propagated containers are decrypted using the router `:identity_ref`.
## Docs
HexDocs: https://hexdocs.pm/lxmf_ex
API highlights:
- `LxmfEx.Message`: LXM structure, `pack/3`, `unpack/1`.
- `LxmfEx.Router`: send/receive, propagated store, peering helpers.
- `LxmfEx.Transport`: behaviour; use `LxmfEx.Transport.Reticulum` in production.
## License
MIT. See `LICENSE`.