### Minimal XMTP Gateway Service Example Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/fund-agents-apps/run-gateway.mdx This Go code demonstrates the most basic setup for an XMTP Gateway Service. It configures itself using environment variables or command-line flags and starts listening for traffic. Note that this example authorizes all requests without limits; production environments require stricter authorization. ```Go package main import ( "context" "log" "slices" "github.com/xmtp/xmtpd/pkg/gateway" ) func main() { // This will gather all the config from environment variables and flags gatewayService, err := gateway.NewGatewayServiceBuilder(gateway.MustLoadConfig()). Build() if err != nil { log.Fatalf("Failed to build gateway service: %v", err) } gatewayService.WaitForShutdown() } ``` -------------------------------- ### XMTP Android SDK Quickstart Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-chat-apps.txt Quickstart guide for the XMTP Android SDK, demonstrating client creation, conversation management, message sending, and listing/streaming/syncing. ```APIDOC # Get started with the XMTP Android SDK Use the [XMTP Android SDK](https://github.com/xmtp/xmtp-android) to build secure, private, and decentralized messaging into your Android app. The guide provides some quickstart code, as well as a map to building a [secure chat app](/protocol/security) with XMTP, including support for: - End-to-end encrypted direct message and group chat conversations - Rich content types (attachments, reactions, replies, and more) - Spam-free chats using user consent preferences ## Quickstart ```kotlin [Kotlin] // 1. Create an EOA or SCW signer. // Details depend on your app's wallet implementation. class EOAWallet : SigningKey { override val publicIdentity: PublicIdentity get() = PublicIdentity(IdentityKind.ETHEREUM, key.publicAddress) override val type: SignerType get() = SignerType.EOA override suspend fun sign(message: String): SignedData { return SignedData(key.sign(message = message)) } } // 2. Create the XMTP client val client = Client.create( account = SigningKey, options = ClientOptions( ClientOptions.Api(XMTPEnvironment.PRODUCTION, true), appContext = ApplicationContext(), dbEncryptionKey = keyBytes // 32 bytes ) ) // 3. Start conversations val group = client.conversations.newGroup(inboxIds = listOf(bo.inboxId, caro.inboxId)) val groupWithMeta = client.conversations.newGroup( inboxIds = listOf(bo.inboxId, caro.inboxId), permissionLevel = GroupPermissionPreconfiguration.ALL_MEMBERS, name = "The Group Name", imageUrl = "www.groupImage.com", description = "The description of the group" ) // 4. Send messages val dm = client.conversations.findOrCreateDm(recipientInboxId) dm.send(text = "Hello world") group.send(text = "Hello everyone") // 5. List, stream, and sync // List existing conversations val conversations = client.conversations.list() val filteredConversations = client.conversations.list(consentState = ConsentState.ALLOWED) // Stream all new conversations and new messages from allowed conversations client.conversations.streamAllMessages(consentStates = listOf(ConsentState.ALLOWED)).collect { // Received a message } // Sync all new welcomes, preference updates, conversations, // and messages from allowed conversations client.conversations.syncAll(consentStates = ConsentState.ALLOWED) ``` ``` -------------------------------- ### Run Example Notification Server Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/push-notifs/android-pn.mdx This command starts the example notification server with specified configurations for XMTP listener, API, database, and FCM integration. Replace placeholders with your actual FCM project ID and credentials. ```bash dev/run \ --xmtp-listener-tls \ --xmtp-listener \ --api \ -x "grpc.production.xmtp.network:443" \ -d "postgres://postgres:xmtp@localhost:25432/postgres?sslmode=disable" \ --fcm-enabled \ --fcm-credentials-json=$YOURFCMJSON \ --fcm-project-id="YOURFCMPROJECTID" ``` -------------------------------- ### Run Example Notification Server with FCM Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-full.txt Starts the example notification server with FCM enabled. Requires XMTP listener, API access, a database connection, and FCM credentials and project ID. ```Bash dev/run \ --xmtp-listener-tls \ --xmtp-listener \ --api \ -x "grpc.production.xmtp.network:443" \ -d "postgres://postgres:xmtp@localhost:25432/postgres?sslmode=disable" \ --fcm-enabled \ --fcm-credentials-json=$YOURFCMJSON \ --fcm-project-id="YOURFCMPROJECTID" ``` -------------------------------- ### XMTP Node SDK Quickstart Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/sdks/node.mdx This example demonstrates creating an XMTP client with a signer, initiating a group conversation, sending messages, and managing conversations by listing, streaming, and syncing. ```typescript // 1. Create an EOA or SCW signer. // Details depend on your app's wallet implementation. import type { Signer, Identifier, IdentifierKind } from '@xmtp/node-sdk'; const signer: Signer = { type: 'EOA', getIdentifier: () => ({ identifier: '0x...', // Ethereum address as the identifier identifierKind: IdentifierKind.Ethereum, }), signMessage: async (message: string): Uint8Array => { // typically, signing methods return a hex string // this string must be converted to bytes and returned in this function }, }; // 2. Create the XMTP client import { Client } from '@xmtp/node-sdk'; import { getRandomValues } from 'node:crypto'; const dbEncryptionKey = getRandomValues(new Uint8Array(32)); const client = await Client.create(signer, { dbEncryptionKey }); // 3. Start a new conversation const group = await client.conversations.createGroup( [bo.inboxId, caro.inboxId], createGroupOptions /* optional */ ); // 4. Send messages await group.sendText('Hello everyone'); // 5. List, stream, and sync // List existing conversations const allConversations = await client.conversations.list({ consentStates: [ConsentState.Allowed], }); // Stream new messages const stream = await client.conversations.streamAllMessages({ consentStates: [ConsentState.Allowed], onValue: (message) => { console.log('New message:', message); }, onError: (error) => { console.error(error); }, }); // Or use for-await loop for await (const message of stream) { // Received a message console.log('New message:', message); } // Sync all new welcomes, preference updates, conversations, // and messages from allowed conversations await client.conversations.syncAll(['allowed']); ``` -------------------------------- ### XMTP Android SDK Quickstart Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-chat-apps.txt Initialize the XMTP client, start conversations, send messages, and manage conversations using the Android SDK. Requires a wallet signer and DB encryption key. ```kotlin // 1. Create an EOA or SCW signer. // Details depend on your app's wallet implementation. class EOAWallet : SigningKey { override val publicIdentity: PublicIdentity get() = PublicIdentity(IdentityKind.ETHEREUM, key.publicAddress) override val type: SignerType get() = SignerType.EOA override suspend fun sign(message: String): SignedData { return SignedData(key.sign(message = message)) } } // 2. Create the XMTP client val client = Client.create( account = SigningKey, options = ClientOptions( ClientOptions.Api(XMTPEnvironment.PRODUCTION, true), appContext = ApplicationContext(), dbEncryptionKey = keyBytes // 32 bytes ) ) // 3. Start conversations val group = client.conversations.newGroup(inboxIds = listOf(bo.inboxId, caro.inboxId)) val groupWithMeta = client.conversations.newGroup( inboxIds = listOf(bo.inboxId, caro.inboxId), permissionLevel = GroupPermissionPreconfiguration.ALL_MEMBERS, name = "The Group Name", imageUrl = "www.groupImage.com", description = "The description of the group" ) // 4. Send messages val dm = client.conversations.findOrCreateDm(recipientInboxId) dm.send(text = "Hello world") group.send(text = "Hello everyone") // 5. List, stream, and sync // List existing conversations val conversations = client.conversations.list() val filteredConversations = client.conversations.list(consentState = ConsentState.ALLOWED) // Stream all new conversations and new messages from allowed conversations client.conversations.streamAllMessages(consentStates = listOf(ConsentState.ALLOWED)).collect { // Received a message } // Sync all new welcomes, preference updates, conversations, // and messages from allowed conversations client.conversations.syncAll(consentStates = ConsentState.ALLOWED) ``` -------------------------------- ### Install XMTP SDK and Dependencies Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/intro/quickstart.mdx Navigate into your project directory and install the necessary XMTP SDK and cryptographic libraries. ```bash cd my-xmtp-app npm install @xmtp/browser-sdk @noble/curves @noble/hashes ``` -------------------------------- ### Install XMTP Browser SDK Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/sdks/browser.mdx Install the `@xmtp/browser-sdk` package using your preferred package manager. ```bash npm i @xmtp/browser-sdk ``` ```bash pnpm i @xmtp/browser-sdk ``` ```bash yarn add @xmtp/browser-sdk ``` ```bash bun i @xmtp/browser-sdk ``` -------------------------------- ### Install XMTP Node SDK Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/sdks/node.mdx Install the XMTP Node SDK using your preferred package manager. ```bash npm i @xmtp/node-sdk ``` ```bash pnpm i @xmtp/node-sdk ``` ```bash yarn add @xmtp/node-sdk ``` ```bash bun i @xmtp/node-sdk ``` -------------------------------- ### Install ElizaOS XMTP Plugin Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/agents/get-started/faq.mdx Install the official ElizaOS XMTP plugin using pnpm or the ElizaOS CLI. ```bash pnpm add @elizaos/plugin-xmtp # or elizaos add plugins @elizaos/plugin-xmtp ``` -------------------------------- ### Install or Upgrade Go Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/push-notifs/pn-server.mdx Install or upgrade the Go programming language using Homebrew. This command ensures you have the latest version. ```bash brew install go ``` -------------------------------- ### Install Canvas Library Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/agents/content-types/attachments.mdx Install the canvas library to programmatically create image files for attachments. ```bash npm install canvas ``` -------------------------------- ### Install PM2 with pnpm Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-full.txt Install PM2 as a project dependency using pnpm. ```bash pnpm add pm2 ``` -------------------------------- ### Install XMTP Browser SDK with bun Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-full.txt Install the XMTP Browser SDK using bun. This command is used for adding the dependency to your project. ```bash bun i @xmtp/browser-sdk ``` -------------------------------- ### Install PM2 with yarn Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-full.txt Install PM2 as a project dependency using yarn. ```bash yarn add pm2 ``` -------------------------------- ### Install Pinata SDK Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/agents/content-types/attachments.mdx Install the Pinata SDK to interact with Pinata's IPFS network for storing attachments. ```bash npm install pinata ``` -------------------------------- ### Agent Start Event and Client Context Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-agents.txt Logs the agent's address and a test URL upon starting. Requires importing `getTestUrl`. ```typescript import { getTestUrl } from '@xmtp/agent-sdk'; agent.on('start', () => { console.log(`Waiting for messages...`); console.log(`Address: ${agent.address}`); console.log(`🔗 ${getTestUrl(agent.client)}`); }); ``` -------------------------------- ### Install XMTP Browser SDK with yarn Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-full.txt Install the XMTP Browser SDK using yarn. This command adds the SDK as a project dependency. ```bash yarn add @xmtp/browser-sdk ``` -------------------------------- ### Dockerfile for Railway Deployment Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/agents/get-started/connect-to-xmtp.mdx Defines the Docker image for your agent, including Node.js setup, dependency installation, and copying source code. Ensure CA certificates are installed for secure connections. ```dockerfile FROM node:22-slim # Install CA certificates for TLS/gRPC connections RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* WORKDIR /app # Copy package files and install dependencies COPY package.json package-lock.json* ./ RUN npm install # Copy source COPY src ./src COPY tsconfig.json ./ # The agent is a long-running process, not a web server CMD ["npm", "start"] ``` -------------------------------- ### Initialize Project Directory Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/agents/get-started/connect-to-xmtp.mdx Create and navigate into a new project directory, then initialize it as a Git repository. ```bash mkdir my-xmtp-agent cd my-xmtp-agent git init ``` -------------------------------- ### Complete XMTP Agent Example Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/agents/get-started/connect-to-xmtp.mdx This is a full example of an XMTP agent that uses the Anthropic AI SDK for its 'brain' and the XMTP Agent SDK for messaging. It includes setup, message handling, and agent startup. ```tsx import "dotenv/config"; import Anthropic from "@anthropic-ai/sdk"; import { Agent } from "@xmtp/agent-sdk"; // --------------------------------------------------------------------------- // THE BRAIN -- Your AI logic // --------------------------------------------------------------------------- const anthropic = new Anthropic(); const SYSTEM_PROMPT = `[REPLACE: Your agent's personality and instructions go here. For example: - A customer service agent: "You are a helpful support agent for Acme Corp..." - A language tutor: "You are a patient French tutor..." - A trading advisor: "You are a cryptocurrency analyst..." Be specific about the tone, constraints, and format of responses.]`; async function think(input: string): Promise { const response = await anthropic.messages.create({ model: "claude-sonnet-4-20250514", max_tokens: 1024, system: SYSTEM_PROMPT, messages: [{ role: "user", content: input }], }); const block = response.content[0]; return block?.type === "text" ? block.text : "Sorry, I couldn't process that."; } // --------------------------------------------------------------------------- // THE MESSAGING RAILS -- XMTP Agent SDK (send/receive messages with users) // --------------------------------------------------------------------------- const agent = await Agent.createFromEnv(); // --------------------------------------------------------------------------- // THE GLUE: Route messages between XMTP and the brain (i.e., AI API, rules engine) // --------------------------------------------------------------------------- agent.on("text", async (ctx) => { const input = ctx.message.content; console.log(`Received: "${input}"`); const response = await think(input); console.log(`Response: "${response}"`); await ctx.conversation.sendText(response); }); agent.on("start", () => { console.log("Agent is online"); console.log(` Address: ${agent.address}`); console.log(` Chat: http://xmtp.chat/dm/${agent.address}`); }); agent.on("unhandledError", (error) => { console.error("Error:", error); }); await agent.start(); ``` -------------------------------- ### View Inbox State Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/core-messaging/manage-inboxes.mdx Get the current inbox state, which includes associated identities and installations. This can be fetched from the network or retrieved from a local cache. ```tsx // fetch inbox states from the network const states = await client.preferences.fetchInboxStates([inboxId, inboxId]); // or get from local cache (doesn't refresh from network) const states = await client.preferences.getInboxStates([inboxId, inboxId]); ``` ```jsx const state = await client.inboxState(true); const states = await client.inboxStates(true, [inboxId, inboxId]); ``` ```kotlin val state = client.inboxState(true) val states = client.inboxStatesForInboxIds(true, listOf(inboxID, inboxID)) ``` ```swift let state = try await client.inboxState(refreshFromNetwork: true) let states = try await client.inboxStatesForInboxIds( refreshFromNetwork: true, inboxIds: [inboxID, inboxID] ) ``` -------------------------------- ### Initialize Project and Install Dependencies Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-full.txt Commands to set up a new project directory, initialize it with ES module support, and install TypeScript and related development dependencies. ```bash mkdir my-agent cd my-agent npm init --init-type=module -y npm i -D typescript npm i -D tsx npm i -D @types/node ``` -------------------------------- ### Create Vite Project Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/intro/quickstart.mdx Use npm to create a new Vite project with the vanilla template. Ensure you select 'No' when prompted to install and start. ```bash npm create vite@latest my-xmtp-app -- --template vanilla ``` -------------------------------- ### Preview Local Static Build Source: https://github.com/xmtp/docs-xmtp-org/blob/main/README.md Start a local server to view the static website content generated in the `dist` directory. The website opens at `http://localhost:4173/`. ```bash $ npm run preview ``` -------------------------------- ### Set Up XMTP Agent Project Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-agents.txt Install Node.js LTS, create a project folder, and initialize a new project with ES module support. Install TypeScript, tsx, and Node.js type definitions as development dependencies. ```bash mkdir my-agent cd my-agent npm init --init-type=module -y npm i -D typescript npm i -D tsx npm i -D @types/node ``` -------------------------------- ### Get Welcome Message Topic ID Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/push-notifs/push-notifs.mdx Obtain the topic identifier for an app installation to listen for push notifications about new group chats or direct messages. This is used for initial welcome messages. ```tsx // Request alix.welcomeTopic() // Response /xmtp/mls/1/w-$installationId/proto ``` ```kotlin // Request Topic.userWelcome(client.installationId).description // Response /xmtp/mls/1/w-$installationId/proto ``` ```swift // Request Topic.userWelcome(client.installationId).description // Response /xmtp/mls/1/w-$installationId/proto ``` -------------------------------- ### Railway CLI Deployment Commands Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-agents.txt These commands guide you through deploying the LLM agent to Railway. They cover installation, login, initialization, linking, setting environment variables, adding persistent storage, and the final deployment. ```bash # Install Railway CLI if you haven't npm install -g @railway/cli # Log in and initialize railway login railway init # Deploy (this creates the service) railway up ``` ```bash # Link to the service so you can set variables railway link # Set the environment variables railway variables set XMTP_WALLET_KEY=0x... railway variables set XMTP_DB_ENCRYPTION_KEY=0x... railway variables set XMTP_ENV=production railway variables set ANTHROPIC_API_KEY=sk-ant-... # Add persistent storage (see below for why this matters) railway volume add --mount-path /app/data railway variables set XMTP_DB_DIRECTORY=/app/data # Redeploy with the new configuration railway up ``` ```bash railway up ``` -------------------------------- ### Create XMTP Client and Start Conversations Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-full.txt Demonstrates creating an XMTP client with a signer and options, then starting new group conversations with specified participants and metadata. ```Swift // 1. Create an EOA or SCW signer // Details depend on your app's wallet implementation. public struct EOAWallet: SigningKey { public var identity: PublicIdentity { return PublicIdentity(kind: .ethereum, identifier: key.publicAddress) } public var type: SignerType { .EOA } public func sign(message: String) async throws -> SignedData { return SignedData(try await key.sign(message: message)) } } // 2. Create the XMTP client let client = try await Client.create( account: SigningKey, options: ClientOptions.init( api: .init(env: .production, isSecure: true), dbEncryptionKey: keyBytes // 32 bytes ) ) // 3. Start conversations let group = try await client.conversations.newGroup([bo.inboxId, caro.inboxId]) let groupWithMeta = try await client.conversations.newGroup([bo.inboxId, caro.inboxId], permissionLevel: .admin_only, name: "The Group Name", imageUrl: "www.groupImage.com", description: "The description of the group" ) ``` -------------------------------- ### Count Total and Unread Messages in a Conversation Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-chat-apps.txt Use `countMessages` to get the total number of messages or the count of messages sent after a specific timestamp. This is useful for unread badges. Examples are provided for Browser, Node.js, Kotlin, and Swift. ```typescript // Get total message count const totalCount = await group.countMessages(); // Get count of messages after last check (for unread badge) const lastCheckTimestamp = 1738620126404999936n; const unreadCount = await group.countMessages({ sentAfterNs: lastCheckTimestamp, }); // Get count for a DM conversation const dm = await client.conversations.createDm(recipientInboxId); const dmUnreadCount = await dm.countMessages({ sentAfterNs: lastCheckTimestamp, }); ``` ```typescript // Get total message count const totalCount = await group.countMessages(); // Get count of messages after last check (for unread badge) const lastCheckTimestamp = 1738620126404999936n; const unreadCount = await group.countMessages({ sentAfterNs: lastCheckTimestamp, }); // Get count for a DM conversation const dm = await client.conversations.createDm(recipientInboxId); const dmUnreadCount = await dm.countMessages({ sentAfterNs: lastCheckTimestamp, }); ``` ```kotlin // Get total message count val totalCount = group.countMessages() // Get count of messages after last check (for unread badge) val lastCheckTimestamp: Long = 1738620126404999936 val unreadCount = group.countMessages(afterNs = lastCheckTimestamp) // Get count for a DM conversation val dm = client.conversations.findOrCreateDm(recipientInboxId) val dmUnreadCount = dm.countMessages(afterNs = lastCheckTimestamp) ``` ```swift // Get total message count let totalCount = try group.countMessages() // Get count of messages after last check (for unread badge) let lastCheckTimestamp: Int64 = 1738620126404999936 let unreadCount = try group.countMessages(afterNs: lastCheckTimestamp) // Get count for a DM conversation let dm = try await client.conversations.findOrCreateDm(with: recipientInboxId) let dmUnreadCount = try dm.countMessages(afterNs: lastCheckTimestamp) ``` -------------------------------- ### XMTP Browser SDK Quickstart Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/sdks/browser.mdx Initialize the XMTP client with a signer, create group conversations, send messages, and stream new messages in a browser environment. ```tsx // 1. Create an EOA or SCW signer. // Details depend on your app's wallet implementation. import type { Signer, Identifier } from '@xmtp/browser-sdk'; import { IdentifierKind } from '@xmtp/browser-sdk'; const signer: Signer = { type: 'EOA', getIdentifier: () => ({ identifier: '0x...', // Ethereum address as the identifier identifierKind: IdentifierKind.Ethereum, }), signMessage: async (message: string): Uint8Array => { // typically, signing methods return a hex string // this string must be converted to bytes and returned in this function }, }; // 2. Create the XMTP client import { Client } from '@xmtp/browser-sdk'; const client = await Client.create(signer, { // Note: dbEncryptionKey is not used for encryption in browser environments }); // 3. Start conversations const group = await client.conversations.createGroup( [bo.inboxId, caro.inboxId], createGroupOptions /* optional */ ); // 4. Send messages await group.sendText('Hello everyone'); // 5. List, stream, and sync // List existing conversations const allConversations = await client.conversations.list({ consentStates: [ConsentState.Allowed], }); const allGroups = await client.conversations.listGroups({ consentStates: [ConsentState.Allowed], }); const allDms = await client.conversations.listDms({ consentStates: [ConsentState.Allowed], }); // Stream new messages const stream = await client.conversations.streamAllMessages({ consentStates: [ConsentState.Allowed], onValue: (message) => { console.log('New message:', message); }, onError: (error) => { console.error(error); }, }); // Or use for-await loop for await (const message of stream) { console.log('New message:', message); } // Sync all new welcomes, preference updates, conversations, // and messages from allowed conversations await client.conversations.syncAll(['allowed']); ``` -------------------------------- ### Install Docker and Docker Compose Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/push-notifs/pn-server.mdx Use Homebrew to install Docker, Docker Compose, and the Docker credential helper. Ensure Docker Desktop is running. ```bash brew install docker docker-compose docker-credential-desktop ``` -------------------------------- ### Get Group Creator/Adder Inbox ID Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/user-consent/support-user-consent.mdx Retrieve the inbox ID of the user who created a group or added you to it. This is useful for checking consent states related to group origins. Examples provided for React Native, Kotlin, and Swift. ```tsx group.addedByInboxId; await group.creatorInboxId(); ``` ```kotlin group.addedByInboxId() group.creatorInboxId() ``` ```swift try await group.addedByInboxId() try await group.creatorInboxId() ``` -------------------------------- ### Get Last Read Times for a Conversation Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-full.txt Retrieves the timestamp of when each participant last read the conversation. The Kotlin and Swift examples return timestamps in nanoseconds. React Native requires manual tracking by filtering for read receipt content types. ```kotlin // Get last read times for a conversation val lastReadTimes = conversation.getLastReadTimes() // Returns Map where value is timestamp in nanoseconds lastReadTimes.forEach { (inboxId, timestampNs) -> println("$inboxId last read at $timestampNs") } ``` ```swift // Get last read times for a conversation let lastReadTimes = try conversation.getLastReadTimes() // Returns [String: Int64] where value is timestamp in nanoseconds for (inboxId, timestampNs) in lastReadTimes { print("\(inboxId) last read at \(timestampNs)") } ``` ```typescript // React Native doesn't have a getLastReadTimes() convenience method. // Track read receipts manually by filtering messages: const messages = await conversation.messages(); const readReceipts = messages.filter( (msg) => msg.contentTypeId === 'xmtp.org/readReceipt:1.0' ); // Build a map of last read times by sender const lastReadTimes = new Map(); readReceipts.forEach((receipt) => { const existing = lastReadTimes.get(receipt.senderInboxId); if (!existing || receipt.sent > existing) { lastReadTimes.set(receipt.senderInboxId, receipt.sent); } }); ``` -------------------------------- ### Revoke Installations using Backend instance (Browser) Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-chat-apps.txt Use the `createBackend` function to initialize the backend and then call `Client.revokeInstallations` with the signer, inbox ID, and installation bytes. This is the recommended method for browser environments. ```tsx import { createBackend } from '@xmtp/browser-sdk'; const backend = await createBackend({ env: "production" }); const inboxStates = await Client.fetchInboxStates([inboxId], backend); const toRevokeInstallationBytes = inboxStates[0].installations.map((i) => i.bytes); await Client.revokeInstallations( signer, inboxId, toRevokeInstallationBytes, backend ); ``` -------------------------------- ### Check Group Join Request Status Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/core-messaging/support-group-invite-links.mdx This example shows how to make a GET request to check the status of a group join request using its ID. The response includes the request ID, its status (e.g., 'approved', 'rejected', 'pending'), and an optional reason. ```html GET /groupJoinRequest/hijklmn ``` -------------------------------- ### Initialize XMTP Client and Manage Conversations Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/sdks/ios.mdx Demonstrates how to create an EOA wallet signer, initialize the XMTP client with encryption options, and start new group or direct message conversations. ```Swift public struct EOAWallet: SigningKey { public var identity: PublicIdentity { return PublicIdentity(kind: .ethereum, identifier: key.publicAddress) } public var type: SignerType { .EOA } public func sign(message: String) async throws -> SignedData { return SignedData(try await key.sign(message: message)) } } // 2. Create the XMTP client let client = try await Client.create( account: SigningKey, options: ClientOptions.init( api: .init(env: .production, isSecure: true), dbEncryptionKey: keyBytes // 32 bytes ) ) // 3. Start conversations let group = try await client.conversations.newGroup([bo.inboxId, caro.inboxId]) let groupWithMeta = try await client.conversations.newGroup([bo.inboxId, caro.inboxId], permissionLevel: .admin_only, name: "The Group Name", imageUrl: "www.groupImage.com", description: "The description of the group" ) ``` -------------------------------- ### Build XMTP Client with Kotlin Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/core-messaging/create-a-client.mdx Instantiate and build an XMTP client using Kotlin. This example shows how to configure API environment, security, and database encryption. ```kotlin val options = ClientOptions( ClientOptions.Api(XMTPEnvironment.PRODUCTION, true), appContext = ApplicationContext(), dbEncryptionKey = keyBytes ) val client = Client().build( identity = identity, options = options ) ``` -------------------------------- ### Revoke Specific Installations Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/core-messaging/manage-inboxes.mdx Use this function to revoke one or more specific installations by their IDs. This is useful when a user needs to remove old or unwanted installations, especially when nearing the installation limit. ```typescript await client.revokeInstallations([installationId1, installationId2]); ``` ```typescript await client.revokeInstallations([installationId1, installationId2]); ``` ```jsx await client.revokeInstallations(signingKey, [installationIds]); ``` ```kotlin client.revokeInstallations(signingKey, listOf(installationIds)) ``` ```swift try await client.revokeInstallations(signingKey, [installationIds]) ``` -------------------------------- ### Revoke All Other Installations Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-chat-apps.txt Revoke all installations associated with an inbox ID, except for the currently accessed installation. This simplifies session management for users. ```APIDOC ## Revoke All Other Installations ### Description Revoke all installations other than the currently accessed installation. ### Method `revokeAllOtherInstallations` ### Parameters #### Path Parameters - `signingKey` (string) - Required - The signing key for authentication. ``` ```APIDOC ## Revoke All Other Installations (Examples) ### Browser/Node Example ```tsx await client.revokeAllOtherInstallations(); ``` ### React Native Example ```jsx await client.revokeAllOtherInstallations(signingKey); ``` ### Kotlin Example ```kotlin client.revokeAllOtherInstallations(signingKey) ``` ### Swift Example ```swift try await client.revokeAllOtherInstallations(signingKey) ``` ``` -------------------------------- ### Install TypeScript and Dependencies Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/agents/get-started/build-an-agent.mdx Installs TypeScript, tsx for direct TypeScript execution, and Node.js type definitions. Ensure Node.js LTS is installed first. ```bash # Create a folder for your agent code mkdir my-agent cd my-agent # Initialize a new project with ES module support npm init --init-type=module -y # Install TypeScript as development dependency (-D) npm i -D typescript # Install tsx to run TypeScript files directly # without a separate build step npm i -D tsx # Install Node.js type definitions # to enable TypeScript support for built-in APIs npm i -D @types/node ``` -------------------------------- ### Revoke Specific Installations Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-chat-apps.txt Revoke one or more specific installations by their IDs. This is useful when a user needs to free up space for a new installation or manage existing ones. ```APIDOC ## Revoke Specific Installations ### Description Revoke one or more specific installations by ID. ### Method `revokeInstallations` ### Parameters #### Path Parameters - `signingKey` (string) - Required - The signing key for authentication. #### Request Body - `installationIds` (string[]) - Required - An array of installation IDs to revoke. ``` ```APIDOC ## Revoke Specific Installations (Examples) ### Browser/Node Example ```tsx await client.revokeInstallations([installationId1, installationId2]); ``` ### React Native Example ```jsx await client.revokeInstallations(signingKey, [installationIds]); ``` ### Kotlin Example ```kotlin client.revokeInstallations(signingKey, listOf(installationIds)) ``` ### Swift Example ```swift try await client.revokeInstallations(signingKey, [installationIds]) ``` ``` -------------------------------- ### Create XMTP Client in Swift Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/core-messaging/create-a-client.mdx Example of creating an XMTP client in Swift, setting up client options including the API environment and database encryption key. ```swift let options = ClientOptions.init( api: .init(env: .production, isSecure: true), dbEncryptionKey: keyBytes // 32 bytes ) let client = try await Client.create( account: SigningKey, options: options ) ``` -------------------------------- ### Send a sync request Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/list-stream-sync/history-sync.mdx Send a request to other installations to sync conversations and messages to the current installation. Call this after creating a client on a new installation to pull in historical data. ```APIDOC ## Send a sync request Send a request to other installations to sync conversations and messages to the current installation. Call this after creating a client on a new installation to pull in historical data. ### Method `client.sendSyncRequest(options?: ArchiveOptions, serverUrl?: string)` ### Parameters #### Options - `startNs` (number) - Optional - Start timestamp in nanoseconds to filter the archive to a time range. - `endNs` (number) - Optional - End timestamp in nanoseconds to filter the archive to a time range. - `archiveElements` (Array) - Optional - What to include in the archive: `messages`, `consent`, or both. Defaults to `[messages, consent]`. - `excludeDisappearingMessages` (boolean) - Optional - Whether to exclude disappearing messages from the archive. Defaults to `false`. #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```js // With default options await client.sendSyncRequest(); // With custom options await client.sendSyncRequest( { archiveElements: ["consent"] }, // options "https://your-history-sync-server.example.com/" // serverUrl ); ``` ### Response #### Success Response (200) - `summary` (object) - An object containing sync summary information. ``` -------------------------------- ### Revoke Agent Installations using CLI Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/agents/build-agents/local-database.mdx Use this command to revoke agent installations. Replace `` with the ID of the inbox and `` with a comma-separated list of installation IDs to exclude from revocation. ```bash yarn revoke ``` -------------------------------- ### Create XMTP Client and Start Conversations (Kotlin) Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-full.txt This snippet demonstrates how to create an XMTP client using a provided signer and options, including database encryption. It then shows how to initiate new group conversations with optional metadata. ```kotlin // 1. Create an EOA or SCW signer. // Details depend on your app's wallet implementation. class EOAWallet : SigningKey { override val publicIdentity: PublicIdentity get() = PublicIdentity(IdentityKind.ETHEREUM, key.publicAddress) override val type: SignerType get() = SignerType.EOA override suspend fun sign(message: String): SignedData { return SignedData(key.sign(message = message)) } } // 2. Create the XMTP client val client = Client.create( account = SigningKey, options = ClientOptions( ClientOptions.Api(XMTPEnvironment.PRODUCTION, true), appContext = ApplicationContext(), dbEncryptionKey = keyBytes // 32 bytes ) ) // 3. Start conversations val group = client.conversations.newGroup(inboxIds = listOf(bo.inboxId, caro.inboxId)) val groupWithMeta = client.conversations.newGroup( inboxIds = listOf(bo.inboxId, caro.inboxId), permissionLevel = GroupPermissionPreconfiguration.ALL_MEMBERS, name = "The Group Name", imageUrl = "www.groupImage.com", description = "The description of the group" ) ``` -------------------------------- ### Revoke Installations using Backend instance (Node) Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-chat-apps.txt For Node.js environments, use `createBackend` from `@xmtp/node-sdk` to initialize the backend and then call `Client.revokeInstallations`. This is the recommended approach. ```tsx import { createBackend } from '@xmtp/node-sdk'; const backend = await createBackend({ env: "production" }); const inboxStates = await Client.fetchInboxStates([inboxId], backend); const toRevokeInstallationBytes = inboxStates[0].installations.map( (i) => i.bytes ); await Client.revokeInstallations( signer, inboxId, toRevokeInstallationBytes, backend ); ``` -------------------------------- ### Install PM2 with npm Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/public/llms/llms-full.txt Install PM2 as a project dependency using npm. ```bash npm i pm2 ``` -------------------------------- ### Build the XMTP Server Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/push-notifs/pn-server.mdx Compile the server application. Resolve any Go module errors by running the suggested `go mod download` commands. ```bash ./dev/build ``` -------------------------------- ### Install PM2 as a dependency Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/agents/deploy/pm2-process-management.mdx Install PM2 using your preferred package manager. ```bash npm i pm2 ``` ```bash yarn add pm2 ``` ```bash pnpm add pm2 ``` -------------------------------- ### Run Local Development Server Source: https://github.com/xmtp/docs-xmtp-org/blob/main/README.md Use this command to start a local development server for viewing website changes as you make them. The website automatically updates without restarting the server. ```bash $ npm run dev ``` -------------------------------- ### Revoke All Other Installations Source: https://github.com/xmtp/docs-xmtp-org/blob/main/docs/pages/chat-apps/core-messaging/manage-inboxes.mdx Use this function to revoke all installations associated with an inbox ID, except for the currently active one. This is a convenient way to clean up old installations and ensure only the current session is active. ```typescript await client.revokeAllOtherInstallations(); ``` ```typescript await client.revokeAllOtherInstallations(); ``` ```jsx await client.revokeAllOtherInstallations(signingKey); ``` ```kotlin client.revokeAllOtherInstallations(signingKey) ``` ```swift try await client.revokeAllOtherInstallations(signingKey) ```