@hybrd/xmtp 1.0.0 → 1.0.3

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 (45) hide show
  1. package/.cache/tsbuildinfo.json +1 -1
  2. package/.turbo/turbo-build.log +5 -0
  3. package/.turbo/turbo-lint$colon$fix.log +6 -0
  4. package/dist/scripts/generate-keys.d.ts +1 -0
  5. package/dist/scripts/generate-keys.js +19 -0
  6. package/dist/scripts/refresh-identity.d.ts +1 -0
  7. package/dist/scripts/refresh-identity.js +93 -0
  8. package/dist/scripts/register-wallet.d.ts +1 -0
  9. package/dist/scripts/register-wallet.js +75 -0
  10. package/dist/scripts/revoke-all-installations.d.ts +2 -0
  11. package/dist/scripts/revoke-all-installations.js +68 -0
  12. package/dist/scripts/revoke-installations.d.ts +2 -0
  13. package/dist/scripts/revoke-installations.js +62 -0
  14. package/dist/src/abi/l2_resolver.d.ts +992 -0
  15. package/dist/src/abi/l2_resolver.js +699 -0
  16. package/dist/src/client.d.ts +76 -0
  17. package/dist/src/client.js +709 -0
  18. package/dist/src/constants.d.ts +3 -0
  19. package/dist/src/constants.js +6 -0
  20. package/dist/src/index.d.ts +22 -0
  21. package/dist/src/index.js +46 -0
  22. package/dist/src/lib/message-listener.d.ts +69 -0
  23. package/dist/src/lib/message-listener.js +235 -0
  24. package/dist/src/lib/message-listener.test.d.ts +1 -0
  25. package/dist/src/lib/message-listener.test.js +303 -0
  26. package/dist/src/lib/subjects.d.ts +24 -0
  27. package/dist/src/lib/subjects.js +68 -0
  28. package/dist/src/resolver/address-resolver.d.ts +57 -0
  29. package/dist/src/resolver/address-resolver.js +168 -0
  30. package/dist/src/resolver/basename-resolver.d.ts +134 -0
  31. package/dist/src/resolver/basename-resolver.js +409 -0
  32. package/dist/src/resolver/ens-resolver.d.ts +95 -0
  33. package/dist/src/resolver/ens-resolver.js +249 -0
  34. package/dist/src/resolver/index.d.ts +1 -0
  35. package/dist/src/resolver/index.js +1 -0
  36. package/dist/src/resolver/resolver.d.ts +162 -0
  37. package/dist/src/resolver/resolver.js +238 -0
  38. package/dist/src/resolver/xmtp-resolver.d.ts +95 -0
  39. package/dist/src/resolver/xmtp-resolver.js +297 -0
  40. package/dist/src/service-client.d.ts +77 -0
  41. package/dist/src/service-client.js +198 -0
  42. package/dist/src/types.d.ts +123 -0
  43. package/dist/src/types.js +5 -0
  44. package/package.json +5 -4
  45. package/tsconfig.json +3 -1
@@ -0,0 +1,5 @@
1
+
2
+ 
3
+ > @hybrd/xmtp@1.0.3 build /Users/ian/Projects/01/hybrid/packages/xmtp
4
+ > tsc
5
+
@@ -0,0 +1,6 @@
1
+
2
+ 
3
+ > @hybrd/xmtp@1.0.2 lint:fix /Users/ian/Projects/01/hybrid/packages/xmtp
4
+ > biome lint --write --unsafe
5
+
6
+ Checked 23 files in 24ms. No fixes applied.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ import { generateEncryptionKeyHex } from "@hybrd/xmtp";
2
+ import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
3
+ // Check Node.js version
4
+ const nodeVersion = process.versions.node;
5
+ const [major] = nodeVersion?.split(".").map(Number) || [0];
6
+ if (major && major < 20) {
7
+ console.error("Error: Node.js version 20 or higher is required");
8
+ process.exit(1);
9
+ }
10
+ console.log("Generating XMTP keys...");
11
+ const walletKey = generatePrivateKey();
12
+ const account = privateKeyToAccount(walletKey);
13
+ const encryptionKeyHex = generateEncryptionKeyHex();
14
+ const publicKey = account.address;
15
+ console.log("\n# === Generated Keys ===");
16
+ console.log(`# Public Address: ${publicKey}`);
17
+ console.log(`XMTP_WALLET_KEY=${walletKey}`);
18
+ console.log(`XMTP_ENCRYPTION_KEY=${encryptionKeyHex}`);
19
+ console.log("\nCopy the above environment variables to your .env file");
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,93 @@
1
+ import { createXMTPClient, logAgentDetails, validateEnvironment } from "../src/client";
2
+ /**
3
+ * Refresh XMTP Identity Script
4
+ *
5
+ * This script refreshes the bot's XMTP identity on the production network
6
+ * to resolve association errors and missing identity updates
7
+ */
8
+ async function refreshXMTPIdentity() {
9
+ console.log("šŸ”„ XMTP Identity Refresh");
10
+ console.log("========================");
11
+ // Validate environment
12
+ const { XMTP_WALLET_KEY } = validateEnvironment(["XMTP_WALLET_KEY"]);
13
+ if (!XMTP_WALLET_KEY) {
14
+ console.error("āŒ XMTP_WALLET_KEY is required");
15
+ process.exit(1);
16
+ }
17
+ try {
18
+ console.log(`🌐 Environment: ${process.env.XMTP_ENV || "dev"}`);
19
+ // Step 1: Create client with persistence to force identity refresh
20
+ console.log("\nšŸ“‹ Step 1: Creating client with persistence...");
21
+ const persistentClient = await createXMTPClient(XMTP_WALLET_KEY, {
22
+ persist: true
23
+ });
24
+ console.log(`šŸ”‘ Wallet Address: ${persistentClient.accountIdentifier?.identifier}`);
25
+ console.log(`🌐 XMTP Environment: ${process.env.XMTP_ENV || "dev"}`);
26
+ // Step 2: Force full sync
27
+ console.log("\nšŸ“‹ Step 2: Forcing full conversation sync...");
28
+ await persistentClient.conversations.sync();
29
+ // Step 3: List conversations
30
+ const conversations = await persistentClient.conversations.list();
31
+ console.log(`šŸ“¬ Found ${conversations.length} conversations`);
32
+ // Step 4: Display agent details
33
+ console.log("\nšŸ“‹ Step 3: Displaying refreshed identity details...");
34
+ await logAgentDetails(persistentClient);
35
+ // Step 5: Test identity resolution
36
+ console.log("\nšŸ“‹ Step 4: Testing identity resolution...");
37
+ if (conversations.length > 0) {
38
+ const testConv = conversations[0];
39
+ if (!testConv) {
40
+ console.log("āŒ No valid conversation found");
41
+ return;
42
+ }
43
+ try {
44
+ // Get all participants
45
+ const members = await testConv.members();
46
+ console.log(`šŸ‘„ Conversation members: ${members.length}`);
47
+ for (const member of members) {
48
+ console.log(` - Inbox ID: ${member.inboxId}`);
49
+ console.log(` - Installation IDs: ${member.installationIds.length}`);
50
+ // Try to resolve addresses
51
+ try {
52
+ const inboxState = await persistentClient.preferences.inboxStateFromInboxIds([
53
+ member.inboxId
54
+ ]);
55
+ if (inboxState.length > 0 &&
56
+ inboxState[0] &&
57
+ inboxState[0].identifiers.length > 0) {
58
+ const identifier = inboxState[0]?.identifiers[0]?.identifier;
59
+ console.log(` - Address: ${identifier || "Unable to resolve"}`);
60
+ }
61
+ else {
62
+ console.log(` - Address: Unable to resolve`);
63
+ }
64
+ }
65
+ catch (error) {
66
+ const err = error;
67
+ console.log(` - Address: Error resolving - ${err.message}`);
68
+ }
69
+ }
70
+ }
71
+ catch (error) {
72
+ const err = error;
73
+ console.log(`āŒ Error testing conversation: ${err.message}`);
74
+ }
75
+ }
76
+ console.log("\nāœ… Identity refresh completed successfully!");
77
+ console.log("šŸ”„ Try processing messages again");
78
+ }
79
+ catch (error) {
80
+ const err = error;
81
+ console.error("āŒ Identity refresh failed:", err);
82
+ if (err.message.includes("XMTP_ENCRYPTION_KEY")) {
83
+ console.log("\nšŸ’” Add XMTP_ENCRYPTION_KEY to your environment:");
84
+ console.log(" export XMTP_ENCRYPTION_KEY=your_key_here");
85
+ console.log(" Or run: pnpm with-env pnpm --filter @hybrd/xmtp refresh:identity");
86
+ }
87
+ process.exit(1);
88
+ }
89
+ }
90
+ // Run the refresh
91
+ if (require.main === module) {
92
+ refreshXMTPIdentity().catch(console.error);
93
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,75 @@
1
+ import { createSigner, createXMTPClient, getDbPath, logAgentDetails, validateEnvironment } from "../src/client";
2
+ async function registerOnProduction() {
3
+ console.log("šŸš€ Starting XMTP Production Network Registration...");
4
+ // Validate required environment variables
5
+ const { XMTP_WALLET_KEY } = validateEnvironment([
6
+ "XMTP_WALLET_KEY",
7
+ "XMTP_ENCRYPTION_KEY"
8
+ ]);
9
+ if (!XMTP_WALLET_KEY) {
10
+ console.error("āŒ XMTP_WALLET_KEY is required for registration");
11
+ process.exit(1);
12
+ }
13
+ try {
14
+ console.log("šŸ”‘ Creating signer...");
15
+ const signer = createSigner(XMTP_WALLET_KEY);
16
+ // Get wallet address for logging
17
+ const identifier = await signer.getIdentifier();
18
+ const address = identifier.identifier;
19
+ console.log(`šŸ“ Wallet Address: ${address}`);
20
+ console.log("🌐 Connecting to XMTP Production Network...");
21
+ console.log("āš ļø This will prompt you to sign messages in your wallet");
22
+ console.log(" - 'XMTP : Authenticate to inbox' message");
23
+ console.log(" - 'Grant messaging access to app' message");
24
+ console.log(" - 'Create inbox' message (if first time)");
25
+ // Use getDbPath to ensure directory creation and proper path handling
26
+ const dbPath = getDbPath(`production-${address}`);
27
+ console.log(`šŸ“ Database path: ${dbPath}`);
28
+ // Connect to production network
29
+ const client = await createXMTPClient(XMTP_WALLET_KEY);
30
+ console.log("āœ… Successfully connected to XMTP Production Network!");
31
+ // Log client details
32
+ await logAgentDetails(client);
33
+ console.log("šŸ“” Syncing conversations...");
34
+ await client.conversations.sync();
35
+ const conversations = await client.conversations.list();
36
+ console.log(`šŸ’¬ Found ${conversations.length} existing conversations`);
37
+ console.log("šŸŽ‰ Registration Complete!");
38
+ console.log(`
39
+ āœ“ Wallet ${address} is now registered on XMTP Production Network
40
+ āœ“ Inbox ID: ${client.inboxId}
41
+ āœ“ Database: production-${address}.db3
42
+ āœ“ Ready to receive messages on production network
43
+
44
+ Next steps:
45
+ 1. Update your environment: XMTP_ENV=production
46
+ 2. Start your listener service
47
+ 3. Share your address for others to message: ${address}
48
+ 4. Test messaging at: https://xmtp.chat/dm/${address}
49
+ `);
50
+ }
51
+ catch (error) {
52
+ console.error("āŒ Registration failed:", error);
53
+ if (error instanceof Error) {
54
+ if (error.message.includes("User rejected")) {
55
+ console.log("šŸ“ Registration was cancelled. You need to approve the wallet signatures to complete registration.");
56
+ }
57
+ else if (error.message.includes("network")) {
58
+ console.log("🌐 Network connection issue. Please check your internet connection and try again.");
59
+ }
60
+ else if (error.message.includes("database") ||
61
+ error.message.includes("Unable to open")) {
62
+ console.log("šŸ’¾ Database access issue. Please check file permissions and ensure the directory exists.");
63
+ }
64
+ else {
65
+ console.log("šŸ’” Make sure your wallet is connected and try again.");
66
+ }
67
+ }
68
+ process.exit(1);
69
+ }
70
+ }
71
+ // Run registration
72
+ registerOnProduction().catch((error) => {
73
+ console.error("šŸ’„ Fatal error during registration:", error);
74
+ process.exit(1);
75
+ });
@@ -0,0 +1,2 @@
1
+ declare function revokeAllInstallations(): Promise<void>;
2
+ export { revokeAllInstallations };
@@ -0,0 +1,68 @@
1
+ import { createXMTPClient, validateEnvironment } from "../src/client";
2
+ import { revokeOldInstallations } from "./revoke-installations";
3
+ async function revokeAllInstallations() {
4
+ console.log("šŸ”„ Revoking ALL XMTP Installations");
5
+ console.log("==================================");
6
+ // Validate environment
7
+ const { XMTP_WALLET_KEY } = validateEnvironment(["XMTP_WALLET_KEY"]);
8
+ if (!XMTP_WALLET_KEY) {
9
+ console.error("āŒ XMTP_WALLET_KEY is required");
10
+ process.exit(1);
11
+ }
12
+ try {
13
+ console.log(`🌐 Environment: ${process.env.XMTP_ENV || "dev"}`);
14
+ // Try to create client to get current inbox ID
15
+ try {
16
+ const client = await createXMTPClient(XMTP_WALLET_KEY);
17
+ const currentInboxId = client.inboxId;
18
+ console.log(`šŸ“§ Current Inbox ID: ${currentInboxId}`);
19
+ console.log("šŸ”§ Attempting to revoke all installations for this inbox...");
20
+ const success = await revokeOldInstallations(client.signer, currentInboxId);
21
+ // Create signer
22
+ console.log(`šŸ”‘ Wallet Address: ${client.accountIdentifier?.identifier}`);
23
+ if (success) {
24
+ console.log("āœ… Successfully revoked all installations");
25
+ }
26
+ else {
27
+ console.log("āŒ Failed to revoke installations");
28
+ process.exit(1);
29
+ }
30
+ }
31
+ catch (clientError) {
32
+ console.log("āš ļø Could not create client, attempting alternative approach...");
33
+ // If we can't create a client, it might be because of installation limits
34
+ // Try to manually construct possible inbox IDs or use a different approach
35
+ console.log("šŸ” This might indicate installation limit issues");
36
+ console.log("šŸ’” You may need to:");
37
+ console.log(" 1. Wait a few minutes and try again");
38
+ console.log(" 2. Use the specific inbox ID if you know it");
39
+ console.log(" 3. Try switching XMTP environments (dev <-> production)");
40
+ throw clientError;
41
+ }
42
+ }
43
+ catch (error) {
44
+ console.error("šŸ’„ Error revoking installations:", error);
45
+ if (error instanceof Error) {
46
+ if (error.message.includes("5/5 installations")) {
47
+ console.log("\nšŸ’” Installation limit reached. Possible solutions:");
48
+ console.log(" 1. Wait 24 hours for installations to expire");
49
+ console.log(" 2. Try switching XMTP environments (dev <-> production)");
50
+ console.log(" 3. Use a different wallet");
51
+ }
52
+ else if (error.message.includes("Missing existing member")) {
53
+ console.log("\nšŸ’” This inbox ID may not exist or may be on a different environment");
54
+ console.log(" 1. Check if you're using the correct XMTP_ENV (dev vs production)");
55
+ console.log(" 2. Verify the inbox ID is correct");
56
+ }
57
+ }
58
+ process.exit(1);
59
+ }
60
+ }
61
+ // Run if called directly
62
+ if (import.meta.url === `file://${process.argv[1]}`) {
63
+ revokeAllInstallations().catch((error) => {
64
+ console.error("šŸ’„ Fatal error:", error);
65
+ process.exit(1);
66
+ });
67
+ }
68
+ export { revokeAllInstallations };
@@ -0,0 +1,2 @@
1
+ import { Signer } from "../src/index";
2
+ export declare function revokeOldInstallations(signer: Signer, inboxId?: string): Promise<boolean>;
@@ -0,0 +1,62 @@
1
+ import { Client, createSigner } from "../src/index";
2
+ // Function to revoke old installations when hitting the limit
3
+ export async function revokeOldInstallations(signer, inboxId) {
4
+ console.log("šŸ”§ Attempting to revoke old installations...");
5
+ try {
6
+ // If we don't have the inboxId, we need to extract it from a temporary client attempt
7
+ if (!inboxId) {
8
+ console.log("ā„¹ļø No inboxId provided, cannot revoke installations");
9
+ return false;
10
+ }
11
+ const inboxStates = await Client.inboxStateFromInboxIds([inboxId], process.env.XMTP_ENV);
12
+ if (!inboxStates[0]) {
13
+ console.log("āŒ No inbox state found for the provided inboxId");
14
+ return false;
15
+ }
16
+ const toRevokeInstallationBytes = inboxStates[0].installations.map((i) => i.bytes);
17
+ await Client.revokeInstallations(signer, inboxId, toRevokeInstallationBytes, process.env.XMTP_ENV);
18
+ const resultingStates = await Client.inboxStateFromInboxIds([inboxId], process.env.XMTP_ENV);
19
+ console.log(`šŸ“‹ Revoked installations: ${toRevokeInstallationBytes.length} installations`);
20
+ console.log(`šŸ“‹ Resulting state: ${resultingStates[0]?.installations.length || 0} installations`);
21
+ return true;
22
+ }
23
+ catch (error) {
24
+ console.error("āŒ Error during installation revocation:", error);
25
+ return false;
26
+ }
27
+ }
28
+ // CLI script to revoke installations
29
+ async function main() {
30
+ const { XMTP_WALLET_KEY } = process.env;
31
+ const inboxId = process.argv[2];
32
+ if (!XMTP_WALLET_KEY) {
33
+ console.error("āŒ XMTP_WALLET_KEY is required");
34
+ process.exit(1);
35
+ }
36
+ if (!inboxId) {
37
+ console.error("āŒ InboxID is required as CLI argument");
38
+ console.error("Usage: tsx revoke-installations.ts <inboxId>");
39
+ process.exit(1);
40
+ }
41
+ const signer = createSigner(XMTP_WALLET_KEY);
42
+ const identifier = await signer.getIdentifier();
43
+ const address = identifier.identifier;
44
+ console.log(`šŸ”‘ Wallet Address: ${address}`);
45
+ console.log(`šŸ“‹ Inbox ID: ${inboxId}`);
46
+ // Try to revoke installations
47
+ const success = await revokeOldInstallations(signer, inboxId);
48
+ if (success) {
49
+ console.log("āœ… Successfully revoked installations");
50
+ }
51
+ else {
52
+ console.log("āŒ Failed to revoke installations");
53
+ process.exit(1);
54
+ }
55
+ }
56
+ // Run if called directly
57
+ if (import.meta.url === `file://${process.argv[1]}`) {
58
+ main().catch((error) => {
59
+ console.error("šŸ’„ Fatal error:", error);
60
+ process.exit(1);
61
+ });
62
+ }