pub struct MlsGroup<Context> {
pub group_id: GroupId,
pub dm_id: Option<String>,
pub conversation_type: ConversationType,
pub created_at_ns: i64,
pub context: Context,
/* private fields */
}Expand description
Fields§
§group_id: GroupId§dm_id: Option<String>§conversation_type: ConversationType§created_at_ns: i64§context: ContextImplementations§
Source§impl<Context: XmtpSharedContext> MlsGroup<Context>
impl<Context: XmtpSharedContext> MlsGroup<Context>
Sourcepub fn set_notifications(
&self,
value: NotificationOverride,
) -> Result<(), StorageError>
pub fn set_notifications( &self, value: NotificationOverride, ) -> Result<(), StorageError>
Set an override after which the task recomputes the desired set.
Sourcepub fn notifications_enabled(&self) -> Result<bool, StorageError>
pub fn notifications_enabled(&self) -> Result<bool, StorageError>
Return the effective local rule for this conversation.
Source§impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
Represents a group, which can contain anywhere from 1 to MAX_GROUP_SIZE inboxes.
impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
Represents a group, which can contain anywhere from 1 to MAX_GROUP_SIZE inboxes.
This is a wrapper around OpenMLS’s MlsGroup that handles our application-level configuration
and validations.
pub fn new( context: Context, group_id: GroupId, dm_id: Option<String>, conversation_type: ConversationType, created_at_ns: i64, ) -> Self
Sourcepub fn new_cached(
context: Context,
group_id: &GroupId,
) -> Result<(Self, StoredGroup), StorageError>
pub fn new_cached( context: Context, group_id: &GroupId, ) -> Result<(Self, StoredGroup), StorageError>
Creates a new group instance from the database. Validate that the group exists in the DB before constructing the group.
§Returns
Returns the Group and the stored group information as a tuple.
Sourcepub async fn all_members_support_proposals(
&self,
mls_group: &OpenMlsGroup,
) -> Result<bool, GroupError>
pub async fn all_members_support_proposals( &self, mls_group: &OpenMlsGroup, ) -> Result<bool, GroupError>
Check if all members in the group support the proposal-by-reference flow.
This checks both:
- Leaf node capabilities in the MLS group (via
check_extension_support) - The latest published key packages for all member installations fetched from the network, since leaf nodes may be stale (they aren’t updated after the first message is sent).
Returns true if all members support proposals, false otherwise.
Sourcepub async fn membership_capabilities(
&self,
) -> Result<GroupMembershipCapabilities, GroupError>
pub async fn membership_capabilities( &self, ) -> Result<GroupMembershipCapabilities, GroupError>
Snapshot this group’s membership capabilities: the extension types in the group context, plus the extension types each member installation advertises.
This reports raw capability facts rather than answers — callers filter
it to whatever question they care about. For the proposal
(app-data-dictionary) migration specifically, a caller checks for
MlsExtensionType::AppDataDictionary in context_extensions (already
migrated?) and in each installation’s supported_extensions (eligible /
who is blocking?).
Every installation’s capabilities — the local one included — come from
its latest published key package, not its in-group leaf node: a leaf
is frozen when the installation joins and is never updated, so it would
understate a client that upgraded afterward (the same reason
Self::all_members_support_proposals falls back to key packages). An
installation whose key package has not been published or fails
verification is reported with capabilities_known == false and an empty
extension list, so callers can distinguish “unknown” from “advertises
nothing”. Transient failures (network, auth, db) surface as an Err
rather than masquerading as unknown capabilities.
Sourcepub fn proposals_enabled(&self, mls_group: &OpenMlsGroup) -> bool
pub fn proposals_enabled(&self, mls_group: &OpenMlsGroup) -> bool
Check if the group has proposals enabled (proposal-by-reference flow).
Delegates to check_proposals_enabled which detects the
standard MLS ExtensionType::AppDataDictionary group-context
extension. A migrated group carries the dict via that extension
type, making it both the wire-format carrier AND the signal
that the proposal flow is in effect.
When proposals are enabled on a group:
- Add/remove member operations MUST use proposals
- All members being added MUST advertise
AppDataDictionarysupport in their key-package capabilities - Direct commits for membership changes are not allowed
Sourcepub fn is_proposals_enabled(&self) -> Result<bool, GroupError>
pub fn is_proposals_enabled(&self) -> Result<bool, GroupError>
Like Self::proposals_enabled, but loads the group from storage
instead of taking a caller-held OpenMlsGroup. The convenience
shape bindings need for a plain “is this group migrated?” read.
Sourcepub async fn enable_proposals(
&self,
options: EnableProposalsOptions,
) -> Result<(), GroupError>
pub async fn enable_proposals( &self, options: EnableProposalsOptions, ) -> Result<(), GroupError>
Enable proposals on this group (proposal-by-reference flow).
Runs the bootstrap commit that migrates the group’s state out
of legacy GMM-style extensions and into the standard MLS
AppDataDictionary extension. After bootstrap completes the
dictionary is the sole source of truth for the metadata
attributes that previously lived in the legacy extensions.
Once enabled:
- All add/remove member operations will use proposals
- All members being added must advertise
AppDataDictionarysupport in their key-package capabilities - This cannot be disabled once set
§Options
See EnableProposalsOptions for the two knobs:
force: skip the pre-flight key-package capability check. Use when the version floor guarantees proposal support.min_version: override theMIN_SUPPORTED_PROTOCOL_VERSIONfloor written into the migrated group. Defaults toxmtp_configuration::PROPOSALS_MIN_PROTOCOL_VERSION— the release where proposals support first ships.
§Prerequisites
Before calling this method with force = false, ensure all
existing members support proposals by calling
all_members_support_proposals().
§Errors
Returns an error if:
force = falseand not all existing members support proposalsmin_versionis set to an invalid semver stringmin_versionis outside the allowed bounds: above the caller’s ownpkg_version, or — in non-test builds — belowxmtp_configuration::PROPOSALS_MIN_PROTOCOL_VERSION- The group context extension update fails
Sourcepub fn validate_key_packages_support_proposals(
&self,
key_packages: &[KeyPackage],
) -> Result<(), GroupError>
pub fn validate_key_packages_support_proposals( &self, key_packages: &[KeyPackage], ) -> Result<(), GroupError>
Validate that key packages support the AppData dictionary
group-context extension. A leaf that advertises
ExtensionType::AppDataDictionary in its standard MLS
Capabilities can join a migrated group and receive standalone
AppDataUpdate proposals.
Source§impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
Sourcepub async fn add_members_by_identity(
&self,
account_identifiers: &[Identifier],
) -> Result<UpdateGroupMembershipResult, GroupError>
pub async fn add_members_by_identity( &self, account_identifiers: &[Identifier], ) -> Result<UpdateGroupMembershipResult, GroupError>
Add members to the group by account address
If any existing members have new installations that have not been added or removed, the group membership will be updated to include those changes as well.
§Returns
Ok(UpdateGroupMembershipResult): Contains details about the membership changes, including:added_members: list of added installationsremoved_members: A list of installations that were removed.members_with_errors: A list of members that encountered errors during the update.
Err(GroupError): If the operation fails due to an error.
pub async fn add_members<S: AsIdRef>( &self, inbox_ids: impl AsRef<[S]>, ) -> Result<UpdateGroupMembershipResult, GroupError>
Sourcepub async fn remove_members_by_identity(
&self,
account_addresses_to_remove: &[Identifier],
) -> Result<(), GroupError>
pub async fn remove_members_by_identity( &self, account_addresses_to_remove: &[Identifier], ) -> Result<(), GroupError>
Sourcepub async fn remove_members(
&self,
inbox_ids: &[InboxIdRef<'_>],
) -> Result<(), GroupError>
pub async fn remove_members( &self, inbox_ids: &[InboxIdRef<'_>], ) -> Result<(), GroupError>
Sourcepub async fn remove_members_pending_removal(&self) -> Result<(), GroupError>
pub async fn remove_members_pending_removal(&self) -> Result<(), GroupError>
Removes all members from the group who are currently in the pending removal list.
Only admins and super admins can call this function. Validates permissions, filters out invalid removal requests and performs batch removal of valid pending members.
§Returns
Ok(())- All valid pending members were successfully removedErr(GroupError)- Failed to retrieve metadata, validate permissions or execute removals
Sourcepub async fn cleanup_pending_removal_list(&self) -> Result<(), GroupError>
pub async fn cleanup_pending_removal_list(&self) -> Result<(), GroupError>
Removes members from the pending removal list who are no longer in the group.
Iterates through all members in the pending removal list, checking each one to see if they’re still in the group. If a member is no longer in the group, they are removed from the pending list. The pending list is refreshed after each removal to ensure we’re working with the most current data.
§Returns
Ok(())- Successfully processed all pending removal membersErr(GroupError)- Failed to retrieve data or update the pending list
pub async fn leave_group(&self) -> Result<(), GroupError>
Source§impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
Sourcepub async fn send_message(
&self,
message: &[u8],
opts: SendMessageOpts,
) -> Result<Vec<u8>, GroupError>
pub async fn send_message( &self, message: &[u8], opts: SendMessageOpts, ) -> Result<Vec<u8>, GroupError>
Send a message on this users XMTP Client.
Sourcepub async fn publish_messages(&self) -> Result<(), GroupError>
pub async fn publish_messages(&self) -> Result<(), GroupError>
Publish all unpublished messages. This happens by calling sync_until_last_intent_resolved
which publishes all pending intents and reads them back from the network.
Sourcepub async fn update_installations(&self) -> Result<(), GroupError>
pub async fn update_installations(&self) -> Result<(), GroupError>
Checks the network to see if any group members have identity updates that would cause installations to be added or removed from the group.
If so, adds/removes those group members
Sourcepub fn send_message_optimistic(
&self,
message: &[u8],
opts: SendMessageOpts,
) -> Result<Vec<u8>, GroupError>
pub fn send_message_optimistic( &self, message: &[u8], opts: SendMessageOpts, ) -> Result<Vec<u8>, GroupError>
Send a message, optimistically returning the ID of the message before the result of a message publish.
Sourcepub fn prepare_message_for_later_publish(
&self,
message: &[u8],
should_push: bool,
idempotency_key: Option<String>,
) -> Result<Vec<u8>, GroupError>
pub fn prepare_message_for_later_publish( &self, message: &[u8], should_push: bool, idempotency_key: Option<String>, ) -> Result<Vec<u8>, GroupError>
Prepare a message for later publishing.
Stores the message locally with Unpublished delivery status but does NOT
create an intent to publish. Use publish_stored_message to publish later.
§Arguments
message- The message content bytesshould_push- Whether to send a push notification when publishingidempotency_key- Optional caller-supplied key the message id is derived from. Defaults to a random key whenNone.
Returns the message ID.
Sourcepub async fn publish_stored_message(
&self,
message_id: &[u8],
) -> Result<(), GroupError>
pub async fn publish_stored_message( &self, message_id: &[u8], ) -> Result<(), GroupError>
Publish a previously stored message by ID.
Creates an intent for the message and publishes it to the network.
Uses the should_push value that was stored with the message.
This is a no-op if the message is already published.
Returns an error if the message is not found.
Sourcepub fn delete_message(&self, message_id: Vec<u8>) -> Result<Vec<u8>, GroupError>
pub fn delete_message(&self, message_id: Vec<u8>) -> Result<Vec<u8>, GroupError>
Delete a message by its ID. Returns the ID of the deletion message.
Only the original sender or a super admin can delete a message.
§Wire Protocol
The DeleteMessage protobuf encodes message_id as a hex-encoded string for wire
transmission, while the database stores message IDs as raw bytes. This function handles
the conversion: it accepts raw bytes, hex-encodes them for the wire protocol, and when
processing incoming deletions (in process_delete_message), the hex string is decoded
back to bytes for database lookups.
§Arguments
message_id- The message ID as bytes
§Returns
The ID of the deletion message
Sourcepub fn find_messages(
&self,
args: &MsgQueryArgs,
) -> Result<Vec<StoredGroupMessage>, GroupError>
pub fn find_messages( &self, args: &MsgQueryArgs, ) -> Result<Vec<StoredGroupMessage>, GroupError>
Query the database for stored messages. Optionally filtered by time, kind, delivery_status and limit
Sourcepub fn count_messages(&self, args: &MsgQueryArgs) -> Result<i64, GroupError>
pub fn count_messages(&self, args: &MsgQueryArgs) -> Result<i64, GroupError>
Count the number of stored messages matching the given criteria
Sourcepub fn find_messages_with_reactions(
&self,
args: &MsgQueryArgs,
) -> Result<Vec<StoredGroupMessageWithReactions>, GroupError>
pub fn find_messages_with_reactions( &self, args: &MsgQueryArgs, ) -> Result<Vec<StoredGroupMessageWithReactions>, GroupError>
Query the database for stored messages. Optionally filtered by time, kind, delivery_status and limit
Sourcepub fn find_enriched_messages(
&self,
args: &MsgQueryArgs,
) -> Result<Vec<DecodedMessage>, EnrichMessageError>
pub fn find_enriched_messages( &self, args: &MsgQueryArgs, ) -> Result<Vec<DecodedMessage>, EnrichMessageError>
Query for enriched messages (with reactions, replies, and deletion status)
pub fn get_last_read_times( &self, ) -> Result<LatestMessageTimeBySender, GroupError>
Sourcepub fn load(&self) -> Result<StoredGroup, StorageError>
pub fn load(&self) -> Result<StoredGroup, StorageError>
Load the group reference stored in the local database
Source§impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
Sourcepub async fn update_group_name(
&self,
group_name: String,
) -> Result<(), GroupError>
pub async fn update_group_name( &self, group_name: String, ) -> Result<(), GroupError>
Updates the name of the group. Will error if the user does not have the appropriate permissions to perform these updates.
Sourcepub async fn update_app_data(
&self,
app_data: String,
expected_app_data: Option<String>,
) -> Result<(), GroupError>
pub async fn update_app_data( &self, app_data: String, expected_app_data: Option<String>, ) -> Result<(), GroupError>
Set the group’s opaque app_data slot.
expected_app_data is an optional compare-and-swap guard. When
Some, the update is abandoned with GroupError::AppDataSuperseded
unless the committed value still equals it — including when another
member’s commit wins the epoch race after this intent was published.
Callers reconciling structured state should pass the value they merged
against, so a concurrent write is reported rather than overwritten.
None keeps the historical last-writer-wins behavior: whatever landed
in the meantime is overwritten.
Sourcepub async fn update_group_min_version(
&self,
version: &str,
) -> Result<(), GroupError>
pub async fn update_group_min_version( &self, version: &str, ) -> Result<(), GroupError>
Updates min version of the group to match the given version.
§Arguments
version- The libxmtp version to update the group min version to. This is a semver-formatted string matching the Cargo.toml in the libxmtp dependency, and does not match mobile or web release versions. Comparison is done via thesemvercrate’sOrdimpl, so pre-release identifiers (e.g."1.0.0-rc.1") sort BEFORE the corresponding release ("1.0.0") per semver 2.0 §11. Build metadata (+...) parses but is included in ordering by the semver crate — avoid passing it unless you understand the total-ordering implication.
§Returns
A Result indicating success or failure of the operation.
Sourcepub async fn update_commit_log_signer(
&self,
commit_log_signer: Secret,
) -> Result<(), GroupError>
pub async fn update_commit_log_signer( &self, commit_log_signer: Secret, ) -> Result<(), GroupError>
Updates the commit log signer of the group. Will error if the user does not have the appropriate permissions to perform these updates.
Sourcepub async fn update_permission_policy(
&self,
permission_update_type: PermissionUpdateType,
permission_policy: PermissionPolicyOption,
metadata_field: Option<MetadataField>,
) -> Result<(), GroupError>
pub async fn update_permission_policy( &self, permission_update_type: PermissionUpdateType, permission_policy: PermissionPolicyOption, metadata_field: Option<MetadataField>, ) -> Result<(), GroupError>
Updates the permission policy of the group. This requires super admin permissions.
Sourcepub fn group_name(&self) -> Result<String, GroupError>
pub fn group_name(&self) -> Result<String, GroupError>
Retrieves the group name from the group’s mutable metadata extension.
Sourcepub fn app_data(&self) -> Result<String, GroupError>
pub fn app_data(&self) -> Result<String, GroupError>
Retrieves the app_data field from the group’s mutable metadata extension
Sourcepub async fn update_group_description(
&self,
group_description: String,
) -> Result<(), GroupError>
pub async fn update_group_description( &self, group_description: String, ) -> Result<(), GroupError>
Updates the description of the group.
pub fn group_description(&self) -> Result<String, GroupError>
Sourcepub async fn update_group_image_url_square(
&self,
group_image_url_square: String,
) -> Result<(), GroupError>
pub async fn update_group_image_url_square( &self, group_image_url_square: String, ) -> Result<(), GroupError>
Updates the image URL (square) of the group.
Sourcepub fn group_image_url_square(&self) -> Result<String, GroupError>
pub fn group_image_url_square(&self) -> Result<String, GroupError>
Retrieves the image URL (square) of the group from the group’s mutable metadata extension.
pub async fn update_conversation_message_disappearing_settings( &self, settings: MessageDisappearingSettings, ) -> Result<(), GroupError>
pub async fn remove_conversation_message_disappearing_settings( &self, ) -> Result<(), GroupError>
Sourcepub fn paused_for_version(&self) -> Result<Option<String>, GroupError>
pub fn paused_for_version(&self) -> Result<Option<String>, GroupError>
If group is not paused, will return None, otherwise will return the version that the group is paused for
pub fn conversation_message_disappearing_settings( &self, ) -> Result<MessageDisappearingSettings, GroupError>
pub fn conversation_message_disappearing_settings_from_extensions( mutable_metadata: &GroupMutableMetadata, ) -> Result<MessageDisappearingSettings, GroupError>
pub fn pending_remove_list(&self) -> Result<Vec<String>, GroupError>
Sourcepub fn is_in_pending_remove(&self, inbox_id: &str) -> Result<bool, GroupError>
pub fn is_in_pending_remove(&self, inbox_id: &str) -> Result<bool, GroupError>
Checks if the given inbox ID is the pending-remove list of the group at the most recently synced epoch.
Sourcepub fn admin_list(&self) -> Result<Vec<String>, GroupError>
pub fn admin_list(&self) -> Result<Vec<String>, GroupError>
Retrieves the admin list of the group from the group’s mutable metadata extension.
Element order: on migrated groups the dict-backed TlsSet<InboxId>
is iterated in sorted-by-raw-bytes order. On unmigrated groups
the legacy GroupMutableMetadata.admin_list is returned in its
stored (insertion) order. Both contracts pre-date this refactor;
preserving each side avoids surprising binding consumers that
rely on the pre-migration order.
Sourcepub fn super_admin_list(&self) -> Result<Vec<String>, GroupError>
pub fn super_admin_list(&self) -> Result<Vec<String>, GroupError>
Retrieves the super admin list of the group from the group’s mutable metadata extension.
Same ordering contract as Self::admin_list.
Sourcepub fn is_admin(&self, inbox_id: String) -> Result<bool, GroupError>
pub fn is_admin(&self, inbox_id: String) -> Result<bool, GroupError>
Checks if the given inbox ID is an admin of the group at the most recently synced epoch.
Sourcepub fn is_super_admin(&self, inbox_id: String) -> Result<bool, GroupError>
pub fn is_super_admin(&self, inbox_id: String) -> Result<bool, GroupError>
Checks if the given inbox ID is a super admin of the group at the most recently synced epoch.
Sourcepub fn is_super_admin_without_lock(
&self,
mls_group: &OpenMlsGroup,
inbox_id: String,
) -> Result<bool, GroupMutableMetadataError>
pub fn is_super_admin_without_lock( &self, mls_group: &OpenMlsGroup, inbox_id: String, ) -> Result<bool, GroupMutableMetadataError>
Checks if the given inbox ID is a super admin of the group at the most recently synced epoch
Sourcepub async fn conversation_type(&self) -> Result<ConversationType, GroupError>
pub async fn conversation_type(&self) -> Result<ConversationType, GroupError>
Retrieves the conversation type of the group from the group’s metadata extension.
Source§impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
Sourcepub async fn update_admin_list(
&self,
action_type: UpdateAdminListType,
inbox_id: String,
) -> Result<(), GroupError>
pub async fn update_admin_list( &self, action_type: UpdateAdminListType, inbox_id: String, ) -> Result<(), GroupError>
Updates the admin list of the group and syncs the changes to the network.
Sourcepub fn added_by_inbox_id(&self) -> Result<String, GroupError>
pub fn added_by_inbox_id(&self) -> Result<String, GroupError>
Find the inbox_id of the group member who added the member to the group
Sourcepub fn consent_state(&self) -> Result<ConsentState, GroupError>
pub fn consent_state(&self) -> Result<ConsentState, GroupError>
Find the consent_state of the group
pub fn quietly_update_consent_state( &self, state: ConsentState, db: &impl DbQuery, ) -> Result<Vec<StoredConsentRecord>, GroupError>
pub fn update_consent_state( &self, state: ConsentState, ) -> Result<(), GroupError>
Sourcepub async fn epoch(&self) -> Result<u64, GroupError>
pub async fn epoch(&self) -> Result<u64, GroupError>
Get the current epoch number of the group.
pub async fn cursor(&self) -> Result<Cursor, GroupError>
pub async fn local_commit_log(&self) -> Result<Vec<LocalCommitLog>, GroupError>
pub async fn remote_commit_log( &self, ) -> Result<Vec<RemoteCommitLog>, GroupError>
pub async fn debug_info(&self) -> Result<ConversationDebugInfo, GroupError>
Sourcepub async fn key_update(&self) -> Result<(), GroupError>
pub async fn key_update(&self) -> Result<(), GroupError>
Update this installation’s leaf key in the group by creating a key update commit
Sourcepub fn is_active(&self) -> Result<bool, GroupError>
pub fn is_active(&self) -> Result<bool, GroupError>
Checks if the current user is active in the group.
If the current user has been kicked out of the group, is_active will return false
Sourcepub fn membership_state(&self) -> Result<GroupMembershipState, GroupError>
pub fn membership_state(&self) -> Result<GroupMembershipState, GroupError>
Returns the membership state of the current user in this group.
Sourcepub async fn metadata(&self) -> Result<GroupMetadata, GroupError>
pub async fn metadata(&self) -> Result<GroupMetadata, GroupError>
Get the GroupMetadata of the group.
On migrated groups the legacy immutable-metadata extension has been removed; synthesize from dict (CONVERSATION_TYPE, CREATOR_INBOX_ID, DM_MEMBERS, ONESHOT_MESSAGE). On unmigrated groups, the legacy extension is authoritative.
Migrated-but-no-seeds is treated as a hard error rather than
falling through to the legacy extension — the bootstrap commit
strips the legacy GroupContextExtension, so falling through
would surface an unrelated MissingExtension from the legacy
path. Returning MissingExtension directly here keeps the
failure shape callers already handle while making the
“incomplete migration” condition explicit at the originating
site.
Sourcepub fn mutable_metadata(&self) -> Result<GroupMutableMetadata, GroupError>
pub fn mutable_metadata(&self) -> Result<GroupMutableMetadata, GroupError>
Get the GroupMutableMetadata of the group.
Post-migration (dict contains COMPONENT_REGISTRY — see
[self::app_data::is_migrated_group]) the legacy GMM extension
is gone; we start with an empty base and
merge_app_data_into_mutable_metadata populates every field
from the AppData dict. Pre-migration we read the legacy GMM
extension authoritatively. The overlay helper itself also
checks the migration marker (defense in depth), so a stray
dict entry on a pre-bootstrap group can’t silently shadow
legacy values.
Intentionally distinct from proposals_enabled: a group can
have proposals_enabled == true but not yet have completed
its bootstrap commit, during which window the legacy GMM is
still authoritative.
pub fn permissions(&self) -> Result<GroupMutablePermissions, GroupError>
Sourcepub fn disappearing_settings(
&self,
) -> Result<Option<MessageDisappearingSettings>, GroupError>
pub fn disappearing_settings( &self, ) -> Result<Option<MessageDisappearingSettings>, GroupError>
Fetches the message disappearing settings for a given group ID.
Returns Some(MessageDisappearingSettings) if the group exists and has valid settings,
None if the group or settings are missing, or Err(ClientError) on a database error.
Sourcepub fn find_duplicate_dms(&self) -> Result<Vec<MlsGroup<Context>>, ClientError>
pub fn find_duplicate_dms(&self) -> Result<Vec<MlsGroup<Context>>, ClientError>
Find all the duplicate dms for this group
Source§impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
Sourcepub async fn members(&self) -> Result<Vec<GroupMember>, GroupError>
pub async fn members(&self) -> Result<Vec<GroupMember>, GroupError>
Load the member list for the group from the DB, merging together multiple installations into a single entry
Source§impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
pub fn find_messages_v2( &self, query: &MsgQueryArgs, ) -> Result<Vec<DecodedMessage>, EnrichMessageError>
pub fn find_messages_v2_with_conn<C>(
&self,
query: &MsgQueryArgs,
conn: C,
) -> Result<Vec<DecodedMessage>, EnrichMessageError>where
C: QueryGroupMessage + DbQuery,
Source§impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
pub async fn maybe_update_installations( &self, update_interval_ns: Option<i64>, ) -> Result<(), GroupError>
Sourcepub fn hmac_keys(
&self,
epoch_delta_range: RangeInclusive<i64>,
) -> Result<Vec<HmacKey>, StorageError>
pub fn hmac_keys( &self, epoch_delta_range: RangeInclusive<i64>, ) -> Result<Vec<HmacKey>, StorageError>
Provides hmac keys for a range of epochs around current epoch
group.hmac_keys(-1..=1)`` will provide 3 keys consisting of last epoch, current epoch, and next epoch group.hmac_keys(0..=0) will provide 1 key, consisting of only the current epoch
Source§impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
Sourcepub async fn receive(&self) -> Result<ProcessSummary, GroupError>
pub async fn receive(&self) -> Result<ProcessSummary, GroupError>
Wait for a fixed network prefix. The summary is local history, not proof of completion.
Source§impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext,
pub async fn sync(&self) -> Result<SyncSummary, GroupError>
Sourcepub async fn sync_with_conn(&self) -> Result<SyncSummary, SyncSummary>
pub async fn sync_with_conn(&self) -> Result<SyncSummary, SyncSummary>
Sync from the network with the ‘conn’ (local database). must return a summary of all messages synced, whether they were successful or not.
Source§impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext + 'static,
impl<Context> MlsGroup<Context>where
Context: XmtpSharedContext + 'static,
Sourcepub async fn process_streamed_group_message(
&self,
envelope_bytes: Vec<u8>,
) -> Result<Vec<StoredGroupMessage>, SubscribeError>
pub async fn process_streamed_group_message( &self, envelope_bytes: Vec<u8>, ) -> Result<Vec<StoredGroupMessage>, SubscribeError>
Use a push envelope only as a target for ordered receipt and processing.
pub async fn stream<'a>(
&'a self,
) -> Result<impl Stream<Item = Result<StoredGroupMessage, SubscribeError>> + use<'a, Context>, SubscribeError>where
Context::ApiClient: XmtpMlsStreams + 'a,
Sourcepub async fn stream_owned(
&self,
) -> Result<impl Stream<Item = Result<StoredGroupMessage, SubscribeError>> + 'static, SubscribeError>
pub async fn stream_owned( &self, ) -> Result<impl Stream<Item = Result<StoredGroupMessage, SubscribeError>> + 'static, SubscribeError>
create a stream that is not attached to any lifetime
pub fn stream_with_callback(
context: Context,
group_id: GroupId,
callback: impl FnMut(Result<StoredGroupMessage, SubscribeError>) + MaybeSend + 'static,
on_close: impl FnOnce() + MaybeSend + 'static,
) -> impl StreamHandle<StreamOutput = Result<(), SubscribeError>>where
Context: 'static,
Context::ApiClient: XmtpMlsStreams + 'static,
Trait Implementations§
Source§impl<Context: XmtpSharedContext> Clone for MlsGroup<Context>
impl<Context: XmtpSharedContext> Clone for MlsGroup<Context>
Source§impl<Context> Debug for MlsGroup<Context>where
Context: XmtpSharedContext,
impl<Context> Debug for MlsGroup<Context>where
Context: XmtpSharedContext,
impl<C> Eq for MlsGroup<C>
Auto Trait Implementations§
impl<Context> Freeze for MlsGroup<Context>where
Context: Freeze,
impl<Context> !RefUnwindSafe for MlsGroup<Context>
impl<Context> Send for MlsGroup<Context>where
Context: Send,
impl<Context> Sync for MlsGroup<Context>where
Context: Sync,
impl<Context> Unpin for MlsGroup<Context>where
Context: Unpin,
impl<Context> UnsafeUnpin for MlsGroup<Context>where
Context: UnsafeUnpin,
impl<Context> !UnwindSafe for MlsGroup<Context>
Blanket Implementations§
§impl<T> AggregateExpressionMethods for T
impl<T> AggregateExpressionMethods for T
§fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
DISTINCT modifier for aggregate functions Read more§fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
ALL modifier for aggregate functions Read more§fn aggregate_filter<P>(self, f: P) -> Self::Outputwhere
P: AsExpression<Bool>,
Self: FilterDsl<<P as AsExpression<Bool>>::Expression>,
fn aggregate_filter<P>(self, f: P) -> Self::Outputwhere
P: AsExpression<Bool>,
Self: FilterDsl<<P as AsExpression<Bool>>::Expression>,
§fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> 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§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<T> IntoSql for T
impl<T> IntoSql for T
§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].§impl<D> OwoColorize for D
impl<D> OwoColorize for D
§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg] or
a color-specific method, such as [OwoColorize::green], Read more§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg] or
a color-specific method, such as [OwoColorize::on_yellow], Read more