Documentation Index
Fetch the complete documentation index at: https://mintlify.com/xmtp/libxmtp/llms.txt
Use this file to discover all available pages before exploring further.
Overview
LibXMTP groups support two types of metadata:
- GroupMetadata - Immutable metadata set at group creation
- GroupMutableMetadata - Mutable metadata that can be updated based on permissions
Both are stored as MLS Unknown Group Context Extensions.
Options for configuring group metadata at creation time.
pub struct GroupMetadataOptions {
pub name: Option<String>,
pub image_url_square: Option<String>,
pub description: Option<String>,
pub message_disappearing_settings: Option<MessageDisappearingSettings>,
pub app_data: Option<String>,
}
Fields
| Field | Type | Description | Max Length |
|---|
name | Option<String> | Group display name | 100 chars |
image_url_square | Option<String> | URL for group image | 2048 chars |
description | Option<String> | Group description | 1000 chars |
message_disappearing_settings | Option<MessageDisappearingSettings> | Disappearing message configuration | N/A |
app_data | Option<String> | Application-specific data | 8192 chars |
Defaults
If not specified, fields use these defaults (from xmtp_configuration):
name: DEFAULT_GROUP_NAME
description: DEFAULT_GROUP_DESCRIPTION
image_url_square: DEFAULT_GROUP_IMAGE_URL_SQUARE
app_data: Empty string
Implementation
impl Default for GroupMetadataOptions {
fn default() -> Self {
Self {
name: None,
image_url_square: None,
description: None,
message_disappearing_settings: None,
app_data: None,
}
}
}
Options for configuring DM (direct message) metadata.
pub struct DMMetadataOptions {
pub message_disappearing_settings: Option<MessageDisappearingSettings>,
}
Note: DMs have fewer configurable options since name/description are derived from participants.
Immutable metadata created at group creation time.
pub struct GroupMetadata {
pub conversation_type: ConversationType,
pub creator_inbox_id: String,
pub dm_members: Option<DmMembers<InboxId>>,
pub oneshot_message: Option<OneshotMessage>,
}
Fields
| Field | Type | Description |
|---|
conversation_type | ConversationType | Type of conversation (Group, DM, etc.) |
creator_inbox_id | String | Inbox ID of the group creator |
dm_members | Option<DmMembers<InboxId>> | DM member information (DMs only) |
oneshot_message | Option<OneshotMessage> | Optional oneshot message |
Methods
new
pub fn new(
conversation_type: ConversationType,
creator_inbox_id: String,
dm_members: Option<DmMembers<InboxId>>,
oneshot_message: Option<OneshotMessage>,
) -> Self
Conversions
impl TryFrom<GroupMetadata> for Vec<u8>
impl TryFrom<&Vec<u8>> for GroupMetadata
impl TryFrom<GroupMetadataProto> for GroupMetadata
impl TryFrom<&Extensions> for GroupMetadata
Helper Function
pub fn extract_group_metadata(
extensions: &Extensions,
) -> Result<GroupMetadata, GroupMetadataError>
Extracts immutable metadata from MLS extensions.
Mutable metadata that can be updated according to permission policies.
pub struct GroupMutableMetadata {
pub attributes: HashMap<String, String>,
pub admin_list: Vec<String>,
pub super_admin_list: Vec<String>,
}
Fields
| Field | Type | Description |
|---|
attributes | HashMap<String, String> | Key-value metadata attributes |
admin_list | Vec<String> | List of admin inbox IDs |
super_admin_list | Vec<String> | List of super admin inbox IDs |
Methods
new
pub fn new(
attributes: HashMap<String, String>,
admin_list: Vec<String>,
super_admin_list: Vec<String>,
) -> Self
new_default
pub fn new_default(
creator_inbox_id: String,
commit_log_signer: Option<Secret>,
opts: GroupMetadataOptions,
) -> Self
Creates default mutable metadata for a new group.
Behavior:
- Creator is added as super admin
- Attributes populated from
opts
- Commit log signer stored if provided
new_dm_default
pub fn new_dm_default(
_creator_inbox_id: String,
_dm_target_inbox_id: &str,
commit_log_signer: Option<Secret>,
opts: DMMetadataOptions,
) -> Self
Creates default mutable metadata for a DM.
Behavior:
- No admins or super admins (not needed for DMs)
- Minimal attributes
supported_fields
pub fn supported_fields() -> Vec<MetadataField>
Returns metadata fields that receive default permission policies.
Supported Fields:
GroupName
Description
GroupImageUrlSquare
MessageDisappearFromNS
MessageDisappearInNS
MinimumSupportedProtocolVersion
AppData
is_admin
pub fn is_admin(&self, inbox_id: &String) -> bool
Checks if an inbox ID is an admin.
is_super_admin
pub fn is_super_admin(&self, inbox_id: &String) -> bool
Checks if an inbox ID is a super admin.
commit_log_signer
pub fn commit_log_signer(&self) -> Option<Secret>
Retrieves the commit log signer secret from attributes.
Returns: None if field is not present or hex decoding fails.
Conversions
impl TryFrom<GroupMutableMetadata> for Vec<u8>
impl TryFrom<&Vec<u8>> for GroupMutableMetadata
impl TryFrom<GroupMutableMetadataProto> for GroupMutableMetadata
impl TryFrom<&Extensions> for GroupMutableMetadata
impl TryFrom<&OpenMlsGroup> for GroupMutableMetadata
Helper Functions
pub fn find_mutable_metadata_extension(
extensions: &Extensions,
) -> Option<&Vec<u8>>
Searches for the mutable metadata extension in MLS Extensions.
pub fn extract_group_mutable_metadata(
group: &OpenMlsGroup,
) -> Result<GroupMutableMetadata, GroupMutableMetadataError>
Extracts mutable metadata from an OpenMLS group.
Enum representing supported metadata fields.
pub enum MetadataField {
GroupName,
Description,
GroupImageUrlSquare,
MessageDisappearFromNS,
MessageDisappearInNS,
MinimumSupportedProtocolVersion,
CommitLogSigner,
AppData,
}
Methods
as_str
pub const fn as_str(&self) -> &'static str
Returns the string representation used as a key in the attributes map.
Mappings:
GroupName → "group_name"
Description → "description"
GroupImageUrlSquare → "group_image_url_square"
MessageDisappearFromNS → "message_disappear_from_ns"
MessageDisappearInNS → "message_disappear_in_ns"
MinimumSupportedProtocolVersion → "minimum_supported_protocol_version"
CommitLogSigner → "_commit_log_signer" (super admin prefix)
AppData → "app_data"
Note: CommitLogSigner uses the _ prefix to make it super-admin-only.
Display Implementation
impl fmt::Display for MetadataField {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
MessageDisappearingSettings
Configuration for disappearing messages.
pub struct MessageDisappearingSettings {
pub from_ns: i64,
pub in_ns: i64,
}
Fields
| Field | Type | Description |
|---|
from_ns | i64 | Timestamp (nanoseconds) from when messages should be tracked for deletion |
in_ns | i64 | Duration (nanoseconds) after which tracked messages will be deleted |
Methods
new
pub fn new(from_ns: i64, in_ns: i64) -> Self
is_enabled
pub fn is_enabled(&self) -> bool
Returns true if both from_ns and in_ns are greater than 0.
Default Implementation
impl Default for MessageDisappearingSettings {
fn default() -> Self {
Self { from_ns: 0, in_ns: 0 }
}
}
DmMembers
Represents the two members of a DM conversation.
pub struct DmMembers<Id: AsRef<str>> {
pub member_one_inbox_id: Id,
pub member_two_inbox_id: Id,
}
Methods
as_ref
impl DmMembers<String> {
pub fn as_ref(&'a self) -> DmMembers<&'a str>
}
Display Implementation
impl<Id: AsRef<str>> Display for DmMembers<Id> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// Formats as "dm:{sorted_inbox_id_1}:{sorted_inbox_id_2}"
// IDs are lowercased and sorted for consistent ordering
}
}
Example: DmMembers { member_one_inbox_id: "Alice", member_two_inbox_id: "Bob" } becomes "dm:alice:bob"
Conversions
impl<Id: AsRef<str>> From<DmMembers<Id>> for DmMembersProto
impl<Id: AsRef<str>> From<DmMembers<Id>> for String
impl TryFrom<DmMembersProto> for DmMembers<InboxId>
Error Handling
pub enum GroupMetadataError {
Serialization(prost::EncodeError),
Deserialization(prost::DecodeError),
InvalidConversationType,
MissingExtension,
InvalidDmMembers,
MissingDmMember,
Conversion(xmtp_proto::ConversionError),
}
pub enum GroupMutableMetadataError {
Serialization(prost::EncodeError),
Deserialization(prost::DecodeError),
MissingExtension,
NonMutableExtensionUpdate,
TooManyUpdates,
NoUpdates,
MissingMetadataField,
}
Usage Examples
use xmtp_mls_common::group::GroupMetadataOptions;
use xmtp_mls_common::group_mutable_metadata::MessageDisappearingSettings;
let opts = GroupMetadataOptions {
name: Some("My Awesome Group".to_string()),
description: Some("A group for awesome people".to_string()),
image_url_square: Some("https://example.com/image.png".to_string()),
message_disappearing_settings: Some(MessageDisappearingSettings::new(
1_000_000_000, // from_ns: start time
86_400_000_000_000, // in_ns: 24 hours
)),
app_data: Some(r#"{"custom":"data"}"#.to_string()),
};
let group = MlsGroup::create_and_insert(
context,
ConversationType::Group,
PolicySet::default(),
opts,
None,
)?;
use xmtp_mls_common::group_metadata::extract_group_metadata;
use xmtp_mls_common::group_mutable_metadata::extract_group_mutable_metadata;
// Extract immutable metadata
let metadata = extract_group_metadata(mls_group.extensions())?;
println!("Creator: {}", metadata.creator_inbox_id);
// Extract mutable metadata
let mutable = extract_group_mutable_metadata(&mls_group)?;
if let Some(name) = mutable.attributes.get("group_name") {
println!("Group name: {}", name);
}
Checking Admin Status
let mutable = extract_group_mutable_metadata(&mls_group)?;
let my_inbox_id = context.inbox_id().to_string();
if mutable.is_super_admin(&my_inbox_id) {
println!("I'm a super admin!");
} else if mutable.is_admin(&my_inbox_id) {
println!("I'm a regular admin");
} else {
println!("I'm a regular member");
}
Constants
Defined in crates/xmtp_mls/src/groups/mod.rs:
const MAX_GROUP_DESCRIPTION_LENGTH: usize = 1000;
const MAX_GROUP_NAME_LENGTH: usize = 100;
const MAX_GROUP_IMAGE_URL_LENGTH: usize = 2048;
const MAX_APP_DATA_LENGTH: usize = 8192;
Source References
- GroupMetadataOptions:
crates/xmtp_mls_common/src/group.rs:3
- DMMetadataOptions:
crates/xmtp_mls_common/src/group.rs:12
- GroupMetadata:
crates/xmtp_mls_common/src/group_metadata.rs:36
- GroupMutableMetadata:
crates/xmtp_mls_common/src/group_mutable_metadata.rs:99
- MetadataField:
crates/xmtp_mls_common/src/group_mutable_metadata.rs:42
- MessageDisappearingSettings:
crates/xmtp_mls_common/src/group_mutable_metadata.rs:83
- DmMembers:
crates/xmtp_mls_common/src/group_metadata.rs:115