@hybrd/xmtp 1.3.2 → 1.4.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.
Files changed (38) hide show
  1. package/README.md +41 -7
  2. package/dist/index.cjs +415 -3085
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +12 -828
  5. package/dist/index.d.ts +12 -828
  6. package/dist/index.js +416 -3056
  7. package/dist/index.js.map +1 -1
  8. package/package.json +18 -5
  9. package/src/client.ts +23 -135
  10. package/src/index.ts +28 -81
  11. package/src/index.ts.old +145 -0
  12. package/src/lib/jwt.ts +45 -13
  13. package/src/lib/{message-listener.test.ts → message-listener.test.ts.old} +1 -1
  14. package/src/lib/subjects.ts +6 -5
  15. package/src/plugin.filters.test.ts +158 -0
  16. package/src/plugin.ts +456 -23
  17. package/src/resolver/address-resolver.ts +217 -211
  18. package/src/resolver/basename-resolver.ts +6 -5
  19. package/src/resolver/ens-resolver.ts +15 -14
  20. package/src/resolver/resolver.ts +3 -2
  21. package/src/resolver/xmtp-resolver.ts +10 -9
  22. package/src/{service-client.ts → service-client.ts.old} +26 -3
  23. package/src/types.ts +9 -157
  24. package/src/types.ts.old +157 -0
  25. package/.cache/tsbuildinfo.json +0 -1
  26. package/.turbo/turbo-build.log +0 -45
  27. package/.turbo/turbo-lint$colon$fix.log +0 -6
  28. package/.turbo/turbo-typecheck.log +0 -5
  29. package/biome.jsonc +0 -4
  30. package/scripts/generate-keys.ts +0 -25
  31. package/scripts/refresh-identity.ts +0 -119
  32. package/scripts/register-wallet.ts +0 -95
  33. package/scripts/revoke-all-installations.ts +0 -91
  34. package/scripts/revoke-installations.ts +0 -94
  35. package/src/endpoints.ts +0 -306
  36. package/tsconfig.json +0 -9
  37. package/tsup.config.ts +0 -14
  38. /package/src/lib/{message-listener.ts → message-listener.ts.old} +0 -0
@@ -1,45 +0,0 @@
1
-
2
- 
3
- > @hybrd/xmtp@1.3.2 build /Users/ian/Projects/01/hybrid/packages/xmtp
4
- > tsup
5
-
6
- CLI Building entry: {"index":"src/index.ts"}
7
- CLI Using tsconfig: tsconfig.json
8
- CLI tsup v8.5.0
9
- CLI Using tsup config: /Users/ian/Projects/01/hybrid/packages/xmtp/tsup.config.ts
10
- CLI Target: es2020
11
- CLI Cleaning output folder
12
- CJS Build start
13
- ESM Build start
14
-
15
- [5:19:03 PM]  WARN  ▲ [WARNING] "import.meta" is not available with the "cjs" output format and will be empty [empty-import-meta]
16
-
17
- scripts/revoke-installations.ts:89:4:
18
-  89 │ if (import.meta.url === file://${process.argv[1]}) {
19
- ╵ ~~~~~~~~~~~
20
-
21
- You need to set the output format to "esm" for "import.meta" to work correctly.
22
-
23
-
24
-
25
-
26
- [5:19:03 PM]  WARN  ▲ [WARNING] "import.meta" is not available with the "cjs" output format and will be empty [empty-import-meta]
27
-
28
- src/client.ts:21:33:
29
-  21 │ const __filename = fileURLToPath(import.meta.url)
30
- ╵ ~~~~~~~~~~~
31
-
32
- You need to set the output format to "esm" for "import.meta" to work correctly.
33
-
34
-
35
-
36
- ESM dist/index.js 114.52 KB
37
- ESM dist/index.js.map 218.83 KB
38
- ESM ⚡️ Build success in 126ms
39
- CJS dist/index.cjs 119.83 KB
40
- CJS dist/index.cjs.map 219.34 KB
41
- CJS ⚡️ Build success in 126ms
42
- DTS Build start
43
- DTS ⚡️ Build success in 3917ms
44
- DTS dist/index.d.cts 29.23 KB
45
- DTS dist/index.d.ts 29.23 KB
@@ -1,6 +0,0 @@
1
-
2
- 
3
- > @hybrd/xmtp@1.2.8 lint:fix /Users/ian/Projects/01/hybrid/packages/xmtp
4
- > biome lint --write --unsafe
5
-
6
- Checked 27 files in 18ms. No fixes applied.
@@ -1,5 +0,0 @@
1
-
2
- 
3
- > @hybrd/xmtp@1.3.1 typecheck /Users/ian/Projects/01/hybrid/packages/xmtp
4
- > tsc --noEmit
5
-
package/biome.jsonc DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3
- "extends": ["@config/biome"]
4
- }
@@ -1,25 +0,0 @@
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")
@@ -1,119 +0,0 @@
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
- }
@@ -1,95 +0,0 @@
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
- })
@@ -1,91 +0,0 @@
1
- import { Signer } from "@xmtp/node-sdk"
2
- import { createXMTPClient, validateEnvironment } from "../src/client"
3
- import { revokeOldInstallations } from "./revoke-installations"
4
-
5
- async function revokeAllInstallations() {
6
- console.log("🔄 Revoking ALL XMTP Installations")
7
- console.log("==================================")
8
-
9
- // Validate environment
10
- const { XMTP_WALLET_KEY } = validateEnvironment(["XMTP_WALLET_KEY"])
11
-
12
- if (!XMTP_WALLET_KEY) {
13
- console.error("❌ XMTP_WALLET_KEY is required")
14
- process.exit(1)
15
- }
16
-
17
- try {
18
- console.log(`🌐 Environment: ${process.env.XMTP_ENV || "dev"}`)
19
-
20
- // Try to create client to get current inbox ID
21
- try {
22
- const client = await createXMTPClient(XMTP_WALLET_KEY)
23
- const currentInboxId = client.inboxId
24
-
25
- console.log(`📧 Current Inbox ID: ${currentInboxId}`)
26
- console.log("🔧 Attempting to revoke all installations for this inbox...")
27
-
28
- const success = await revokeOldInstallations(
29
- client.signer as Signer,
30
- currentInboxId
31
- )
32
-
33
- // Create signer
34
- console.log(`🔑 Wallet Address: ${client.accountIdentifier?.identifier}`)
35
-
36
- if (success) {
37
- console.log("✅ Successfully revoked all installations")
38
- } else {
39
- console.log("❌ Failed to revoke installations")
40
- process.exit(1)
41
- }
42
- } catch (clientError) {
43
- console.log(
44
- "⚠️ Could not create client, attempting alternative approach..."
45
- )
46
-
47
- // If we can't create a client, it might be because of installation limits
48
- // Try to manually construct possible inbox IDs or use a different approach
49
- console.log("🔍 This might indicate installation limit issues")
50
- console.log("💡 You may need to:")
51
- console.log(" 1. Wait a few minutes and try again")
52
- console.log(" 2. Use the specific inbox ID if you know it")
53
- console.log(" 3. Try switching XMTP environments (dev <-> production)")
54
-
55
- throw clientError
56
- }
57
- } catch (error) {
58
- console.error("💥 Error revoking installations:", error)
59
-
60
- if (error instanceof Error) {
61
- if (error.message.includes("5/5 installations")) {
62
- console.log("\n💡 Installation limit reached. Possible solutions:")
63
- console.log(" 1. Wait 24 hours for installations to expire")
64
- console.log(
65
- " 2. Try switching XMTP environments (dev <-> production)"
66
- )
67
- console.log(" 3. Use a different wallet")
68
- } else if (error.message.includes("Missing existing member")) {
69
- console.log(
70
- "\n💡 This inbox ID may not exist or may be on a different environment"
71
- )
72
- console.log(
73
- " 1. Check if you're using the correct XMTP_ENV (dev vs production)"
74
- )
75
- console.log(" 2. Verify the inbox ID is correct")
76
- }
77
- }
78
-
79
- process.exit(1)
80
- }
81
- }
82
-
83
- // Run if called directly
84
- if (import.meta.url === `file://${process.argv[1]}`) {
85
- revokeAllInstallations().catch((error) => {
86
- console.error("💥 Fatal error:", error)
87
- process.exit(1)
88
- })
89
- }
90
-
91
- export { revokeAllInstallations }
@@ -1,94 +0,0 @@
1
- import { Client, Signer, createSigner } from "../src/index"
2
-
3
- // Function to revoke old installations when hitting the limit
4
- export async function revokeOldInstallations(signer: Signer, inboxId?: string) {
5
- console.log("🔧 Attempting to revoke old installations...")
6
-
7
- try {
8
- // If we don't have the inboxId, we need to extract it from a temporary client attempt
9
- if (!inboxId) {
10
- console.log("ℹ️ No inboxId provided, cannot revoke installations")
11
- return false
12
- }
13
-
14
- const inboxStates = await Client.inboxStateFromInboxIds(
15
- [inboxId],
16
- process.env.XMTP_ENV as "dev" | "production"
17
- )
18
-
19
- if (!inboxStates[0]) {
20
- console.log("❌ No inbox state found for the provided inboxId")
21
- return false
22
- }
23
-
24
- const toRevokeInstallationBytes = inboxStates[0].installations.map(
25
- (i) => i.bytes
26
- )
27
-
28
- await Client.revokeInstallations(
29
- signer,
30
- inboxId,
31
- toRevokeInstallationBytes,
32
- process.env.XMTP_ENV as "dev" | "production"
33
- )
34
-
35
- const resultingStates = await Client.inboxStateFromInboxIds(
36
- [inboxId],
37
- process.env.XMTP_ENV as "dev" | "production"
38
- )
39
-
40
- console.log(
41
- `📋 Revoked installations: ${toRevokeInstallationBytes.length} installations`
42
- )
43
- console.log(
44
- `📋 Resulting state: ${resultingStates[0]?.installations.length || 0} installations`
45
- )
46
-
47
- return true
48
- } catch (error) {
49
- console.error("❌ Error during installation revocation:", error)
50
- return false
51
- }
52
- }
53
-
54
- // CLI script to revoke installations
55
- async function main() {
56
- const { XMTP_WALLET_KEY } = process.env
57
- const inboxId = process.argv[2]
58
-
59
- if (!XMTP_WALLET_KEY) {
60
- console.error("❌ XMTP_WALLET_KEY is required")
61
- process.exit(1)
62
- }
63
-
64
- if (!inboxId) {
65
- console.error("❌ InboxID is required as CLI argument")
66
- console.error("Usage: tsx revoke-installations.ts <inboxId>")
67
- process.exit(1)
68
- }
69
-
70
- const signer = createSigner(XMTP_WALLET_KEY)
71
- const identifier = await signer.getIdentifier()
72
- const address = identifier.identifier
73
-
74
- console.log(`🔑 Wallet Address: ${address}`)
75
- console.log(`📋 Inbox ID: ${inboxId}`)
76
-
77
- // Try to revoke installations
78
- const success = await revokeOldInstallations(signer, inboxId)
79
-
80
- if (success) {
81
- console.log("✅ Successfully revoked installations")
82
- } else {
83
- console.log("❌ Failed to revoke installations")
84
- process.exit(1)
85
- }
86
- }
87
-
88
- // Run if called directly
89
- if (import.meta.url === `file://${process.argv[1]}`) {
90
- main().catch((error) => {
91
- console.error("💥 Fatal error:", error)
92
- process.exit(1)
93
- })
94
- }