@hybrd/xmtp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+
2
+ 
3
+ > @hybrd/xmtp@1.0.0-alpha.1 typecheck /Users/ian/Projects/01/hybrid/packages/xmtp
4
+ > tsc --noEmit
5
+
package/README.md ADDED
@@ -0,0 +1,380 @@
1
+ # Enhanced XMTP SDK with Robust Reliability πŸš€
2
+
3
+ This package provides an enhanced XMTP client with robust connection management, retry logic, and health monitoring capabilities.
4
+
5
+ ## πŸ†™ Upgraded Features
6
+
7
+ - **XMTP Node SDK**: Upgraded to `^3.1.0` (latest version)
8
+ - **Enhanced Connection Management**: Automatic reconnection and health monitoring
9
+ - **Robust Retry Logic**: Exponential backoff and configurable retry strategies
10
+ - **Health Monitoring**: Real-time connection health tracking with metrics
11
+ - **Production Ready**: Built for scalable, reliable XMTP integrations
12
+
13
+ ## πŸ—οΈ Architecture Overview
14
+
15
+ Your system uses a **"Thin Listener + QStash Callbacks"** architecture that already provides excellent reliability:
16
+
17
+ ```
18
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
19
+ β”‚ XMTP Network│───▢│Thin Server │───▢│ QStash β”‚
20
+ β”‚ β”‚ β”‚(Enhanced) β”‚ β”‚ (Reliable) β”‚
21
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
22
+ β”‚
23
+ β–Ό
24
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
25
+ β”‚ Agent │◀───│App/Webhook β”‚
26
+ β”‚ Processing β”‚ β”‚ (Scalable) β”‚
27
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
28
+ ```
29
+
30
+ ### βœ… Built-in Reliability Features
31
+
32
+ 1. **QStash Automatic Retries**: Built-in exponential backoff
33
+ 2. **No Persistent Connections**: Eliminates connection drop issues
34
+ 3. **Horizontal Scalability**: Multiple instances supported
35
+ 4. **Dead Letter Queues**: Failed messages are preserved
36
+ 5. **At-least-once Delivery**: Messages guaranteed to be processed
37
+
38
+ ## πŸ”§ Enhanced Connection Management
39
+
40
+ ### Basic Usage
41
+
42
+ ```typescript
43
+ import {
44
+ createSigner,
45
+ createXMTPConnectionManager,
46
+ type XMTPConnectionConfig
47
+ } from "@hybrd/xmtp"
48
+
49
+ // Enhanced connection with reliability features
50
+ const signer = createSigner(process.env.XMTP_WALLET_KEY!)
51
+
52
+ const connectionConfig: XMTPConnectionConfig = {
53
+ maxRetries: 5, // Connection attempts
54
+ retryDelayMs: 1000, // Base retry delay
55
+ healthCheckIntervalMs: 30000, // Health check interval
56
+ connectionTimeoutMs: 15000, // Connection timeout
57
+ reconnectOnFailure: true // Auto-reconnect
58
+ }
59
+
60
+ const connectionManager = await createXMTPConnectionManager(
61
+ signer,
62
+ connectionConfig
63
+ )
64
+
65
+ // Get health metrics
66
+ const health = connectionManager.getHealth()
67
+ console.log('Connection Health:', health)
68
+ ```
69
+
70
+ ### Advanced Production Usage
71
+
72
+ ```typescript
73
+ import { RobustXMTPService } from "@hybrd/xmtp/scripts/enhanced-connection-example"
74
+
75
+ const service = new RobustXMTPService()
76
+ await service.start()
77
+
78
+ // Process messages with automatic retry/reconnection
79
+ await service.processMessage(conversationId, "Hello!")
80
+
81
+ // Monitor health
82
+ const health = service.getConnectionHealth()
83
+ if (!health?.isConnected) {
84
+ console.warn("XMTP connection unhealthy")
85
+ }
86
+ ```
87
+
88
+ ## πŸ”„ Connection Health Monitoring
89
+
90
+ The enhanced client provides real-time health metrics:
91
+
92
+ ```typescript
93
+ interface XMTPConnectionHealth {
94
+ isConnected: boolean // Current connection status
95
+ lastHealthCheck: Date // Last health check timestamp
96
+ consecutiveFailures: number // Failed health checks in a row
97
+ totalReconnects: number // Total reconnection attempts
98
+ avgResponseTime: number // Average response time in ms
99
+ }
100
+ ```
101
+
102
+ ## πŸš€ Quick Start
103
+
104
+ ### 1. Install Dependencies
105
+
106
+ ```bash
107
+ pnpm with-env pnpm --filter @hybrd/xmtp install
108
+ ```
109
+
110
+ ### 2. Run Enhanced Connection Demo
111
+
112
+ ```bash
113
+ pnpm with-env pnpm --filter @hybrd/xmtp enhanced:demo
114
+ ```
115
+
116
+ ### 3. Integrate in Your Code
117
+
118
+ ```typescript
119
+ // Replace basic XMTP client creation
120
+ // OLD:
121
+ const client = await createXMTPClient(signer)
122
+
123
+ // NEW: With enhanced reliability
124
+ const connectionManager = await createXMTPConnectionManager(signer, {
125
+ maxRetries: 5,
126
+ healthCheckIntervalMs: 30000,
127
+ reconnectOnFailure: true
128
+ })
129
+ const client = connectionManager.getClient()
130
+ ```
131
+
132
+ ## πŸ“Š Why Your Current Architecture is Already Robust
133
+
134
+ Your **QStash-based webhook system** already provides superior reliability compared to traditional streaming:
135
+
136
+ ### Traditional Streaming Issues ❌
137
+ - Connection drops require manual reconnection
138
+ - Memory leaks from long-running connections
139
+ - Difficult to scale horizontally
140
+ - Complex heartbeat/keepalive management
141
+ - Single point of failure
142
+
143
+ ### Your QStash Architecture Benefits βœ…
144
+ - **Automatic Retries**: QStash handles exponential backoff
145
+ - **No Connection Drops**: Stateless webhook calls
146
+ - **Horizontal Scaling**: Multiple app instances supported
147
+ - **Built-in Monitoring**: QStash provides delivery metrics
148
+ - **Dead Letter Queues**: Failed messages preserved
149
+ - **At-least-once Delivery**: Guaranteed message processing
150
+
151
+ ## πŸ”§ Configuration Options
152
+
153
+ ### Environment Variables
154
+
155
+ | Variable | Description | Default |
156
+ | --------------------- | ---------------------------------------- | --------------------------------------- |
157
+ | `XMTP_STORAGE_PATH` | Custom path for XMTP database storage | `.data/xmtp` (relative to project root) |
158
+ | `XMTP_WALLET_KEY` | Private key for XMTP wallet | Required |
159
+ | `XMTP_ENCRYPTION_KEY` | Encryption key for database | Required for persistent mode |
160
+ | `XMTP_ENV` | XMTP environment (`dev` or `production`) | `dev` |
161
+ | `PROJECT_ROOT` | Override project root path | Auto-detected |
162
+
163
+ ### Connection Configuration
164
+
165
+ ```typescript
166
+ interface XMTPConnectionConfig {
167
+ maxRetries?: number // Default: 5
168
+ retryDelayMs?: number // Default: 1000ms
169
+ healthCheckIntervalMs?: number // Default: 30000ms
170
+ connectionTimeoutMs?: number // Default: 10000ms
171
+ reconnectOnFailure?: boolean // Default: true
172
+ }
173
+ ```
174
+
175
+ ### Custom Storage Location
176
+
177
+ You can specify a custom storage location for XMTP database files:
178
+
179
+ ```bash
180
+ # Absolute path
181
+ export XMTP_STORAGE_PATH=/custom/path/to/xmtp/storage
182
+
183
+ # Relative path (relative to current working directory)
184
+ export XMTP_STORAGE_PATH=./custom/xmtp/storage
185
+
186
+ # Use with pnpm with-env
187
+ pnpm with-env your-xmtp-command
188
+ ```
189
+
190
+ ### Testing Custom Storage
191
+
192
+ Run the custom storage example to test your configuration:
193
+
194
+ ```bash
195
+ # Test with default storage location
196
+ pnpm with-env pnpm --filter @hybrd/xmtp custom:storage
197
+
198
+ # Test with custom storage location
199
+ export XMTP_STORAGE_PATH=/tmp/my-custom-xmtp-storage
200
+ pnpm with-env pnpm --filter @hybrd/xmtp custom:storage
201
+
202
+ # Test with relative path
203
+ export XMTP_STORAGE_PATH=./my-xmtp-data
204
+ pnpm with-env pnpm --filter @hybrd/xmtp custom:storage
205
+ ```
206
+
207
+ ## πŸ› οΈ Available Scripts
208
+
209
+ | Script | Command | Description |
210
+ | ------------------ | -------------------------------------------- | --------------------------------- |
211
+ | `gen:keys` | `pnpm --filter @hybrd/xmtp gen:keys` | Generate new XMTP wallet keys |
212
+ | `register` | `pnpm --filter @hybrd/xmtp register` | Register wallet on XMTP network |
213
+ | `revoke` | `pnpm --filter @hybrd/xmtp revoke` | Revoke old XMTP installations |
214
+ | `enhanced:demo` | `pnpm --filter @hybrd/xmtp enhanced:demo` | Demo enhanced connection features |
215
+ | `test:messages` | `pnpm --filter @hybrd/xmtp test:messages` | Test message reception |
216
+ | `refresh:identity` | `pnpm --filter @hybrd/xmtp refresh:identity` | Refresh XMTP identity |
217
+ | `custom:storage` | `pnpm --filter @hybrd/xmtp custom:storage` | Test custom storage configuration |
218
+
219
+ > **Note**: Always use `pnpm with-env` to ensure environment variables are loaded:
220
+ > ```bash
221
+ > pnpm with-env pnpm --filter @hybrd/xmtp <script-name>
222
+ > ```
223
+
224
+ ## 🎯 Best Practices
225
+
226
+ ### 1. Use Connection Manager for Long-Running Services
227
+ ```typescript
228
+ // For services that need persistent XMTP connections
229
+ const manager = await createXMTPConnectionManager(signer, config)
230
+ ```
231
+
232
+ ### 2. Leverage Your Existing QStash Architecture
233
+ ```typescript
234
+ // For message processing, your webhook system is ideal
235
+ // No changes needed - it's already robust!
236
+ ```
237
+
238
+ ### 3. Monitor Connection Health
239
+ ```typescript
240
+ setInterval(() => {
241
+ const health = connectionManager.getHealth()
242
+ if (health.consecutiveFailures > 3) {
243
+ console.warn("XMTP connection degraded")
244
+ }
245
+ }, 60000)
246
+ ```
247
+
248
+ ### 4. Use Environment Variables
249
+ ```typescript
250
+ // Always use the project's environment wrapper
251
+ pnpm with-env [your-command]
252
+ ```
253
+
254
+ ## πŸ§ͺ Testing
255
+
256
+ Run the enhanced connection demo to see health monitoring in action:
257
+
258
+ ```bash
259
+ # Start the demo (runs for 2 minutes showing health checks)
260
+ pnpm with-env pnpm --filter @hybrd/xmtp enhanced:demo
261
+ ```
262
+
263
+ ## πŸ” Debugging
264
+
265
+ Enable debug logging:
266
+
267
+ ```bash
268
+ DEBUG=xmtp-sdk* pnpm with-env pnpm --filter @hybrd/xmtp enhanced:demo
269
+ ```
270
+
271
+ ## πŸ“ˆ Metrics & Monitoring
272
+
273
+ The enhanced client provides detailed metrics:
274
+
275
+ - **Connection Status**: Real-time connection state
276
+ - **Response Times**: Average XMTP response latency
277
+ - **Failure Counts**: Track connection reliability
278
+ - **Reconnection Events**: Monitor stability over time
279
+
280
+ ## 🚨 Migration Guide
281
+
282
+ ### From Basic XMTP Client
283
+
284
+ ```typescript
285
+ // Before
286
+ const client = await createXMTPClient(signer)
287
+
288
+ // After
289
+ const manager = await createXMTPConnectionManager(signer)
290
+ const client = manager.getClient()
291
+
292
+ // Remember to cleanup
293
+ await manager.disconnect()
294
+ ```
295
+
296
+ ### Keep Your Webhook Architecture
297
+
298
+ **No changes needed!** Your QStash webhook system is already providing:
299
+ - βœ… Automatic retries with exponential backoff
300
+ - βœ… Reliable message delivery guarantees
301
+ - βœ… Horizontal scalability
302
+ - βœ… Built-in monitoring and alerting
303
+ - βœ… Dead letter queue handling
304
+
305
+ ## πŸ“š Additional Resources
306
+
307
+ - [XMTP Node SDK Documentation](https://xmtp.org/docs/build/get-started/overview)
308
+ - [QStash Documentation](https://upstash.com/docs/qstash)
309
+ - [Project Architecture](../../ARCHITECTURE.md)
310
+
311
+ ---
312
+
313
+ Your system is already built with production-grade reliability. The enhanced XMTP client provides additional connection management features for edge cases, but your webhook-based architecture is the recommended approach for scalable XMTP integrations! πŸŽ‰
314
+
315
+ # XMTP Package
316
+
317
+ This package provides XMTP client functionality and various resolvers for address, ENS, and basename resolution.
318
+
319
+ ## Resolvers
320
+
321
+ ### Master Resolver
322
+
323
+ The `Resolver` class provides a unified interface for all resolution types:
324
+
325
+ ```typescript
326
+ import { Resolver } from '@hybrd/xmtp/resolver'
327
+ import { createPublicClient, http } from 'viem'
328
+ import { mainnet, base } from 'viem/chains'
329
+
330
+ // Create clients
331
+ const mainnetClient = createPublicClient({
332
+ chain: mainnet,
333
+ transport: http()
334
+ })
335
+
336
+ const baseClient = createPublicClient({
337
+ chain: base,
338
+ transport: http()
339
+ })
340
+
341
+ // Initialize the master resolver
342
+ const resolver = new Resolver({
343
+ xmtpClient: yourXmtpClient,
344
+ mainnetClient,
345
+ baseClient,
346
+ maxCacheSize: 1000,
347
+ cacheTtl: 3600000 // 1 hour
348
+ })
349
+
350
+ // Universal name resolution
351
+ const address = await resolver.resolveName('vitalik.eth')
352
+ const basenameAddress = await resolver.resolveName('myname.base.eth')
353
+
354
+ // Universal reverse resolution
355
+ const name = await resolver.resolveAddressToName('0x...')
356
+
357
+ // Get complete profile (ENS + basename data)
358
+ const profile = await resolver.getCompleteProfile('0x...')
359
+
360
+ // Individual resolver methods are also available
361
+ const ensName = await resolver.resolveENSName('vitalik.eth')
362
+ const basename = await resolver.getBasename('0x...')
363
+ const message = await resolver.findMessage('messageId')
364
+ ```
365
+
366
+ ### Individual Resolvers
367
+
368
+ You can also use individual resolvers directly:
369
+
370
+ - `AddressResolver` - XMTP address resolution
371
+ - `XmtpResolver` - XMTP message and address resolution with advanced features
372
+ - `ENSResolver` - ENS name resolution
373
+ - `BasenameResolver` - Basename resolution for Base network
374
+
375
+ ```typescript
376
+ import { ENSResolver, BasenameResolver } from '@hybrd/xmtp/resolver'
377
+
378
+ const ensResolver = new ENSResolver({ mainnetClient })
379
+ const basenameResolver = new BasenameResolver({ publicClient: baseClient })
380
+ ```
package/biome.jsonc ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3
+ "extends": ["@hybrd/biome"]
4
+ }
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@hybrd/xmtp",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "import": "./src/index.ts",
8
+ "types": "./src/index.ts"
9
+ }
10
+ },
11
+ "dependencies": {
12
+ "@coinbase/coinbase-sdk": "^0.22.0",
13
+ "@xmtp/content-type-group-updated": "2.0.2",
14
+ "@xmtp/content-type-reaction": "2.0.2",
15
+ "@xmtp/content-type-reply": "2.0.2",
16
+ "@xmtp/content-type-text": "2.0.2",
17
+ "@xmtp/content-type-transaction-reference": "2.0.2",
18
+ "@xmtp/content-type-wallet-send-calls": "2.0.0",
19
+ "@xmtp/node-sdk": "^4.0.1",
20
+ "jsonwebtoken": "^9.0.2",
21
+ "uint8arrays": "^5.1.0",
22
+ "viem": "^2.22.17"
23
+ },
24
+ "devDependencies": {
25
+ "@types/jsonwebtoken": "^9.0.7",
26
+ "@types/node": "22.8.6",
27
+ "vitest": "^3.2.4",
28
+ "@hybrd/biome": "0.0.0",
29
+ "@hybrd/tsconfig": "0.0.0"
30
+ },
31
+ "scripts": {
32
+ "clean": "rm -rf .turbo",
33
+ "gen:keys": "tsx scripts/generate-keys.ts",
34
+ "register": "tsx scripts/register-wallet.ts",
35
+ "revoke": "tsx scripts/revoke-installations.ts",
36
+ "revoke:all": "tsx scripts/revoke-all-installations.ts",
37
+ "enhanced:demo": "tsx scripts/enhanced-connection-example.ts",
38
+ "test:messages": "tsx scripts/test-message-reception.ts",
39
+ "refresh:identity": "tsx scripts/refresh-identity.ts",
40
+ "custom:storage": "tsx scripts/custom-storage-example.ts",
41
+ "typecheck": "tsc --noEmit",
42
+ "lint": "biome lint --unsafe",
43
+ "lint:fix": "biome lint --write --unsafe",
44
+ "format": "biome format --write"
45
+ }
46
+ }
@@ -0,0 +1,25 @@
1
+ import { generateEncryptionKeyHex } from "@hybrd/xmtp"
2
+ import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"
3
+
4
+ // Check Node.js version
5
+ const nodeVersion = process.versions.node
6
+ const [major] = nodeVersion?.split(".").map(Number) || [0]
7
+
8
+ if (major && major < 20) {
9
+ console.error("Error: Node.js version 20 or higher is required")
10
+ process.exit(1)
11
+ }
12
+
13
+ console.log("Generating XMTP keys...")
14
+
15
+ const walletKey = generatePrivateKey()
16
+ const account = privateKeyToAccount(walletKey)
17
+ const encryptionKeyHex = generateEncryptionKeyHex()
18
+ const publicKey = account.address
19
+
20
+ console.log("\n# === Generated Keys ===")
21
+ console.log(`# Public Address: ${publicKey}`)
22
+ console.log(`XMTP_WALLET_KEY=${walletKey}`)
23
+ console.log(`XMTP_ENCRYPTION_KEY=${encryptionKeyHex}`)
24
+
25
+ console.log("\nCopy the above environment variables to your .env file")
@@ -0,0 +1,119 @@
1
+ import {
2
+ createXMTPClient,
3
+ logAgentDetails,
4
+ validateEnvironment
5
+ } from "../src/client"
6
+
7
+ /**
8
+ * Refresh XMTP Identity Script
9
+ *
10
+ * This script refreshes the bot's XMTP identity on the production network
11
+ * to resolve association errors and missing identity updates
12
+ */
13
+
14
+ async function refreshXMTPIdentity() {
15
+ console.log("πŸ”„ XMTP Identity Refresh")
16
+ console.log("========================")
17
+
18
+ // Validate environment
19
+ const { XMTP_WALLET_KEY } = validateEnvironment(["XMTP_WALLET_KEY"])
20
+
21
+ if (!XMTP_WALLET_KEY) {
22
+ console.error("❌ XMTP_WALLET_KEY is required")
23
+ process.exit(1)
24
+ }
25
+
26
+ try {
27
+ console.log(`🌐 Environment: ${process.env.XMTP_ENV || "dev"}`)
28
+
29
+ // Step 1: Create client with persistence to force identity refresh
30
+ console.log("\nπŸ“‹ Step 1: Creating client with persistence...")
31
+ const persistentClient = await createXMTPClient(XMTP_WALLET_KEY, {
32
+ persist: true
33
+ })
34
+
35
+ console.log(
36
+ `πŸ”‘ Wallet Address: ${persistentClient.accountIdentifier?.identifier}`
37
+ )
38
+ console.log(`🌐 XMTP Environment: ${process.env.XMTP_ENV || "dev"}`)
39
+
40
+ // Step 2: Force full sync
41
+ console.log("\nπŸ“‹ Step 2: Forcing full conversation sync...")
42
+ await persistentClient.conversations.sync()
43
+
44
+ // Step 3: List conversations
45
+ const conversations = await persistentClient.conversations.list()
46
+ console.log(`πŸ“¬ Found ${conversations.length} conversations`)
47
+
48
+ // Step 4: Display agent details
49
+ console.log("\nπŸ“‹ Step 3: Displaying refreshed identity details...")
50
+ await logAgentDetails(persistentClient)
51
+
52
+ // Step 5: Test identity resolution
53
+ console.log("\nπŸ“‹ Step 4: Testing identity resolution...")
54
+
55
+ if (conversations.length > 0) {
56
+ const testConv = conversations[0]
57
+ if (!testConv) {
58
+ console.log("❌ No valid conversation found")
59
+ return
60
+ }
61
+
62
+ try {
63
+ // Get all participants
64
+ const members = await testConv.members()
65
+ console.log(`πŸ‘₯ Conversation members: ${members.length}`)
66
+
67
+ for (const member of members) {
68
+ console.log(` - Inbox ID: ${member.inboxId}`)
69
+ console.log(` - Installation IDs: ${member.installationIds.length}`)
70
+
71
+ // Try to resolve addresses
72
+ try {
73
+ const inboxState =
74
+ await persistentClient.preferences.inboxStateFromInboxIds([
75
+ member.inboxId
76
+ ])
77
+ if (
78
+ inboxState.length > 0 &&
79
+ inboxState[0] &&
80
+ inboxState[0].identifiers.length > 0
81
+ ) {
82
+ const identifier = inboxState[0]?.identifiers[0]?.identifier
83
+ console.log(` - Address: ${identifier || "Unable to resolve"}`)
84
+ } else {
85
+ console.log(` - Address: Unable to resolve`)
86
+ }
87
+ } catch (error) {
88
+ const err = error as Error
89
+ console.log(` - Address: Error resolving - ${err.message}`)
90
+ }
91
+ }
92
+ } catch (error) {
93
+ const err = error as Error
94
+ console.log(`❌ Error testing conversation: ${err.message}`)
95
+ }
96
+ }
97
+
98
+ console.log("\nβœ… Identity refresh completed successfully!")
99
+ console.log("πŸ”„ Try processing messages again")
100
+ } catch (error) {
101
+ const err = error as Error
102
+ console.error("❌ Identity refresh failed:", err)
103
+
104
+ if (err.message.includes("XMTP_ENCRYPTION_KEY")) {
105
+ console.log("\nπŸ’‘ Add XMTP_ENCRYPTION_KEY to your environment:")
106
+ console.log(" export XMTP_ENCRYPTION_KEY=your_key_here")
107
+ console.log(
108
+ " Or run: pnpm with-env pnpm --filter @hybrd/xmtp refresh:identity"
109
+ )
110
+ }
111
+
112
+ process.exit(1)
113
+ }
114
+ }
115
+
116
+ // Run the refresh
117
+ if (require.main === module) {
118
+ refreshXMTPIdentity().catch(console.error)
119
+ }
@@ -0,0 +1,95 @@
1
+ import { createSigner, createXMTPClient, getDbPath, logAgentDetails, validateEnvironment } from "../src/client"
2
+
3
+ async function registerOnProduction() {
4
+ console.log("πŸš€ Starting XMTP Production Network Registration...")
5
+
6
+ // Validate required environment variables
7
+ const { XMTP_WALLET_KEY } = validateEnvironment([
8
+ "XMTP_WALLET_KEY",
9
+ "XMTP_ENCRYPTION_KEY"
10
+ ])
11
+
12
+ if (!XMTP_WALLET_KEY) {
13
+ console.error("❌ XMTP_WALLET_KEY is required for registration")
14
+ process.exit(1)
15
+ }
16
+
17
+ try {
18
+ console.log("πŸ”‘ Creating signer...")
19
+ const signer = createSigner(XMTP_WALLET_KEY)
20
+
21
+ // Get wallet address for logging
22
+ const identifier = await signer.getIdentifier()
23
+ const address = identifier.identifier
24
+ console.log(`πŸ“ Wallet Address: ${address}`)
25
+
26
+ console.log("🌐 Connecting to XMTP Production Network...")
27
+ console.log("⚠️ This will prompt you to sign messages in your wallet")
28
+ console.log(" - 'XMTP : Authenticate to inbox' message")
29
+ console.log(" - 'Grant messaging access to app' message")
30
+ console.log(" - 'Create inbox' message (if first time)")
31
+
32
+ // Use getDbPath to ensure directory creation and proper path handling
33
+ const dbPath = getDbPath(`production-${address}`)
34
+ console.log(`πŸ“ Database path: ${dbPath}`)
35
+
36
+ // Connect to production network
37
+ const client = await createXMTPClient(XMTP_WALLET_KEY)
38
+
39
+ console.log("βœ… Successfully connected to XMTP Production Network!")
40
+
41
+ // Log client details
42
+ await logAgentDetails(client)
43
+
44
+ console.log("πŸ“‘ Syncing conversations...")
45
+ await client.conversations.sync()
46
+
47
+ const conversations = await client.conversations.list()
48
+ console.log(`πŸ’¬ Found ${conversations.length} existing conversations`)
49
+
50
+ console.log("πŸŽ‰ Registration Complete!")
51
+ console.log(`
52
+ βœ“ Wallet ${address} is now registered on XMTP Production Network
53
+ βœ“ Inbox ID: ${client.inboxId}
54
+ βœ“ Database: production-${address}.db3
55
+ βœ“ Ready to receive messages on production network
56
+
57
+ Next steps:
58
+ 1. Update your environment: XMTP_ENV=production
59
+ 2. Start your listener service
60
+ 3. Share your address for others to message: ${address}
61
+ 4. Test messaging at: https://xmtp.chat/dm/${address}
62
+ `)
63
+ } catch (error) {
64
+ console.error("❌ Registration failed:", error)
65
+
66
+ if (error instanceof Error) {
67
+ if (error.message.includes("User rejected")) {
68
+ console.log(
69
+ "πŸ“ Registration was cancelled. You need to approve the wallet signatures to complete registration."
70
+ )
71
+ } else if (error.message.includes("network")) {
72
+ console.log(
73
+ "🌐 Network connection issue. Please check your internet connection and try again."
74
+ )
75
+ } else if (
76
+ error.message.includes("database") ||
77
+ error.message.includes("Unable to open")
78
+ ) {
79
+ console.log(
80
+ "πŸ’Ύ Database access issue. Please check file permissions and ensure the directory exists."
81
+ )
82
+ } else {
83
+ console.log("πŸ’‘ Make sure your wallet is connected and try again.")
84
+ }
85
+ }
86
+
87
+ process.exit(1)
88
+ }
89
+ }
90
+
91
+ // Run registration
92
+ registerOnProduction().catch((error) => {
93
+ console.error("πŸ’₯ Fatal error during registration:", error)
94
+ process.exit(1)
95
+ })