Skip to content

Commit 039a966

Browse files
authored
Merge branch 'main' into humanagent/feature-20251024-200221
2 parents c10d4c7 + 95bcea5 commit 039a966

File tree

6 files changed

+251
-99
lines changed

6 files changed

+251
-99
lines changed

docs/pages/agents/build-agents/create-a-client.mdx

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const signer = createSigner(user);
1515

1616
const agent = await Agent.create(signer, {
1717
env: 'dev', // or 'production'
18-
dbEncryptionKey: getRandomValues(new Uint8Array(32)), // save it for later
18+
dbEncryptionKey: `0x${getRandomValues(new Uint8Array(32))}`, // save it for later
1919
});
2020
```
2121

@@ -25,11 +25,11 @@ The XMTP Agent SDK allows you to use environment variables (`process.env`) for e
2525

2626
**Available variables:**
2727

28-
| Variable | Purpose | Example |
29-
| ------------------------ | -------------------------------------------------------------- | --------------------------------------- |
30-
| `XMTP_WALLET_KEY` | Private key for wallet | `XMTP_WALLET_KEY=0x1234...abcd` |
31-
| `XMTP_ENV` | XMTP network environment (`local`, `dev`, or `production`) | `XMTP_ENV=dev` or `XMTP_ENV=production` |
32-
| `XMTP_DB_ENCRYPTION_KEY` | Database encryption key for the local database (32 bytes, hex) | `XMTP_DB_ENCRYPTION_KEY=0xabcd...1234` |
28+
| Variable | Purpose | Example |
29+
| ------------------------ | ------------------------------------------------------------------------------------ | --------------------------------------- |
30+
| `XMTP_WALLET_KEY` | Private key for wallet | `XMTP_WALLET_KEY=0x1234...abcd` |
31+
| `XMTP_ENV` | XMTP network environment (`local`, `dev`, or `production`) | `XMTP_ENV=dev` or `XMTP_ENV=production` |
32+
| `XMTP_DB_ENCRYPTION_KEY` | Database encryption key for the local database (32 bytes, hex string with 0x prefix) | `XMTP_DB_ENCRYPTION_KEY=0xabcd...1234` |
3333

3434
Using the environment variables, you can setup your agent in just a few lines of code:
3535

@@ -40,7 +40,7 @@ import { generatePrivateKey } from 'viem';
4040
import { getRandomValues } from 'node:crypto';
4141

4242
const walletKey = generatePrivateKey();
43-
const encryptionKeyHex = getRandomValues(new Uint8Array(32));
43+
const encryptionKeyHex = `0x${getRandomValues(new Uint8Array(32))}`;
4444

4545
console.log(`Wallet key: ${walletKey}`);
4646
console.log(`Encryption key: ${encryptionKeyHex}`);
@@ -121,9 +121,13 @@ apiUrl?: string;
121121
*/
122122
dbPath?: string | null | ((inboxId: string) => string);
123123
/**
124-
* Encryption key for the local DB
124+
* Encryption key for the local DB (32 bytes)
125+
*
126+
* Accepts either:
127+
* - Uint8Array (32 bytes)
128+
* - Hex string with 0x prefix (64 hex characters representing 32 bytes)
125129
*/
126-
dbEncryptionKey?: Uint8Array;
130+
dbEncryptionKey?: Uint8Array | `0x${string}`;
127131
/**
128132
* Allow configuring codecs for additional content types
129133
*/

docs/pages/agents/concepts/identity.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ When you call `Agent.create()`, the following steps happen under the hood:
3636

3737
The `dbEncryptionKey` client option is used by the Node, React Native, Android, and Swift SDKs only.
3838

39-
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.
39+
The encryption key is used together with an auto-generated salt to encrypt the local database using [SQLCipher](https://www.zetetic.net/sqlcipher/). It encrypts the database created when you call `Agent.create()`.
4040

4141
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.
4242

docs/pages/chat-apps/core-messaging/create-a-client.mdx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,12 @@ const signer: Signer = {
102102
*
103103
* This value must be consistent when creating a client with an existing
104104
* database.
105+
*
106+
* You can provide the key as either:
107+
* - Uint8Array (32 bytes)
108+
* - Hex string with 0x prefix (64 hex characters representing 32 bytes)
105109
*/
106-
const dbEncryptionKey = getRandomValues(new Uint8Array(32));
110+
const dbEncryptionKey = `0x${getRandomValues(new Uint8Array(32))}`;
107111

108112
const client = await Client.create(
109113
signer,
@@ -219,9 +223,13 @@ type ClientOptions = {
219223
*/
220224
dbPath?: string | null | ((inboxId: string) => string);
221225
/**
222-
* Encryption key for the local DB
226+
* Encryption key for the local DB (32 bytes)
227+
*
228+
* Accepts either:
229+
* - Uint8Array (32 bytes)
230+
* - Hex string with 0x prefix (64 hex characters representing 32 bytes)
223231
*/
224-
dbEncryptionKey?: Uint8Array;
232+
dbEncryptionKey?: Uint8Array | `0x${string}`;
225233
/**
226234
* Enable structured JSON logging
227235
*/
@@ -307,9 +315,13 @@ type ClientOptions = {
307315
*/
308316
dbPath?: string | null | ((inboxId: string) => string);
309317
/**
310-
* Encryption key for the local DB
318+
* Encryption key for the local DB (32 bytes)
319+
*
320+
* Accepts either:
321+
* - Uint8Array (32 bytes)
322+
* - Hex string with 0x prefix (64 hex characters representing 32 bytes)
311323
*/
312-
dbEncryptionKey?: Uint8Array;
324+
dbEncryptionKey?: Uint8Array | `0x${string}`;
313325
/**
314326
* Allow configuring codecs for additional content types
315327
*/

docs/pages/chat-apps/core-messaging/manage-inboxes.mdx

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,30 +75,51 @@ An inbox ID is limited to 256 inbox updates. Inbox updates include actions like:
7575
- Add an installation
7676
- Revoke an installation
7777

78-
This means that one inbox ID can have up to 256 installations. When you add an inbox ID to a group, you are adding every installation as a member of the group. This means a group with an inbox that has 200+ installations can very quickly make a group size very large, which can have downstream performance implications.
78+
:::danger[CRITICAL FOR PRODUCTION]
7979

80-
If an inbox reaches its limit of 256 inbox updates, the user must [rotate their inbox](#rotate-an-inbox-id) to continue using their identity with XMTP. Rotating the inbox permanently removes access to all existing conversations but allows the user to continue using their identity with new XMTP conversations.
80+
Inbox updates are cumulative and **cannot be reversed**. Revoking an installation counts as an update but does not decrease the total count. Once you've performed 256 updates, you've reached the permanent limit for that inbox.
81+
82+
:::
83+
84+
**What happens when you hit the limit:** If an inbox reaches its limit of 256 inbox updates, you may encounter an "inbox log is full" error. At this point, you must [rotate your inbox](#rotate-an-inbox-id) to continue using your identity with XMTP. Rotating the inbox permanently removes access to all existing conversations but allows you to continue using your identity with new XMTP conversations.
85+
86+
**Why this limit exists:** All identity updates for an inbox must be fetched and validated by every other inbox that interacts with you on the XMTP network. In group conversations, this validation requirement multiplies. If multiple members have extensive identity update histories, it can significantly impact performance and message delivery speed.
8187

8288
### Installation limits
8389

8490
XMTP enforces a 10-installation limit per inbox. When an inbox reaches 10 active installations, the user must revoke at least one installation before adding a new one. This limit serves two purposes:
8591

8692
1. Prevents excessive group sizes: Since all installations in an inbox are added as group members, limiting installations keeps group sizes manageable and maintains performance.
87-
2. Protects against accidental exhaustion: The limit helps prevent users from accidentally reaching the 256-update threshold.
93+
2. Protects against accidental exhaustion: The limit helps prevent users from accidentally reaching the 256 inbox update threshold.
8894

8995
:::warning[Important]
9096

91-
Revoking an installation counts as one of the 256 inbox updates. This means frequently adding and revoking installations will still consume your update quota and could lead to reaching the limit prematurely.
97+
The only way to avoid consuming installation updates is to ensure your XMTP database is persisted and reloaded between app sessions and deployments. When you reuse an existing database, you maintain the same installation instead of creating a new one each time.
9298

9399
:::
94100

95-
The only way to prevent consuming installation updates is to ensure your XMTP database is persisted and reloaded between app sessions and deployments. When you reuse an existing database, you maintain the same installation instead of creating a new one each time.
101+
### Best Practices
102+
103+
**For testing and development:**
104+
105+
If you're developing or testing and frequently creating new installations, you can quickly exhaust your inbox update limit. To avoid this during development:
106+
107+
1. Use persistent storage: Always configure your deployments to preserve the database between restarts
108+
2. Use a local node: Run XMTP locally so you can reset it when hitting limits
109+
3. Use different wallets for testing: Create separate test wallets rather than repeatedly creating installations with the same wallet
110+
4. Monitor your usage: Regularly check your inbox state to track how many updates you've used
96111

97112
Have feedback about the inbox update and installation limits? We'd love to hear it. Post to the [XMTP Community Forums](https://community.xmtp.org/).
98113

99114
### Rotate an inbox ID
100115

101-
When you create an inbox ID, there is a nonce on it that is used to create the ID. If an inbox reaches its inbox updates limit, you can increment the nonce and it will create a new inbox ID associated with the user's information.
116+
When you create an inbox ID, a [cryptographic nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) is used to create the ID. If an inbox reaches its inbox updates limit, you can increment the nonce to create a new inbox ID associated with the same wallet address.
117+
118+
:::danger[CRITICAL FOR PRODUCTION]
119+
120+
Rotating an inbox creates a completely new inbox ID. All conversations and message history from the old inbox will be permanently lost. Other users will need to start new conversations with your new inbox ID.
121+
122+
:::
102123

103124
## Help users manage installations
104125

docs/pages/fund-agents-apps/run-gateway.mdx

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -94,20 +94,9 @@ Every app and agent needs an XMTP Gateway Service.
9494

9595
### For browser and mobile client apps
9696

97-
You must run the XMTP Gateway Service written in Go. Choose the option that works best for you:
97+
Use the [example gateway service repository](https://github.com/xmtp/gateway-service-example) as a starting point to build your own custom gateway with authentication
9898

99-
**Option 1: Basic Docker image** (No Go knowledge required)
100-
101-
- XMTP provides a Docker image that works out of the box
102-
- Authorizes all requests (add authentication for production)
103-
- Suitable for testing
104-
105-
**Option 2: Custom implementation** (Go knowledge required)
106-
107-
- Start with XMTP's Go implementation
108-
- Add your own authentication logic
109-
- Implement custom rate limiting
110-
- Required for apps with authentication needs
99+
For detailed implementation steps, see [Deploy your XMTP Gateway Service](#deploy-your-xmtp-gateway-service).
111100

112101
### For agents and Node.js apps
113102

@@ -275,7 +264,7 @@ This identity will then be used for rate limiting, and will be passed to your `A
275264

276265
:::code-group
277266

278-
```go [IP Address]
267+
```go [IP address]
279268
// We provide a simple implementation that uses the client's IP address to identify users. For a production application, you should limit requests to only users actually authenticated in your application.
280269
package main
281270

@@ -393,7 +382,7 @@ func main() {
393382

394383
```
395384

396-
```go [Rate Limiting]
385+
```go [Rate limiting]
397386
package main
398387

399388
import (
@@ -478,22 +467,39 @@ func main() {
478467

479468
## Deploy your XMTP Gateway Service
480469

481-
Deploy the XMTP Gateway Service on your infrastructure of choice, such as a container hosting service ($25-50/month minimum).
470+
:::tip[Example repo]
482471

483-
We provide a Docker image that corresponds to the bare bones example above that you can run with the appropriate environment variables set in any hosting provider that supports Docker.
472+
You can start with the [example gateway service repository](https://github.com/xmtp/gateway-service-example).
484473

485-
```bash [Bash]
486-
docker run -p 5050:5050 -p 5055:5055 -e XMTPD_PAYER_PRIVATE_KEY=... xmtp/xmtpd-gateway:main
487-
```
474+
:::
488475

489-
Most production apps will require some level of customization to authorize user requests. You can fork our [example repository](https://github.com/xmtp/gateway-service-example), which includes a Dockerfile and a sample configuration.
476+
1. Fork or clone the repository.
477+
2. Add your own authentication logic.
478+
3. Configure your rate limits
479+
4. Deploy your custom image on your infrastructure of choice, such as a container hosting service ($25-50/month minimum).
480+
481+
#### Additional recommendations
490482

491483
The system is able to run without any external dependencies, but we recommend configuring a Redis instance to use for nonce management and rate limiting.
492484

493485
If your XMTP Gateway Service goes down, messages will queue until it comes back online. Build redundancy, if needed.
494486

495487
## Test your XMTP Gateway Service
496488

489+
You can use the prebuilt Docker image for local development and testing:
490+
491+
```bash [Bash]
492+
docker run -p 5050:5050 -p 5055:5055 -e XMTPD_PAYER_PRIVATE_KEY=... xmtp/xmtpd-gateway:main
493+
```
494+
495+
:::warning
496+
497+
This pre-built image authorizes all requests without authentication. Never use it in production.
498+
499+
:::
500+
501+
### Test scenarios
502+
497503
Here are some high priority scenarios to test:
498504

499505
- Deploy and test XMTP Gateway Service

0 commit comments

Comments
 (0)