Core Concepts
Inbox ID
An Inbox ID represents a single user identity in XMTP. It’s derived from:wallet_address: The initial wallet creating the inboxnonce: A number (typically 0 for new users, or used for testing)
Members and Identifiers
An inbox has members which can be:Identifiers (Addresses)
- Ethereum addresses: EOA wallets or smart contract wallets
- Passkeys: WebAuthn-based authentication (future support)
Installations
- Represent individual devices or clients
- Each has a unique Ed25519 keypair
- Can send/receive messages on behalf of the inbox
- Cannot add other installations (only addresses can)
Association State
TheAssociationState represents the current members of an inbox at a point in time:
identifier: The wallet address or installation keyadded_by_entity: Which member added this memberclient_timestamp_ns: When the member was addedchain_id: For smart contract wallets, which chain
Identity Actions
Identity updates are composed of actions that modify association state:CreateInbox
Establishes a new inbox:- Must be the first action for a new inbox
account_identifierbecomes the recovery identifier- Signature must be from the account creating the inbox
- Inbox ID is derived:
SHA256(account_identifier + nonce)
AddAssociation
Links a new wallet or installation:existing_member_signaturemust be from a current inbox membernew_member_signaturemust matchnew_member_identifier- Installations cannot add other installations (only addresses can)
- Both signatures must be on the same signature text
RevokeAssociation
Removes a member from the inbox:- Only the recovery identifier can revoke members
- Revoking a member also revokes all its “children” (members it added)
- Example: Revoking a wallet also revokes all installations it added
- Cannot revoke the recovery identifier itself
ChangeRecoveryIdentity
Updates the recovery address:- Only the current recovery identifier can change it
- After changing, the old recovery identifier loses special privileges
- The old address remains a member unless explicitly revoked
Identity Updates
Actions are grouped into IdentityUpdates and published to the network:Building Identity Updates
Use theSignatureRequestBuilder:
- Collects unsigned actions
- Generates signature text for all actions
- Waits for required signatures
- Produces a complete
IdentityUpdate
Signature Types
XMTP supports multiple signature verification methods:EOA Wallet Signatures (ERC-191)
Externally Owned Accounts use ECDSA:- Recover signer address from ECDSA signature
- Ensure recovered address matches expected address
- Signature is valid only for the exact signature text
Smart Contract Wallet Signatures (ERC-1271)
Smart contract wallets validate signatures on-chain:- Signature verification requires calling contract on blockchain
- Contract logic can change over time
- Signature may be valid at one block but invalid later
block_number with signature
- Verification happens at that specific block height
- Uses EIP-6492 for pre-deployed contracts
- Universal validator contract validates signatures
Applications must provide RPC URLs for all supported blockchains when instantiating the client.
Legacy V2 Signatures
XMTP V2 used a different identity model. For migration:- Only usable on inbox with
nonce=0 - Can only be used once (globally per V2 key)
- Replay protection prevents reuse on same inbox
- Allows one-time migration from V2 to MLS
- Recover wallet address from signature on V2 public key
- Verify association challenge signature recovers to V2 public key
- If chain validates, treat as if signed by wallet
Installation Key Signatures
Installations sign with their Ed25519 private key:Replay Protection
To prevent signature reuse attacks:Across Inboxes
Inbox ID is included in all signature text, preventing cross-inbox replay.Within Same Inbox
Raw signatures are stored inseen_signatures:
AssociationError::Replay.
State Management
Computing State
Association state is computed by applying updates sequentially:AssociationState. If any update fails, the entire operation fails.
State Diffs
Compare two states to find membership changes:Smart Contract Wallet Verification
TheSmartContractSignatureVerifier trait abstracts verification:
ChainRpcVerifier: Validates via EVM RPC callsRemoteSignatureVerifier: Delegates to XMTP’s validation serviceMockSmartContractSignatureVerifier: For testing
Chain ID Binding
For smart contract wallets, signatures are bound to a specific chain:Client Integration
TheIdentity struct in xmtp_mls handles:
is_ready(): Check if identity is registeredsequence_id(): Get current sequence for inboxgenerate_and_store_key_package(): Create MLS key packagerotate_and_upload_key_package(): Refresh after use
Querying Identity State
Clients can query association state:Security Considerations
Trust Model
- Backend can return wrong information or hide revocations
- No built-in key transparency (planned for future)
- Clients should verify critical operations
Credential Validation
Clients validate credentials by:- Extracting
inbox_idfrom MLS credential - Resolving current association state for that inbox
- Ensuring installation key is a current member (not revoked)
Revocation Semantics
Revoking an installation:- Does not immediately remove from existing groups
- Groups updated on next sync (typically fast)
- No protocol-level timeliness guarantee
Related Concepts
- MLS Protocol - How identity integrates with MLS
- Client Lifecycle - Registration process
- Groups and Conversations - How identity affects group membership
