//! quicnprotochat CLI client library. //! //! # KeyPackage expiry and refresh //! //! KeyPackages are single-use (consumed when someone fetches them for an invite) and the server //! may enforce a TTL (e.g. 24 hours). To stay invitable, run `quicnprotochat refresh-keypackage` //! periodically (e.g. before the server TTL) or after your KeyPackage was consumed: //! //! ```bash //! quicnprotochat refresh-keypackage --state quicnprotochat-state.bin --server 127.0.0.1:7000 //! ``` //! //! Use the same `--access-token` (or `QUICNPROTOCHAT_ACCESS_TOKEN`) as for other authenticated //! commands. See the [running-the-client](https://docs.quicnprotochat.dev/getting-started/running-the-client) //! docs for details. use std::sync::OnceLock; pub mod client; pub use client::commands::{ cmd_chat, cmd_check_key, cmd_create_group, cmd_demo_group, cmd_fetch_key, cmd_health, cmd_health_json, cmd_invite, cmd_join, cmd_login, cmd_ping, cmd_recv, cmd_register, cmd_register_state, cmd_refresh_keypackage, cmd_register_user, cmd_send, cmd_whoami, receive_pending_plaintexts, whoami_json, }; pub use client::rpc::{connect_node, enqueue, fetch_wait}; pub use client::state::{load_existing_state, StoredState}; // Global auth context initialized once per process. pub(crate) static AUTH_CONTEXT: OnceLock = OnceLock::new(); #[derive(Clone, Debug)] pub struct ClientAuth { pub(crate) version: u16, pub(crate) access_token: Vec, pub(crate) device_id: Vec, } impl ClientAuth { /// Build a client auth context from optional token and device id. pub fn from_parts(access_token: String, device_id: Option) -> Self { let token = access_token.into_bytes(); let device = device_id.unwrap_or_default().into_bytes(); Self { version: 1, access_token: token, device_id: device, } } } /// Initialize the global auth context; subsequent calls are ignored. pub fn init_auth(ctx: ClientAuth) { let _ = AUTH_CONTEXT.set(ctx); }