# API Overview
## MessengerClient
- `fn new(local: LocalIdentity, transport: Arc<dyn Transport>) -> Self`
- `fn ensure_session_with(&mut self, remote: &str, bootstrap: SessionBootstrap) -> Result<()>`
- `async fn send_text(&mut self, remote: &str, text_utf8: &str) -> Result<Uuid>`
- `async fn send_attachment_bytes(&mut self, remote: &str, kind: AttachmentKind, filename: Option<&str>, content_type: Option<&str>, bytes: &[u8], chunk_size: usize) -> Result<Uuid>`
- `async fn poll_once(&mut self) -> Result<Option<ClientEvent>>`
- `async fn close(&self) -> Result<()>`
`ClientEvent` variants:
- `MessageReceived { from, message }`
- `AttachmentProgress { from, attachment_id, received_chunks, total_chunks }`
- `AttachmentCompleted { from, attachment_id, total_size }`
## SessionBootstrap
Currently a single variant:
```
PreSharedSecret {
secret32: [u8; 32],
role: InitiatorOrResponder,
remote_dh_pub: Option<[u8; 32]>,
}
```
The role governs how send/receive chains are ordered. The remote DH value is optional extra entropy for deployments that already exchange public keys.
## Transport Trait
```
#[async_trait]
pub trait Transport {
async fn send(&self, data: Bytes) -> Result<()>;
async fn recv(&self) -> Result<Bytes>;
async fn close(&self) -> Result<()>;
}
```
`in_memory_duplex_pair` produces two `Transport` instances backed by bounded channels, ideal for tests.
## Attachment Helpers
- `build_attachment_init` – produce an init `Message` with metadata (kind, size, chunk count)
- `build_attachment_chunks` – split raw bytes into chunk messages with indices
- `build_attachment_end` – finalizer referencing attachment id, total size, and chunk count