Skip to main content

CoreContext

Struct CoreContext 

Source
pub struct CoreContext {
Show 20 fields pub profile: UserProfile, pub signing_key: PrivateKey, pub public_key: PublicKey, pub four_words: String, pub display_name: String, pub device_name: String, pub crdt_manager: Arc<CrdtManager>, pub entity_service: Arc<EntityService>, pub message_service: Arc<MessageService>, pub message_sync: Arc<MessageSyncService>, pub doc_replicator: Arc<DocReplicator>, pub listen_address: Option<SocketAddr>, pub connection_identity: Option<String>, pub external_address: Option<SocketAddr>, pub gossip: Option<Arc<GossipContext>>, pub group_keys: HashMap<String, GroupKeyPairPlaceholder>, pub disk_service: Arc<EntityDiskService>, pub webrtc: Option<Arc<CommunitasWebRtcService>>, pub kanban_service: Arc<KanbanService>, pub invite_service: Arc<InviteService>,
}
Expand description

Centralized context for the Communitas application

This replaces the old saorsa_core-based CoreContext with a simpler architecture based on saorsa-gossip for networking and four-word-networking for identities.

Lifecycle:

  1. Initialize with user profile (four-word ID, display name, device)
  2. Start gossip networking (optional, can run in local mode)
  3. Initialize message sync service
  4. Ready for operations

Fields§

§profile: UserProfile

User profile with identity and device info

§signing_key: PrivateKey

ML-DSA-87 post-quantum signing key (kept in memory for session)

§public_key: PublicKey

ML-DSA-87 post-quantum public key

§four_words: String

Four-word user identity (derived from public key)

§display_name: String

Display name for this user

§device_name: String

Device name for this instance

§crdt_manager: Arc<CrdtManager>

CRDT manager for persistent document storage

§entity_service: Arc<EntityService>

Entity service for managing groups, channels, and members

§message_service: Arc<MessageService>

Message service for unified messaging operations

§message_sync: Arc<MessageSyncService>

Message synchronization service (CRDT-based) - legacy, use message_service instead

§doc_replicator: Arc<DocReplicator>

Document replicator for collaborative editing (CRDT-based, Yrs) Handles dual-storage: Files (encrypted) + Web (public)

§listen_address: Option<SocketAddr>

Current listen address (if networking is active)

§connection_identity: Option<String>

Connection identity (four-word encoded listen address)

§external_address: Option<SocketAddr>

External/public address (NAT-reflected address for WAN connectivity) This is the address that other peers on the internet see us at, obtained via address reflection from a coordinator/bootstrap node

§gossip: Option<Arc<GossipContext>>

Gossip overlay system (replaces DHT-based networking) Handles P2P networking, membership, pubsub, presence, and discovery

§group_keys: HashMap<String, GroupKeyPairPlaceholder>

Group keys for channels/projects/orgs (MLS-based) Maps group ID to group keypair

§disk_service: Arc<EntityDiskService>

Per-entity virtual disk service (Private, Public, Shared disks)

§webrtc: Option<Arc<CommunitasWebRtcService>>

WebRTC service for voice, video, and screen sharing Initialized when networking starts (requires gossip context)

§kanban_service: Arc<KanbanService>

Kanban service for project management boards CRDT-based, offline-first collaborative Kanban system

§invite_service: Arc<InviteService>

Invite service for cross-organization collaboration Handles four-word invite creation, acceptance, rejection, and revocation

Implementations§

Source§

impl CoreContext

Source

pub async fn initialize( four_words: String, display_name: String, device_name: String, device_type: DeviceType, storage_dir: PathBuf, ) -> Result<Self, String>

Initialize a new CoreContext from a four-word identity

This creates a new profile with:

  • Generated Ed25519 keypair
  • Four-word user identity derived from public key
  • Local storage directory

Note: This does NOT start networking. Call start_networking() separately.

§Arguments
  • four_words - Four-word user identity (e.g., “ocean-forest-moon-star”)
  • display_name - Human-readable display name
  • device_name - Device identifier for this instance
  • device_type - Device type classification
  • storage_dir - Directory for profile storage
§Returns

New CoreContext instance

§Errors

Returns error if:

  • Four-word format is invalid
  • Storage directory cannot be created
  • Message sync initialization fails
Source

pub async fn start_networking( &mut self, preferred_port: Option<u16>, ) -> Result<String, String>

Start networking with gossip overlay system

Initializes the saorsa-gossip based P2P networking layer:

  • Creates QUIC transport on random high port (49152-65535)
  • Initializes HyParView membership and Plumtree pubsub
  • Sets up peer cache for fast boot
  • Connects to coordinator and rendezvous services
  • Generates connection identity (four-word encoded address)
§Arguments
  • _port - Optional specific port (currently ignored, transport auto-selects)
§Returns

Connection identity (four-word encoded address)

Source

pub async fn auto_request_external_address(&mut self) -> Result<(), String>

Automatically request external address with retry logic

This is called after networking starts to discover our public IP address. It retries a few times with delays to allow peer connections to establish.

§Returns

Ok if external address was successfully determined, Err otherwise

Source

pub async fn request_external_address(&mut self) -> Result<(), String>

Request external/public address via NAT reflection from a bootstrap node

Get our external IP address and port as seen from the internet.

This uses the native QUIC OBSERVED_ADDRESS frame mechanism (draft-ietf-quic-address-discovery) which is automatically exchanged during QUIC connection establishment.

Should be called after networking is active and we have connections to bootstrap nodes.

§Returns

The external address if successfully obtained, or an error message

Source

pub async fn stop_networking(&mut self) -> Result<(), String>

Stop networking gracefully

Shuts down gossip services, presence beacons, and transport

Source

pub async fn connect_to_peer(&self, peer_four_words: &str) -> Result<(), String>

Connect to a peer using their four-word identity

This adds the peer to favourite contacts and initiates FOAF discovery. The gossip overlay will find and connect to the peer automatically.

§Arguments
  • peer_four_words - The peer’s four-word identity (e.g., “ocean-forest-moon-star”)
§Returns

Success if peer added to favourites

Source

pub async fn send_and_publish_channel_message( &self, channel_id: String, content_text: String, reply_to_id: Option<String>, ) -> Result<String, String>

Send a channel message and publish it to gossip if networking is active

This method:

  1. Stores the message locally via CRDT
  2. If gossip is active, joins the entity topic and publishes for P2P sync
§Arguments
  • channel_id - The channel to send to
  • content_text - The message text
  • reply_to_id - Optional parent message for threading
§Returns

The message ID on success

Source

pub fn add_group_key(&mut self, group_id: String, key: GroupKeyPairPlaceholder)

Add a group key for a channel/project/org

§Arguments
  • group_id - Group identifier
  • key - Group key material (placeholder for now)
Source

pub fn get_public_key(&self) -> &PublicKey

Get the ML-DSA-87 public key for this identity

Source

pub fn public_key_bytes(&self) -> [u8; 2592]

Get the public key bytes ML-DSA-87 public keys are 2592 bytes

Source

pub fn sign(&self, message: &[u8]) -> Result<[u8; 4627], String>

Sign a message with ML-DSA-87 post-quantum signature

§Arguments
  • message - Message bytes to sign
§Returns

ML-DSA-87 signature (4627 bytes for ML-DSA-87)

§Errors

Returns error if signing fails

Source

pub fn verify(&self, message: &[u8], signature: &[u8; 4627]) -> bool

Verify an ML-DSA-87 signature

§Arguments
  • message - Message bytes that were signed
  • signature - ML-DSA-87 signature (4627 bytes)
§Returns

true if signature is valid, false otherwise

Source

pub fn storage_dir(&self) -> &PathBuf

Get the storage directory for this profile

Source

pub fn is_networking_active(&self) -> bool

Check if networking is active

Source

pub fn connection_identity(&self) -> Option<&str>

Get connection identity (if networking is active)

Source

pub fn set_display_name(&mut self, display_name: String)

Update display name

Source

pub fn device_type(&self) -> DeviceType

Get device type

Source

pub fn has_passkey(&self) -> bool

Check if passkey is registered for this profile

Trait Implementations§

Source§

impl Debug for CoreContext

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more