Create an XMTP client
Create an XMTP client that can use the signing capabilities provided by the signer. This signer links the client to the appropriate EOA or SCW.
Understand creating and building a client
This video provides a walkthrough of creating and building a client.
How it works
When you call Client.create()
, the following steps happen under the hood:
- Extracts the
signer
and retrieves the wallet address from it. - Checks the XMTP identity ledger to find an inbox ID associated with the signer address. The inbox ID serves as the user's identity on the XMTP network.
- If it doesn't find an existing inbox ID, it requests a wallet signature to register the identity and create an inbox ID.
- If it finds an existing inbox ID, it uses the existing inbox ID.
- Checks if a local SQLite database exists. This database contains the identity's installation state and message data.
- If it doesn't find an existing local database, it creates one. On non-web platforms, it encrypts the database with the provided
dbEncryptionKey
. - If it finds an existing local database:
- For the Node, React Native, Android, and iOS SDKs: It checks if the provided
dbEncryptionKey
matches. If it matches, it uses the existing database. If not, it creates a new database encrypted with the provided key. - For the Browser SDK: A
dbEncryptionKey
is not used for encryption due to technical limitations in web environments. Be aware that the database is not encrypted.
- For the Node, React Native, Android, and iOS SDKs: It checks if the provided
- If it doesn't find an existing local database, it creates one. On non-web platforms, it encrypts the database with the provided
- Returns the XMTP client, ready to send and receive messages.
Keep the database encryption key safe
The dbEncryptionKey
client option is used by the Node, React Native, Android, and Swift SDKs only.
The encryption key is critical to the stability and continuity of an XMTP client. It encrypts the local SQLite database created when you call Client.create()
, and must be provided every time you create or build a client.
As long as the local database and encryption key remain intact, you can use Client.build()
to rehydrate the same client without re-signing.
This encryption key is not stored or persisted by the XMTP SDK, so it's your responsibility as the app developer to store it securely and consistently.
If the encryption key is lost, rotated, or passed incorrectly during a subsequent Client.create()
or Client.build()
call (on non-web platforms), the app will be unable to access the local database. Likewise, if you initially provided the dbPath
option, you must always provide it with every subsequent call or the client may be unable to access the database. The client will assume that the database can't be decrypted or doesn't exist, and will fall back to creating a new installation.
Creating a new installation requires a new identity registration and signature—and most importantly, results in loss of access to all previously stored messages unless the user has done a history sync.
To ensure seamless app experiences persist the dbEncryptionKey
securely, and make sure it's available and correctly passed on each app launch
The dbEncryptionKey
client option is not used by the Browser SDK for due to technical limitations in web environments. In this case, be aware that the database is not encrypted.
To learn more about database operations, see the XMTP MLS protocol spec.
Create a client
To call Client.create()
, you must pass in a required signer
and can also pass in any of the optional parameters covered in Configure an XMTP client.
import { Client, type Signer } from "@xmtp/browser-sdk";
// create a signer
const signer: Signer = { /* ... */ };
const client = await Client.create(
signer,
// client options
{
// Note: dbEncryptionKey is not used for encryption in browser environments
},
);
Configure an XMTP client
You can configure an XMTP client with these options passed to Client.create
:
import type { ContentCodec } from "@xmtp/content-type-primitives";
type ClientOptions = {
/**
* Specify which XMTP environment to connect to. (default: `dev`)
*/
env?: "local" | "dev" | "production";
/**
* apiUrl can be used to override the `env` flag and connect to a
* specific endpoint
*/
apiUrl?: string;
/**
* historySyncUrl can be used to override the `env` flag and connect to a
* specific endpoint for syncing history
*/
historySyncUrl?: string;
/**
* Allow configuring codecs for additional content types
*/
codecs?: ContentCodec[];
/**
* Path to the local DB
*/
dbPath?: string;
/**
* Encryption key for the local DB
*/
dbEncryptionKey?: Uint8Array;
/**
* Enable structured JSON logging
*/
structuredLogging?: boolean;
/**
* Enable performance metrics
*/
performanceLogging?: boolean;
/**
* Logging level
*/
loggingLevel?: "off" | "error" | "warn" | "info" | "debug" | "trace";
/**
* Disable automatic registration when creating a client
*/
disableAutoRegister?: boolean;
};
XMTP network environments
XMTP provides dev
and production
network environments. These networks are completely separate and not interchangeable.
For example, an XMTP identity on the dev
network is completely distinct from the XMTP identity on the production
network, as are the messages associated with these identities. In addition, XMTP identities and messages created on the dev
network can't be accessed from or moved to the production
network, and vice versa.
The production
network is configured to store messages indefinitely. XMTP may occasionally delete messages and identities from the dev
network, and will provide advance notice in the XMTP Community Forums.
You can also use a local
network to have a client communicate with an XMTP node you are running locally. During development, it's highly recommended to use a local
network environment for speed and reliability.
Build an existing client
Build, or resume, an existing client (created using Client.create()
) that's logged in and has an existing local database.
import { Client, type Identifier } from "@xmtp/browser-sdk";
const identifier: Identifier = {
identifier: "0x1234567890abcdef1234567890abcdef12345678",
identifierKind: "Ethereum",
};
const client = await Client.build(identifier, options);
Log out a client
When you log a user out of your app, you can give them the option to delete their local database.
/**
* The Browser SDK client does not currently support deleting the local database.
*/
// this method only terminates the client's associated web worker
client.close();