Skip to main content
Complete method reference for the Client struct.

Identity Methods

inbox_id()

Get the client’s inbox ID. Returns: InboxIdRef<'_> - Reference to the inbox ID string Source: crates/xmtp_mls/src/client.rs:280
let inbox_id = client.inbox_id();
println!("Inbox ID: {}", inbox_id);

installation_public_key()

Get the client’s installation public key (also called installation_id). Returns: InstallationId - Public key bytes identifying this installation Source: crates/xmtp_mls/src/client.rs:276
let installation_id = client.installation_public_key();

identity()

Get a reference to the client’s identity. Returns: &Identity - Reference to the identity object Source: crates/xmtp_mls/src/client.rs:520
let identity = client.identity();
if identity.is_ready() {
    println!("Identity is registered");
}

register_identity(signature_request)

Register the client’s identity on the network.
signature_request
SignatureRequest
required
Signed request containing identity updates to publish
Returns: Result<(), ClientError> Source: crates/xmtp_mls/src/client.rs:875 Process:
  1. Checks if already registered (crash recovery)
  2. Generates and stores key package locally
  3. Validates signatures without network pollution
  4. Uploads key package to network
  5. Publishes identity update
  6. Fetches and stores identity in local database
  7. Marks identity as ready
let signature_request = /* obtain signed request */;
client.register_identity(signature_request).await?;

inbox_state(refresh_from_network)

Get the association state for the client’s inbox.
refresh_from_network
bool
required
If true, fetch latest state from network. If false, use local database.
Returns: Result<AssociationState, ClientError> Source: crates/xmtp_mls/src/client.rs:369
let state = client.inbox_state(true).await?;
for installation in state.installation_ids() {
    println!("Installation: {}", hex::encode(installation));
}

inbox_addresses(refresh_from_network, inbox_ids)

Get association states for multiple inboxes.
refresh_from_network
bool
required
Whether to fetch from network
inbox_ids
Vec<InboxIdRef<'_>>
required
List of inbox IDs to query
Returns: Result<Vec<AssociationState>, ClientError> Source: crates/xmtp_mls/src/client.rs:387
let inbox_ids = vec!["inbox_1", "inbox_2"];
let states = client.inbox_addresses(true, inbox_ids).await?;

find_inbox_id_from_identifier(conn, identifier)

Look up an inbox ID by blockchain address or other identifier.
conn
&impl DbQuery
required
Database connection
identifier
Identifier
required
Account identifier (address, etc.)
Returns: Result<Option<String>, ClientError> Source: crates/xmtp_mls/src/client.rs:310
let conn = client.db();
let identifier = Identifier::Address("0x...".to_string());
if let Some(inbox_id) = client.find_inbox_id_from_identifier(&conn, identifier).await? {
    println!("Found inbox: {}", inbox_id);
}

inbox_sequence_id(conn)

Get the highest sequence_id from the local database for the client’s inbox.
conn
&DbConnection<Connection>
required
Database connection
Returns: Result<i64, StorageError> Source: crates/xmtp_mls/src/client.rs:359 Note: May not be consistent with network state.
let conn = DbConnection::new(client.db());
let sequence_id = client.inbox_sequence_id(&conn)?;

fetch_inbox_updates_count(refresh_from_network, inbox_ids)

Get total number of inbox updates for specified inboxes.
refresh_from_network
bool
required
Whether to refresh from network first
inbox_ids
Vec<InboxIdRef<'_>>
required
Inbox IDs to check
Returns: Result<HashMap<InboxId, u32>, ClientError> Source: crates/xmtp_mls/src/client.rs:409
let counts = client.fetch_inbox_updates_count(true, vec!["inbox_1"]).await?;

fetch_own_inbox_updates_count(refresh_from_network)

Get total number of inbox updates for the client’s own inbox.
refresh_from_network
bool
required
Whether to refresh from network
Returns: Result<u32, ClientError> Source: crates/xmtp_mls/src/client.rs:426
let count = client.fetch_own_inbox_updates_count(true).await?;
println!("Total updates: {}", count);

inbox_creation_signature_kind(inbox_id, refresh_from_network)

Get the signature type used to create an inbox.
inbox_id
InboxIdRef<'_>
required
Inbox ID to check
refresh_from_network
bool
required
Whether to fetch updates from network first
Returns: Result<Option<SignatureKind>, ClientError>
  • Some(SignatureKind) - The signature kind used
  • None - Inbox doesn’t exist or creation info unavailable
Source: crates/xmtp_mls/src/client.rs:448
if let Some(kind) = client.inbox_creation_signature_kind("inbox_1", true).await? {
    println!("Created with: {:?}", kind);
}

Group Management

create_group(permissions_policy_set, opts)

Create a new group with default or custom settings.
permissions_policy_set
Option<PolicySet>
Custom permissions policy. Uses default if None.
opts
Option<GroupMetadataOptions>
Group metadata options (name, image, etc.)
Returns: Result<MlsGroup<Context>, ClientError> Source: crates/xmtp_mls/src/client.rs:539 Requirements: Must call register_identity() first.
let group = client.create_group(None, None)?;

create_group_with_members(inbox_ids, permissions_policy_set, opts)

Create a group and immediately add members.
inbox_ids
&[impl AsIdRef]
required
Inbox IDs of members to add
permissions_policy_set
Option<PolicySet>
Custom permissions policy
opts
Option<GroupMetadataOptions>
Group metadata options
Returns: Result<MlsGroup<Context>, ClientError> Source: crates/xmtp_mls/src/client.rs:582
let members = vec!["inbox_1", "inbox_2"];
let group = client.create_group_with_members(&members, None, None).await?;

create_group_with_identifiers(account_identifiers, permissions_policy_set, opts)

Create a group and add members by their account identifiers.
account_identifiers
&[Identifier]
required
Account identifiers (addresses, etc.) of members
permissions_policy_set
Option<PolicySet>
Custom permissions policy
opts
Option<GroupMetadataOptions>
Group metadata options
Returns: Result<MlsGroup<Context>, ClientError> Source: crates/xmtp_mls/src/client.rs:569 Note: Looks up inbox IDs for each identifier before adding.
let identifiers = vec![
    Identifier::Address("0x123...".to_string()),
    Identifier::Address("0x456...".to_string()),
];
let group = client.create_group_with_identifiers(&identifiers, None, None).await?;

find_or_create_dm(inbox_id, opts)

Find existing DM or create new one with the specified inbox.
inbox_id
impl AsIdRef
required
Target inbox ID
opts
Option<DMMetadataOptions>
DM metadata options
Returns: Result<MlsGroup<Context>, ClientError> Source: crates/xmtp_mls/src/client.rs:648
let dm = client.find_or_create_dm("target_inbox_id", None).await?;

find_or_create_dm_by_identity(target_identity, opts)

Find or create DM by account identifier.
target_identity
Identifier
required
Account identifier of target
opts
Option<DMMetadataOptions>
DM metadata options
Returns: Result<MlsGroup<Context>, ClientError> Source: crates/xmtp_mls/src/client.rs:627 Note: Returns error if no inbox found for the identifier.
let identifier = Identifier::Address("0x...".to_string());
let dm = client.find_or_create_dm_by_identity(identifier, None).await?;

group(group_id)

Look up a group by its ID.
group_id
&Vec<u8>
required
Group ID bytes
Returns: Result<MlsGroup<Context>, ClientError> Source: crates/xmtp_mls/src/client.rs:678
let group = client.group(&group_id)?;

stitched_group(group_id)

Look up a group by ID while stitching duplicate DMs.
group_id
&[u8]
required
Group ID bytes
Returns: Result<MlsGroup<Context>, ClientError> Source: crates/xmtp_mls/src/client.rs:688 Note: For DMs, may return a different group ID if this DM has been superseded.
let group = client.stitched_group(&group_id)?;

dm_group_from_target_inbox(target_inbox_id)

Look up an active DM by the target’s inbox ID.
target_inbox_id
String
required
Target inbox ID
Returns: Result<MlsGroup<Context>, ClientError> Source: crates/xmtp_mls/src/client.rs:731
let dm = client.dm_group_from_target_inbox("target_inbox".to_string())?;

find_groups(args)

Query for groups with optional filters.
args
GroupQueryArgs
required
Query arguments:
  • allowed_states: Filter by membership states
  • created_after_ns: Filter by creation time
  • created_before_ns: Filter by creation time
  • limit: Maximum number of results
  • consent_states: Filter by consent status
  • conversation_type: Filter by type (DM, Group, etc.)
Returns: Result<Vec<MlsGroup<Context>>, ClientError> Source: crates/xmtp_mls/src/client.rs:809
let args = GroupQueryArgs {
    limit: Some(10),
    conversation_type: Some(ConversationType::Group),
    ..Default::default()
};
let groups = client.find_groups(args)?;

list_conversations(args)

List conversations with last message and metadata.
args
GroupQueryArgs
required
Query arguments (same as find_groups)
Returns: Result<Vec<ConversationListItem<Context>>, ClientError> Source: crates/xmtp_mls/src/client.rs:816 Note: Defaults to ordering by last activity.
let conversations = client.list_conversations(GroupQueryArgs::default())?;
for item in conversations {
    if let Some(msg) = item.last_message {
        println!("Last message: {:?}", msg);
    }
}

find_duplicate_dms_for_group(group_id)

Find all duplicate DMs for a given group.
group_id
&[u8]
required
Group ID to check
Returns: Result<Vec<MlsGroup<Context>>, ClientError> Source: crates/xmtp_mls/src/client.rs:706
let duplicates = client.find_duplicate_dms_for_group(&group_id)?;

group_disappearing_settings(group_id)

Get message disappearing settings for a group.
group_id
&[u8]
required
Group ID
Returns: Result<Option<MessageDisappearingSettings>, ClientError> Source: crates/xmtp_mls/src/client.rs:718
if let Some(settings) = client.group_disappearing_settings(&group_id)? {
    println!("Messages disappear after: {} seconds", settings.duration_seconds);
}

Message Methods

message(message_id)

Look up a message by its ID.
message_id
Vec<u8>
required
Message ID bytes
Returns: Result<StoredGroupMessage, ClientError> Source: crates/xmtp_mls/src/client.rs:754
let message = client.message(message_id)?;

message_v2(message_id)

Look up and enrich a message by ID.
message_id
Vec<u8>
required
Message ID bytes
Returns: Result<DecodedMessage, ClientError> Source: crates/xmtp_mls/src/client.rs:762 Note: Returns enriched message with decoded content.
let decoded = client.message_v2(message_id)?;
println!("Decoded content: {:?}", decoded.content);

delete_message(message_id)

Delete a message by its ID.
message_id
Vec<u8>
required
Message ID bytes
Returns: Result<usize, ClientError> - Number of messages deleted (0 or 1) Source: crates/xmtp_mls/src/client.rs:783 Note: Idempotent - doesn’t error if message not found.
let deleted = client.delete_message(message_id)?;
if deleted > 0 {
    println!("Message deleted");
}

Synchronization

sync_welcomes()

Download all unread welcome messages and create groups. Returns: Result<Vec<MlsGroup<Context>>, GroupError> Source: crates/xmtp_mls/src/client.rs:985 Note: Ignores malformed messages. Returns newly created groups.
let new_groups = client.sync_welcomes().await?;
println!("Joined {} new groups", new_groups.len());

sync_all_groups(groups)

Sync specified groups to receive latest messages.
groups
Vec<MlsGroup<Context>>
required
Groups to sync
Returns: Result<GroupSyncSummary, GroupError> Source: crates/xmtp_mls/src/client.rs:994
let groups = client.find_groups(GroupQueryArgs::default())?;
let summary = client.sync_all_groups(groups).await?;
println!("Synced {}/{} groups", summary.num_synced, summary.num_eligible);
Sync welcomes and then sync all groups.
Filter groups by consent state
Returns: Result<GroupSyncSummary, GroupError> Source: crates/xmtp_mls/src/client.rs:1006
let summary = client.sync_all_welcomes_and_groups(None).await?;

sync_all_welcomes_and_device_sync_groups()

Sync welcomes and device sync groups (preferences). Returns: Result<GroupSyncSummary, ClientError> Source: crates/xmtp_mls/src/client.rs:1016
let summary = client.sync_all_welcomes_and_device_sync_groups().await?;

wait_for_sync_worker_init()

Wait until the sync worker is initialized and running. Returns: (async fn) Source: crates/xmtp_mls/src/client.rs:262
client.wait_for_sync_worker_init().await;
Set consent records in the local database.
records
&[StoredConsentRecord]
required
Consent records to store
Returns: Result<(), ClientError> Source: crates/xmtp_mls/src/client.rs:469 Note: Broadcasts changes to sync workers.
use xmtp_db::consent_record::{ConsentState, ConsentType, StoredConsentRecord};

let record = StoredConsentRecord {
    entity_type: ConsentType::InboxId,
    entity: "target_inbox".to_string(),
    state: ConsentState::Allowed,
};
client.set_consent_states(&[record]).await?;
Get the consent state for an entity.
entity_type
ConsentType
required
Type of entity (Address, InboxId, ConversationId)
entity
String
required
Entity identifier
Returns: Result<ConsentState, ClientError> Source: crates/xmtp_mls/src/client.rs:496
let state = client.get_consent_state(
    ConsentType::InboxId,
    "target_inbox".to_string()
).await?;

Network Queries

can_message(account_identifiers)

Check if account identifiers can receive messages.
account_identifiers
&[Identifier]
required
Account identifiers to check
Returns: Result<HashMap<Identifier, bool>, ClientError> Source: crates/xmtp_mls/src/client.rs:1074
let identifiers = vec![
    Identifier::Address("0x123...".to_string()),
];
let results = client.can_message(&identifiers).await?;
for (ident, can_msg) in results {
    println!("{}: {}", ident, can_msg);
}

get_key_packages_for_installation_ids(installation_ids)

Fetch current key packages from the network.
installation_ids
Vec<Vec<u8>>
required
Installation IDs to fetch key packages for
Returns: Result<HashMap<Vec<u8>, Result<VerifiedKeyPackageV2, KeyPackageVerificationError>>, ClientError> Source: crates/xmtp_mls/src/client.rs:969
let installation_ids = vec![installation_id_bytes];
let key_packages = client.get_key_packages_for_installation_ids(installation_ids).await?;

validate_credential_against_network(conn, credential, installation_pub_key)

Validate a credential against the network.
conn
&DbConnection<Connection>
required
Database connection
credential
&[u8]
required
Credential bytes to validate
installation_pub_key
Vec<u8>
required
Installation public key to verify
Returns: Result<InboxId, ClientError> Source: crates/xmtp_mls/src/client.rs:1049
let conn = DbConnection::new(client.db());
let inbox_id = client.validate_credential_against_network(
    &conn,
    &credential_bytes,
    installation_key,
).await?;

Key Package Management

queue_key_rotation()

Schedule key rotation to occur soon (within 5 seconds). Returns: Result<(), ClientError> Source: crates/xmtp_mls/src/client.rs:945
client.queue_key_rotation().await?;

rotate_and_upload_key_package()

Generate and upload a new key package, replacing the old one. Returns: Result<(), ClientError> Source: crates/xmtp_mls/src/client.rs:955 Note: Should be run after receiving welcome messages.
client.rotate_and_upload_key_package().await?;

Database Management

db()

Get a reference to the database query interface. Returns: <Context::Db as XmtpDb>::DbQuery Source: crates/xmtp_mls/src/client.rs:286
let conn = client.db();

release_db_connection()

Release the client’s database connection pool. Returns: Result<(), ClientError> Source: crates/xmtp_mls/src/client.rs:511
client.release_db_connection()?;

reconnect_db()

Reconnect to the database and restart workers. Returns: Result<(), ClientError> Source: crates/xmtp_mls/src/client.rs:255
client.reconnect_db()?;

Context Access

identity_updates()

Get an IdentityUpdates service instance. Returns: IdentityUpdates<&Context> Source: crates/xmtp_mls/src/client.rs:197
let identity_service = client.identity_updates();

mls_store()

Get an MlsStore instance. Returns: MlsStore<Context> Source: crates/xmtp_mls/src/client.rs:201
let store = client.mls_store();

scw_verifier()

Get the smart contract signature verifier. Returns: Arc<Box<dyn SmartContractSignatureVerifier>> Source: crates/xmtp_mls/src/client.rs:205
let verifier = client.scw_verifier();

version_info()

Get the client’s version information. Returns: &VersionInfo Source: crates/xmtp_mls/src/client.rs:209
let version = client.version_info();

device_sync_client()

Get a device sync client instance. Returns: DeviceSyncClient<Context> Source: crates/xmtp_mls/src/client.rs:301
let sync_client = client.device_sync_client();

device_sync_worker_enabled()

Check if device sync worker is enabled. Returns: bool Source: crates/xmtp_mls/src/client.rs:297
if client.device_sync_worker_enabled() {
    println!("Device sync is active");
}

Statistics (when API client implements HasStats)

api_stats()

Get API call statistics. Returns: ApiStats Source: crates/xmtp_mls/src/client.rs:219
let stats = client.api_stats();
println!("Total API calls: {}", stats.total());

identity_api_stats()

Get identity API statistics. Returns: IdentityStats Source: crates/xmtp_mls/src/client.rs:223
let stats = client.identity_api_stats();

clear_stats()

Clear all API statistics. Source: crates/xmtp_mls/src/client.rs:227
client.clear_stats();

sync_metrics()

Get sync worker metrics. Returns: Option<Arc<WorkerMetrics<SyncMetric>>> Source: crates/xmtp_mls/src/client.rs:266
if let Some(metrics) = client.sync_metrics() {
    println!("Worker metrics: {:?}", metrics);
}

Build docs developers (and LLMs) love