pub struct User<P: DeMlsProvider, H: GroupEventHandler, SCH: StateChangeHandler> { /* private fields */ }Expand description
User manages multiple MLS groups.
This struct provides the main application-level interface for working with MLS groups, handling consensus, and processing messages.
The type parameter P determines which service implementations are used
(storage, consensus). Use DefaultProvider for standard configuration.
The type parameter H is the handler that receives output events
(outbound packets, app messages, leave/join notifications).
The type parameter SCH is the handler for state machine state changes
(an app-layer concern, separate from the core GroupEventHandler).
Implementations§
Source§impl<P: DeMlsProvider, H: GroupEventHandler + 'static, SCH: StateChangeHandler + 'static> User<P, H, SCH>
impl<P: DeMlsProvider, H: GroupEventHandler + 'static, SCH: StateChangeHandler + 'static> User<P, H, SCH>
Sourcepub fn identity_string(&self) -> String
pub fn identity_string(&self) -> String
Get the user’s identity string (wallet address as checksummed hex).
Sourcepub async fn create_group(
&mut self,
group_name: &str,
is_creation: bool,
) -> Result<(), UserError>
pub async fn create_group( &mut self, group_name: &str, is_creation: bool, ) -> Result<(), UserError>
Create or join a group with the user’s default config.
§Arguments
group_name- The name of the groupis_creation-trueto create a new group as steward,falseto prepare to join
Sourcepub async fn create_group_with_config(
&mut self,
group_name: &str,
is_creation: bool,
config: GroupConfig,
) -> Result<(), UserError>
pub async fn create_group_with_config( &mut self, group_name: &str, is_creation: bool, config: GroupConfig, ) -> Result<(), UserError>
Create or join a group with custom config.
§Arguments
group_name- The name of the groupis_creation-trueto create a new group as steward,falseto prepare to joinconfig- Group-specific configuration
Sourcepub async fn leave_group(&mut self, group_name: &str) -> Result<(), UserError>
pub async fn leave_group(&mut self, group_name: &str) -> Result<(), UserError>
Leave a group.
For PendingJoin state: immediate cleanup (no MLS state exists).
For Leaving state: error (already leaving).
For Working/Waiting: transitions to Leaving and sends a self-removal
ban request. Actual cleanup happens when the removal commit arrives
via DispatchAction::LeaveGroup.
Sourcepub async fn get_group_state(
&self,
group_name: &str,
) -> Result<GroupState, UserError>
pub async fn get_group_state( &self, group_name: &str, ) -> Result<GroupState, UserError>
Get the state of a group.
Sourcepub async fn list_groups(&self) -> Vec<String>
pub async fn list_groups(&self) -> Vec<String>
List all group names.
Sourcepub async fn is_steward_for_group(
&self,
group_name: &str,
) -> Result<bool, UserError>
pub async fn is_steward_for_group( &self, group_name: &str, ) -> Result<bool, UserError>
Check if the user is steward for a group.
Sourcepub async fn get_group_members(
&self,
group_name: &str,
) -> Result<Vec<String>, UserError>
pub async fn get_group_members( &self, group_name: &str, ) -> Result<Vec<String>, UserError>
Get the members of a group.
Sourcepub async fn get_approved_proposal_for_current_epoch(
&self,
group_name: &str,
) -> Result<Vec<GroupUpdateRequest>, UserError>
pub async fn get_approved_proposal_for_current_epoch( &self, group_name: &str, ) -> Result<Vec<GroupUpdateRequest>, UserError>
Get current epoch proposals for a group.
Sourcepub async fn get_epoch_history(
&self,
group_name: &str,
) -> Result<Vec<Vec<GroupUpdateRequest>>, UserError>
pub async fn get_epoch_history( &self, group_name: &str, ) -> Result<Vec<Vec<GroupUpdateRequest>>, UserError>
Get epoch history for a group (past batches of approved proposals, most recent last).
Returns up to the last 10 epoch batches for UI display.
Sourcepub async fn send_kp_message(&self, group_name: &str) -> Result<(), UserError>
pub async fn send_kp_message(&self, group_name: &str) -> Result<(), UserError>
Build and send a key package message for a group via the handler.
Sourcepub async fn send_app_message(
&self,
group_name: &str,
message: Vec<u8>,
) -> Result<(), UserError>
pub async fn send_app_message( &self, group_name: &str, message: Vec<u8>, ) -> Result<(), UserError>
Send a conversation message to a group.
Allowed in Working and Leaving states (user is still a group member).
Blocked in PendingJoin (no MLS state) and Waiting (epoch freeze).
Sourcepub async fn process_ban_request(
&mut self,
ban_request: BanRequest,
group_name: &str,
) -> Result<(), UserError>
pub async fn process_ban_request( &mut self, ban_request: BanRequest, group_name: &str, ) -> Result<(), UserError>
Process a ban request.
Returns an error if the group is blocked (PendingJoin, Waiting, or Leaving state).
Sourcepub async fn check_pending_join(&self, group_name: &str) -> bool
pub async fn check_pending_join(&self, group_name: &str) -> bool
Check if still in pending join state.
Called periodically while in PendingJoin state to:
- Detect when the member has joined (state changed to Working)
- Check for timeout (time-based fallback if group is quiet after rejection)
Returns true if still waiting (PendingJoin), false if no longer pending
(either joined, timed out, or group not found).
Sourcepub async fn time_until_next_epoch(&self, group_name: &str) -> Option<Duration>
pub async fn time_until_next_epoch(&self, group_name: &str) -> Option<Duration>
Get the time until the next epoch boundary for a group.
Returns None if the group doesn’t exist or hasn’t synced yet.
Returns Some(Duration::ZERO) if we’re already past the boundary.
Sourcepub async fn check_commit_timeout(
&self,
group_name: &str,
) -> CommitTimeoutStatus
pub async fn check_commit_timeout( &self, group_name: &str, ) -> CommitTimeoutStatus
Check if the commit has timed out while in Waiting state.
Returns a CommitTimeoutStatus indicating:
NotWaiting— not in Waiting state (nothing to check)StillWaiting— in Waiting but timeout not reached yetTimedOut { has_proposals }— timeout reached, state reverted to Working
When timed out, checks if approved proposals still exist:
- If proposals exist: steward failed to commit (steward fault)
- If no proposals: false alarm (proposals cleared by other means)
In both cases the member is unblocked (reverted to Working) and the epoch boundary is re-synced to now.
Sourcepub async fn start_member_epoch(
&self,
group_name: &str,
) -> Result<bool, UserError>
pub async fn start_member_epoch( &self, group_name: &str, ) -> Result<bool, UserError>
Start a member epoch check.
Non-steward members call this at the epoch boundary (not before). If they have approved proposals, they transition to Waiting state expecting a commit.
Returns true if entered Waiting state (caller should poll for commit timeout),
false otherwise (no polling needed).
This method does nothing for stewards or members in PendingJoin/Leaving state.
Sourcepub async fn start_steward_epoch(
&mut self,
group_name: &str,
) -> Result<(), UserError>
pub async fn start_steward_epoch( &mut self, group_name: &str, ) -> Result<(), UserError>
Start a steward epoch.
pub async fn start_voting_on_request_background( &self, group_name: String, upd_request: GroupUpdateRequest, ) -> Result<(), UserError>
Sourcepub async fn process_user_vote(
&mut self,
group_name: &str,
proposal_id: u32,
vote: bool,
) -> Result<(), UserError>
pub async fn process_user_vote( &mut self, group_name: &str, proposal_id: u32, vote: bool, ) -> Result<(), UserError>
Process a user vote.
Allowed in Working, Leaving, and PendingJoin states.
Blocked in Waiting state (epoch freeze — vote is sent as MLS message).
Sourcepub async fn process_inbound_packet(
&self,
packet: InboundPacket,
) -> Result<(), UserError>
pub async fn process_inbound_packet( &self, packet: InboundPacket, ) -> Result<(), UserError>
Process an inbound packet.
Sourcepub async fn handle_consensus_event(
&mut self,
group_name: &str,
event: ConsensusEvent,
) -> Result<(), UserError>
pub async fn handle_consensus_event( &mut self, group_name: &str, event: ConsensusEvent, ) -> Result<(), UserError>
Handle a consensus event.
Source§impl<H: GroupEventHandler + 'static, SCH: StateChangeHandler + 'static> User<DefaultProvider, H, SCH>
impl<H: GroupEventHandler + 'static, SCH: StateChangeHandler + 'static> User<DefaultProvider, H, SCH>
Sourcepub fn with_private_key(
private_key: &str,
consensus_service: Arc<DefaultConsensusService>,
handler: Arc<H>,
state_handler: Arc<SCH>,
) -> Result<Self, UserError>
pub fn with_private_key( private_key: &str, consensus_service: Arc<DefaultConsensusService>, handler: Arc<H>, state_handler: Arc<SCH>, ) -> Result<Self, UserError>
Convenience constructor for the default provider with default group config.
Creates a User with MLS service and the given consensus service.
§Arguments
private_key- Ethereum private key as hex stringconsensus_service- The default consensus servicehandler- Event handler for output eventsstate_handler- Handler for state machine state changes
Sourcepub fn with_private_key_and_config(
private_key: &str,
consensus_service: Arc<DefaultConsensusService>,
handler: Arc<H>,
state_handler: Arc<SCH>,
default_group_config: GroupConfig,
) -> Result<Self, UserError>
pub fn with_private_key_and_config( private_key: &str, consensus_service: Arc<DefaultConsensusService>, handler: Arc<H>, state_handler: Arc<SCH>, default_group_config: GroupConfig, ) -> Result<Self, UserError>
Convenience constructor for the default provider with custom group config.
Creates a User with MLS service and the given consensus service.
§Arguments
private_key- Ethereum private key as hex stringconsensus_service- The default consensus servicehandler- Event handler for output eventsstate_handler- Handler for state machine state changesdefault_group_config- Default config applied to new groups
Auto Trait Implementations§
impl<P, H, SCH> !Freeze for User<P, H, SCH>
impl<P, H, SCH> !RefUnwindSafe for User<P, H, SCH>
impl<P, H, SCH> Send for User<P, H, SCH>
impl<P, H, SCH> Sync for User<P, H, SCH>
impl<P, H, SCH> Unpin for User<P, H, SCH>
impl<P, H, SCH> !UnwindSafe for User<P, H, SCH>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Declassify for T
impl<T> Declassify for T
type Declassified = T
fn declassify(self) -> T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more