ma_core/lib.rs
1//! # ma-core
2//!
3//! A lean `DIDComm` service library for the ma ecosystem.
4//!
5//! `ma-core` provides the building blocks for ma-capable endpoints:
6//!
7//! - **DID documents** — create, validate, resolve, and publish `did:ma:` documents
8//! to IPFS/IPNS (via Kubo on native targets).
9//! - **Service inboxes** — bounded, TTL-aware FIFO queues ([`Inbox`])
10//! for receiving validated messages on named protocol services.
11//! - **Outbound sending** — fire-and-forget delivery of validated [`Message`] objects
12//! to remote endpoints, serialized to CBOR on the wire.
13//! - **Endpoint abstraction** — the [`MaEndpoint`] trait with pluggable
14//! transport backends.
15//! - **Transport parsing** — extract endpoint IDs and protocols from DID document
16//! service strings (`/iroh/<id>/<protocol>`).
17//! - **Identity bootstrap** — secure secret key generation and persistence.
18//!
19//! ## Services
20//!
21//! Every endpoint must provide `/ma/inbox/0.0.1` (the default inbox).
22//! Endpoints may optionally provide `ma/ipfs/0.0.1` to publish DID documents
23//! on behalf of others.
24//!
25//! ## Feature flags
26//!
27//! - **`kubo`** — enables native IPFS RPC backend for publishing (native only).
28//! - **`iroh`** — enables the internal iroh QUIC transport backend.
29//! - **`gossip`** — enables internal iroh-gossip broadcast support.
30//! - **`config`** — enables [`Config`], [`SecretBundle`], and [`MaArgs`] for
31//! YAML-based daemon configuration, encrypted secret bundles, and CLI
32//! argument parsing.
33//!
34//! ## Platform support
35//!
36//! Core types (`Inbox`, `Service`, transport parsing, validation)
37//! compile on all targets including `wasm32-unknown-unknown`.
38//!
39//! ### wasm vs native
40//!
41//! - `ma-core` supports both wasm and native targets.
42//! - `IpfsGatewayResolver` (HTTP gateway DID fetch) is available on wasm and native.
43//! - Native IPFS RPC write/pin APIs are native-only (`not(wasm32)` + `kubo` feature).
44//! - wasm builds expose only `ipfs::gateway_resolver` (no native RPC helpers).
45//! - `config` serialization and `SecretBundle` crypto work on wasm.
46//! - `config` filesystem paths, CLI/env merging, and file I/O are native-only.
47//! - If your wasm application needs native IPFS RPC write/pin operations, provide
48//! them in a native companion layer.
49
50#![forbid(unsafe_code)]
51#![allow(
52 clippy::cast_possible_truncation,
53 clippy::cast_precision_loss,
54 clippy::if_not_else,
55 clippy::items_after_statements,
56 clippy::manual_let_else,
57 clippy::map_unwrap_or,
58 clippy::missing_errors_doc,
59 clippy::must_use_candidate,
60 clippy::uninlined_format_args
61)]
62
63#[cfg(feature = "acl")]
64pub mod acl;
65#[cfg(feature = "config")]
66pub mod config;
67pub mod constants;
68pub mod did;
69pub mod doc;
70pub mod endpoint;
71pub mod error;
72pub mod identity;
73pub mod inbox;
74pub mod interfaces;
75pub mod ipfs;
76#[cfg(feature = "iroh")]
77#[allow(dead_code)]
78mod iroh;
79pub mod key;
80#[cfg(feature = "kubo")]
81pub mod kubo;
82pub mod msg;
83mod multiformat;
84#[cfg(feature = "iroh")]
85#[allow(dead_code)]
86mod outbox;
87pub mod service;
88pub mod topic;
89pub mod transport;
90pub(crate) mod ttl_queue;
91
92// ─── Re-export DID/message primitives ───────────────────────────────────────
93
94pub use did::{Did, DID_PREFIX};
95pub use doc::{
96 now_iso_utc, Document, Proof, VerificationMethod, DEFAULT_DID_CONTEXT, DEFAULT_PROOF_PURPOSE,
97 DEFAULT_PROOF_TYPE,
98};
99pub use error::{Error, MaError, Result};
100pub use identity::{
101 generate_identity, generate_identity_from_secret, ipns_from_secret, GeneratedIdentity,
102};
103pub use ipld_core::ipld::Ipld;
104pub use key::{
105 EncryptionKey, SigningKey, ASSERTION_METHOD_KEY_TYPE, ED25519_PUB_CODEC, EDDSA_SIG_CODEC,
106 KEY_AGREEMENT_KEY_TYPE, X25519_PUB_CODEC,
107};
108pub use msg::{
109 Envelope, Headers, Message, ReplayGuard, DEFAULT_MAX_CLOCK_SKEW_SECS, DEFAULT_MESSAGE_TTL_SECS,
110 DEFAULT_REPLAY_WINDOW_SECS, MESSAGE_PREFIX,
111};
112
113#[cfg(feature = "acl")]
114pub use acl::Acl;
115
116// ─── Re-export service constants ────────────────────────────────────────────
117
118pub use service::{
119 Service, BROADCAST_PROTOCOL, BROADCAST_TOPIC, CONTENT_TYPE_BROADCAST, CONTENT_TYPE_DOC,
120 CONTENT_TYPE_IPFS_REQUEST, CONTENT_TYPE_MESSAGE, INBOX_PROTOCOL, INBOX_PROTOCOL_ID,
121 IPFS_PROTOCOL,
122};
123
124// ─── Re-export Inbox ────────────────────────────────────────────────────────
125
126pub use inbox::Inbox;
127
128// ─── Re-export Topic ────────────────────────────────────────────────────────
129
130pub use topic::{topic_id, Topic, TopicId};
131
132// ─── Re-export endpoint trait and implementations ───────────────────────────
133
134pub use endpoint::{MaEndpoint, DEFAULT_DELIVERY_PROTOCOL_ID};
135#[cfg(feature = "iroh")]
136pub use outbox::Outbox;
137
138/// Create a default ma endpoint backend from 32-byte secret key material.
139///
140/// This keeps the transport backend type internal while exposing
141/// [`MaEndpoint`] and [`Outbox`] as stable API surfaces.
142#[cfg(feature = "iroh")]
143pub async fn new_ma_endpoint(secret_bytes: [u8; 32]) -> Result<Box<dyn MaEndpoint>> {
144 let endpoint = iroh::new_endpoint(secret_bytes).await?;
145 Ok(Box::new(endpoint))
146}
147
148// ─── Re-export transport parsing ────────────────────────────────────────────
149
150pub use transport::{
151 endpoint_id_from_transport, endpoint_id_from_transport_value, normalize_endpoint_id,
152 protocol_from_transport, resolve_endpoint_for_protocol, resolve_inbox_endpoint_id,
153 transport_string,
154};
155
156// ─── Re-export identity helpers ─────────────────────────────────────────────
157
158pub use identity::{generate_secret_key_file, load_secret_key_bytes, socket_addr_to_multiaddr};
159
160// ─── Re-export config types ──────────────────────────────────────────────────
161
162#[cfg(all(feature = "config", not(target_arch = "wasm32")))]
163pub use config::MaArgs;
164#[cfg(feature = "config")]
165pub use config::{BrowserIdentityExport, Config, SecretBundle};
166
167// ─── Re-export DID resolution ───────────────────────────────────────────────
168
169pub use ipfs::gateway_resolver::{DidDocumentResolver, IpfsGatewayResolver};
170
171// ─── Re-export existing modules ─────────────────────────────────────────────
172
173pub use interfaces::{DidPublisher, IpfsPublisher};
174pub use ipfs::*;