diff --git a/README.md b/README.md index 314b6af..247eba6 100644 --- a/README.md +++ b/README.md @@ -26,11 +26,11 @@ ENCRYPTION_KEY= # encryption key for the local database You can generate random keys with the following command: ```bash -yarn gen:keys +yarn gen:keys ``` -> [!WARNING] -> Running the `gen:keys` script will overwrite the existing `.env` file. +> [!TIP] +> Running the `gen:keys` or `gen:keys ` command will append keys to your existing `.env` file. ### Fetching messages @@ -52,31 +52,51 @@ await client.conversations.sync(); await client.conversations.messages(); ``` -### Working with addresses +### Conversations can be of type `Group` or `Dm` -Conversations in XMTP can be `DMs` or `Groups`. The underlying technicalities are the same, but DMs are essentially groups locked between two users that can be reused - basically a fixed group of 2. This is how MLS works. - -Each member of a conversation has the following properties: +The new `Group` and `Dm` classes extend the `Conversation` class and provide specific functionality based on the conversation type. ```tsx -inboxId: string; // unique identifier from the XMTP network -accountAddresses: Array; // ethereum network addresses -installationIds: Array; // How many active devices the user has -permissionLevel: PermissionLevel; // In the context of a group, if it's admin or not -consentState: ConsentState; // If it's blocked or allowed via consent +const conversations: (Group | Dm)[] = await client.conversations.list(); + +for (const conversation of conversations) { + // narrow the type to Group to access the group name + if (conversation instanceof Group) { + console.log(group.name); + } + + // narrow the type to Dm to access the peer inboxId + if (conversation instanceof Dm) { + console.log(conversation.peerInboxId); + } +} ``` -To fetch an ethereum address in a DM, you can use a script like the following: +## Working with addresses + +Because XMTP is interoperable, you may interact with inboxes that are not on your app. In these scenarios, you will need to find the appropriate inbox ID or address. ```tsx -const address = - (await group.members?.find( - (member: any) => member.inboxId === dm.dmPeerInboxId, - )?.accountAddresses[0]) || ""; -``` +// get an inbox ID from an address +const inboxId = await getInboxIdForIdentifier({ + identifier: "0x1234567890abcdef1234567890abcdef12345678", + identifierKind: IdentifierKind.Ethereum, +}); + +// find the addresses associated with an inbox ID +const inboxState = await client.inboxStateFromInboxIds([inboxId]); + +interface InboxState { + inboxId: string; + recoveryIdentifier: Identifier; + installations: Installation[]; + identifiers: Identifier[]; +} -> [!WARNING] -> XMTP is working on integrating passkeys as a pillar of identity. Expect a breaking change soon as XMTP prepares for the first v3 stable release. +const addresses = inboxState.identifiers + .filter((i) => i.identifierKind === IdentifierKind.Ethereum) + .map((i) => i.identifier); +``` ## Web inbox @@ -97,5 +117,6 @@ Interact with the XMTP network using [xmtp.chat](https://xmtp.chat), the officia Examples integrating XMTP with external libraries from the ecosystem - [grok](/integrations/grok/): Integrate XMTP to the Grok API +- [gaia](/integrations/gaia/): Integrate XMTP to the Gaia API > See all the available [integrations](/integrations/). diff --git a/examples/gated-group/README.md b/examples/gated-group/README.md index a2e4633..987a898 100644 --- a/examples/gated-group/README.md +++ b/examples/gated-group/README.md @@ -20,9 +20,6 @@ You can generate random keys with the following command: yarn gen:keys ``` -> [!WARNING] -> Running the `gen:keys` script will overwrite the existing `.env` file. - ## Start the XMTP agent Start your XMTP client and begin listening to messages. The bot responds to the following commands: @@ -33,7 +30,7 @@ Start your XMTP client and begin listening to messages. The bot responds to the if (message.content === "/create") { console.log("Creating group"); const group = await client.conversations.newGroup([]); - await group.addMembersByInboxId([message.senderInboxId]); + await group.addMembers([message.senderInboxId]); await group.addSuperAdmin(message.senderInboxId); await conversation.send( diff --git a/examples/gated-group/index.ts b/examples/gated-group/index.ts index 47f06eb..8e5aec9 100644 --- a/examples/gated-group/index.ts +++ b/examples/gated-group/index.ts @@ -1,4 +1,4 @@ -import { Client, type XmtpEnv } from "@xmtp/node-sdk"; +import { Client, type Group, type XmtpEnv } from "@xmtp/node-sdk"; import { Alchemy, Network } from "alchemy-sdk"; import { createSigner, getEncryptionKeyFromHex } from "@/helpers"; @@ -36,8 +36,11 @@ async function main() { console.log("Syncing conversations..."); await client.conversations.sync(); + const identifier = await signer.getIdentifier(); + const address = identifier.identifier; + console.log( - `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}`, + `Agent initialized on ${address}\nSend a message on http://xmtp.chat/dm/${address}`, ); console.log("Waiting for messages..."); @@ -56,8 +59,8 @@ async function main() { `Received message: ${message.content as string} by ${message.senderInboxId}`, ); - const conversation = client.conversations.getConversationById( - message.conversationId, + const conversation = client.conversations.getDmByInboxId( + message.senderInboxId, ); if (!conversation) { @@ -74,7 +77,7 @@ async function main() { const group = await client.conversations.newGroup([]); console.log("Group created", group.id); // First add the sender to the group - await group.addMembersByInboxId([message.senderInboxId]); + await group.addMembers([message.senderInboxId]); // Then make the sender a super admin await group.addSuperAdmin(message.senderInboxId); console.log( @@ -98,7 +101,7 @@ async function main() { await conversation.send("Please provide a group id"); return; } - const group = client.conversations.getConversationById(groupId); + const group = await client.conversations.getConversationById(groupId); if (!group) { await conversation.send("Please provide a valid group id"); return; @@ -113,7 +116,7 @@ async function main() { console.log("User can't be added to the group"); return; } else { - await group.addMembers([walletAddress]); + await (group as Group).addMembers([walletAddress]); await conversation.send( `User added to the group\n- Group ID: ${groupId}\n- Wallet Address: ${walletAddress}`, ); diff --git a/examples/gm/README.md b/examples/gm/README.md index d447a4b..dfba002 100644 --- a/examples/gm/README.md +++ b/examples/gm/README.md @@ -36,8 +36,10 @@ async function main() { /* Sync the conversations from the network to update the local db */ await client.conversations.sync(); + const identifier = await signer.getIdentifier(); + const address = identifier.identifier; console.log( - `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}?env=${env}`, + `Agent initialized on ${address}\nSend a message on http://xmtp.chat/dm/${address}`, ); console.log("Waiting for messages..."); diff --git a/examples/gm/index.ts b/examples/gm/index.ts index e5e85fa..365e4bf 100644 --- a/examples/gm/index.ts +++ b/examples/gm/index.ts @@ -1,5 +1,9 @@ import { Client, type XmtpEnv } from "@xmtp/node-sdk"; -import { createSigner, getEncryptionKeyFromHex } from "@/helpers"; +import { + createSigner, + getAddressOfMember, + getEncryptionKeyFromHex, +} from "@/helpers"; /* Get the wallet key associated to the public key of * the agent and the encryption key for the local db @@ -30,8 +34,10 @@ async function main() { /* Sync the conversations from the network to update the local db */ await client.conversations.sync(); + const identifier = await signer.getIdentifier(); + const address = identifier.identifier; console.log( - `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}?env=${env}`, + `Agent initialized on ${address}\nSend a message on http://xmtp.chat/dm/${address}`, ); console.log("Waiting for messages..."); @@ -52,16 +58,18 @@ async function main() { ); /* Get the conversation by id */ - const conversation = client.conversations.getConversationById( - message.conversationId, + const conversation = client.conversations.getDmByInboxId( + message.senderInboxId, ); if (!conversation) { console.log("Unable to find conversation, skipping"); continue; } + const members = await conversation.members(); - console.log(`Sending "gm" response...`); + const address = getAddressOfMember(members, message.senderInboxId); + console.log(`Sending "gm" response to ${address}...`); /* Send a message to the conversation */ await conversation.send("gm"); diff --git a/examples/gpt/README.md b/examples/gpt/README.md index 81c2b1d..c6387a5 100644 --- a/examples/gpt/README.md +++ b/examples/gpt/README.md @@ -18,9 +18,6 @@ You can generate random keys with the following command: yarn gen:keys ``` -> [!WARNING] -> Running the `gen:keys` script will overwrite the existing `.env` file. - ## Usage ```tsx @@ -60,7 +57,7 @@ async function main() { await client.conversations.sync(); console.log( - `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}`, + `Agent initialized on ${address}\nSend a message on http://xmtp.chat/dm/${address}`, ); console.log("Waiting for messages..."); diff --git a/examples/gpt/index.ts b/examples/gpt/index.ts index 44c400e..4fd0a71 100644 --- a/examples/gpt/index.ts +++ b/examples/gpt/index.ts @@ -46,8 +46,10 @@ async function main() { /* Sync the conversations from the network to update the local db */ await client.conversations.sync(); + const identifier = await signer.getIdentifier(); + const address = identifier.identifier; console.log( - `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}?env=${env}`, + `Agent initialized on ${address}\nSend a message on http://xmtp.chat/dm/${address}`, ); console.log("Waiting for messages..."); @@ -68,8 +70,8 @@ async function main() { ); /* Get the conversation from the local db */ - const conversation = client.conversations.getConversationById( - message.conversationId, + const conversation = client.conversations.getDmByInboxId( + message.senderInboxId, ); /* If the conversation is not found, skip the message */ diff --git a/helpers/index.ts b/helpers/index.ts index 6680c42..6174df1 100644 --- a/helpers/index.ts +++ b/helpers/index.ts @@ -1,20 +1,22 @@ import { getRandomValues } from "node:crypto"; -import type { Signer } from "@xmtp/node-sdk"; +import { IdentifierKind, type GroupMember } from "@xmtp/node-bindings"; +import { type Signer } from "@xmtp/node-sdk"; import { fromString, toString } from "uint8arrays"; import { createWalletClient, http, toBytes } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { sepolia } from "viem/chains"; interface User { - key: string; + key: `0x${string}`; account: ReturnType; wallet: ReturnType; } -export const createUser = (key: string): User => { - const account = privateKeyToAccount(key as `0x${string}`); +export const createUser = (key: `0x${string}`): User => { + const accountKey = key; + const account = privateKeyToAccount(accountKey); return { - key, + key: accountKey, account, wallet: createWalletClient({ account, @@ -24,11 +26,14 @@ export const createUser = (key: string): User => { }; }; -export const createSigner = (key: string): Signer => { +export const createSigner = (key: `0x${string}`): Signer => { const user = createUser(key); return { - walletType: "EOA", - getAddress: () => user.account.address, + type: "EOA", + getIdentifier: () => ({ + identifierKind: IdentifierKind.Ethereum, + identifier: user.account.address.toLowerCase(), + }), signMessage: async (message: string) => { const signature = await user.wallet.signMessage({ message, @@ -39,6 +44,25 @@ export const createSigner = (key: string): Signer => { }; }; +/** + * Get the address of a member + * @param members - The members of the group + * @param inboxId - The inboxId of the member + * @returns The address of the member + */ +export function getAddressOfMember(members: GroupMember[], inboxId: string) { + for (const member of members) { + for (const identifier of member.accountIdentifiers) { + if ( + identifier.identifierKind === IdentifierKind.Ethereum && + member.inboxId === inboxId + ) { + return identifier.identifier; + } + } + } +} + /** * Generate a random encryption key * @returns The encryption key diff --git a/integrations/gaia/README.md b/integrations/gaia/README.md index b3bdbca..197de58 100644 --- a/integrations/gaia/README.md +++ b/integrations/gaia/README.md @@ -22,9 +22,6 @@ You can generate random keys with the following command: yarn gen:keys ``` -> [!WARNING] -> Running the `gen:keys` script will overwrite the existing `.env` file. - ## Usage ```tsx @@ -32,7 +29,13 @@ import { Client, type XmtpEnv } from "@xmtp/node-sdk"; import OpenAI from "openai"; import { createSigner, getEncryptionKeyFromHex } from "@/helpers"; -const { WALLET_KEY, ENCRYPTION_KEY, GAIA_NODE_URL, GAIA_API_KEY, GAIA_MODEL_NAME } = process.env; +const { + WALLET_KEY, + ENCRYPTION_KEY, + GAIA_NODE_URL, + GAIA_API_KEY, + GAIA_MODEL_NAME, +} = process.env; if (!WALLET_KEY) { throw new Error("WALLET_KEY must be set"); @@ -59,9 +62,9 @@ if (!GAIA_MODEL_NAME) { const signer = createSigner(WALLET_KEY); const encryptionKey = getEncryptionKeyFromHex(ENCRYPTION_KEY); -const openai = new OpenAI({ - baseURL: GAIA_NODE_URL, - apiKey: GAIA_API_KEY +const openai = new OpenAI({ + baseURL: GAIA_NODE_URL, + apiKey: GAIA_API_KEY, }); /* Set the environment to dev or production */ @@ -77,8 +80,10 @@ async function main() { /* Sync the conversations from the network to update the local db */ await client.conversations.sync(); + const identifier = await signer.getIdentifier(); + const address = identifier.identifier; console.log( - `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}`, + `Agent initialized on ${address}\nSend a message on http://xmtp.chat/dm/${address}`, ); console.log("Waiting for messages..."); diff --git a/integrations/gaia/index.ts b/integrations/gaia/index.ts index d4d96f0..ef7cd1a 100644 --- a/integrations/gaia/index.ts +++ b/integrations/gaia/index.ts @@ -65,8 +65,10 @@ async function main() { /* Sync the conversations from the network to update the local db */ await client.conversations.sync(); + const identifier = await signer.getIdentifier(); + const address = identifier.identifier; console.log( - `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}`, + `Agent initialized on ${address}\nSend a message on http://xmtp.chat/dm/${address}`, ); console.log("Waiting for messages..."); diff --git a/integrations/gaia/package.json b/integrations/gaia/package.json index db0dc9e..9a824eb 100644 --- a/integrations/gaia/package.json +++ b/integrations/gaia/package.json @@ -8,7 +8,7 @@ "gen:keys": "tsx ../../scripts/generateKeys.ts" }, "dependencies": { - "@xmtp/node-sdk": "0.0.47", + "@xmtp/node-sdk": "1.0.0-rc1", "tsx": "^4.19.2", "uint8arrays": "^5.1.0", "viem": "^2.22.17" diff --git a/integrations/grok/README.md b/integrations/grok/README.md index 87c8797..f9cac76 100644 --- a/integrations/grok/README.md +++ b/integrations/grok/README.md @@ -18,9 +18,6 @@ You can generate random keys with the following command: yarn gen:keys ``` -> [!WARNING] -> Running the `gen:keys` script will overwrite the existing `.env` file. - ## Usage ```tsx @@ -68,9 +65,12 @@ async function main() { /* Sync the conversations from the network to update the local db */ await client.conversations.sync(); + const identifier = await signer.getIdentifier(); + const address = identifier.identifier; console.log( - `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}?env=${env}`, + `Agent initialized on ${address}\nSend a message on http://xmtp.chat/dm/${address}`, ); + console.log("Waiting for messages..."); /* Stream all messages from the network */ const stream = client.conversations.streamAllMessages(); diff --git a/integrations/grok/index.ts b/integrations/grok/index.ts index cbac903..4484fc2 100644 --- a/integrations/grok/index.ts +++ b/integrations/grok/index.ts @@ -42,9 +42,12 @@ async function main() { /* Sync the conversations from the network to update the local db */ await client.conversations.sync(); + const identifier = await signer.getIdentifier(); + const address = identifier.identifier; console.log( - `Agent initialized on ${client.accountAddress}\nSend a message on http://xmtp.chat/dm/${client.accountAddress}?env=${env}`, + `Agent initialized on ${address}\nSend a message on http://xmtp.chat/dm/${address}`, ); + console.log("Waiting for messages..."); /* Stream all messages from the network */ const stream = client.conversations.streamAllMessages(); @@ -63,8 +66,8 @@ async function main() { ); /* Get the conversation from the local db */ - const conversation = client.conversations.getConversationById( - message.conversationId, + const conversation = client.conversations.getDmByInboxId( + message.senderInboxId, ); /* If the conversation is not found, skip the message */ diff --git a/integrations/grok/package.json b/integrations/grok/package.json index f1de7e0..40601c4 100644 --- a/integrations/grok/package.json +++ b/integrations/grok/package.json @@ -8,7 +8,7 @@ "gen:keys": "tsx ../../scripts/generateKeys.ts" }, "dependencies": { - "@xmtp/node-sdk": "0.0.42", + "@xmtp/node-sdk": "1.0.0-rc1", "tsx": "^4.19.2", "uint8arrays": "^5.1.0", "viem": "^2.22.17" diff --git a/package.json b/package.json index 95d9ef0..af6960d 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "typecheck": "tsc" }, "dependencies": { - "@xmtp/node-sdk": "0.0.45", + "@xmtp/node-sdk": "1.0.0-rc1", "alchemy-sdk": "^3.0.0", "openai": "latest", "tsx": "^4.19.2", diff --git a/scripts/generateKeys.ts b/scripts/generateKeys.ts index d49280a..0a88fa0 100644 --- a/scripts/generateKeys.ts +++ b/scripts/generateKeys.ts @@ -1,20 +1,39 @@ import { writeFile } from "node:fs/promises"; import { join } from "node:path"; -import { generatePrivateKey } from "viem/accounts"; +import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; import { generateEncryptionKeyHex } from "@/helpers"; console.log("Generating keys..."); +const person = process.argv[2]; const walletKey = generatePrivateKey(); +const account = privateKeyToAccount(walletKey); const encryptionKeyHex = generateEncryptionKeyHex(); +const publicKey = account.address; const filePath = join(process.cwd(), ".env"); -await writeFile( - filePath, - `WALLET_KEY=${walletKey} +// Format the environment variables based on whether a person name was provided +let envContent; +if (person) { + envContent = `# ${person.toLowerCase()} +WALLET_KEY_${person.toUpperCase()}=${walletKey} +ENCRYPTION_KEY_${person.toUpperCase()}=${encryptionKeyHex} +# public key is ${publicKey} +`; +} else { + envContent = `# generic keys +WALLET_KEY=${walletKey} ENCRYPTION_KEY=${encryptionKeyHex} -`, -); +# public key is ${publicKey} +`; +} -console.log(`Keys written to ${filePath}`); +await writeFile(filePath, envContent, { flag: "a" }); + +// Log appropriate message based on whether a person name was provided +if (person) { + console.log(`Keys for ${person} written to ${filePath}`); +} else { + console.log(`Generic keys written to ${filePath}`); +} diff --git a/tsconfig.json b/tsconfig.json index c46e6b9..869d58b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,7 @@ "declaration": true, "declarationMap": true, "forceConsistentCasingInFileNames": true, - "isolatedModules": true, + "isolatedModules": false, "lib": ["ESNext"], "module": "ESNext", "moduleResolution": "Bundler", diff --git a/yarn.lock b/yarn.lock index 19e3357..02d7d98 100644 --- a/yarn.lock +++ b/yarn.lock @@ -812,7 +812,7 @@ __metadata: version: 0.0.0-use.local resolution: "@integrations/gaia@workspace:integrations/gaia" dependencies: - "@xmtp/node-sdk": "npm:0.0.47" + "@xmtp/node-sdk": "npm:1.0.0-rc1" tsx: "npm:^4.19.2" uint8arrays: "npm:^5.1.0" viem: "npm:^2.22.17" @@ -823,7 +823,7 @@ __metadata: version: 0.0.0-use.local resolution: "@integrations/gpt@workspace:integrations/grok" dependencies: - "@xmtp/node-sdk": "npm:0.0.42" + "@xmtp/node-sdk": "npm:1.0.0-rc1" tsx: "npm:^4.19.2" uint8arrays: "npm:^5.1.0" viem: "npm:^2.22.17" @@ -1285,63 +1285,23 @@ __metadata: languageName: node linkType: hard -"@xmtp/node-bindings@npm:^0.0.37": - version: 0.0.37 - resolution: "@xmtp/node-bindings@npm:0.0.37" - checksum: 10/06d12ee27f306a2ad767b75eedf3ceb0457cab3f574a545f44e487cbb39d07a3866c81277954a4937dc1f048a75c10b34b5ffa5de4fc43eaf9b1310a1c4dce8a +"@xmtp/node-bindings@npm:^1.0.0-rc2": + version: 1.0.0-rc2 + resolution: "@xmtp/node-bindings@npm:1.0.0-rc2" + checksum: 10/2cd22b55accdc90f463d983eba43e3b78335e974036622808c42488b99589b9c94a8c7dfce6e76f32d6e5da5fc65cb2888a09f2dc7210a85ed058109f26a50bf languageName: node linkType: hard -"@xmtp/node-bindings@npm:^0.0.38": - version: 0.0.38 - resolution: "@xmtp/node-bindings@npm:0.0.38" - checksum: 10/a9452a913cdda5cd050b91ed34358b8975524d1c5e6434db51b1d60f13a29069b531ee566811ab4ed339713ad0e041e83f24fc916684c968c322ba63f21319f3 - languageName: node - linkType: hard - -"@xmtp/node-bindings@npm:^0.0.41": - version: 0.0.41 - resolution: "@xmtp/node-bindings@npm:0.0.41" - checksum: 10/809347d36de2b4f205fe46cc3869b1eab7595107fd14b0535457732745d14851121d1e7b0f22a0845deb32e48dfca29a7ad36a12bf9fc5c46b445a308a589c10 - languageName: node - linkType: hard - -"@xmtp/node-sdk@npm:0.0.42": - version: 0.0.42 - resolution: "@xmtp/node-sdk@npm:0.0.42" - dependencies: - "@xmtp/content-type-group-updated": "npm:^2.0.0" - "@xmtp/content-type-primitives": "npm:^2.0.0" - "@xmtp/content-type-text": "npm:^2.0.0" - "@xmtp/node-bindings": "npm:^0.0.37" - "@xmtp/proto": "npm:^3.72.3" - checksum: 10/6163ede6d9cd7bc36b3a237d9a63a8be0041a11a1eefc6f56fefbf7cb8b8cc02c817c4696996a29a4f296d7545fd3172d8ebf8f85e1aeb23dcff917719dfcd10 - languageName: node - linkType: hard - -"@xmtp/node-sdk@npm:0.0.45": - version: 0.0.45 - resolution: "@xmtp/node-sdk@npm:0.0.45" - dependencies: - "@xmtp/content-type-group-updated": "npm:^2.0.0" - "@xmtp/content-type-primitives": "npm:^2.0.0" - "@xmtp/content-type-text": "npm:^2.0.0" - "@xmtp/node-bindings": "npm:^0.0.38" - "@xmtp/proto": "npm:^3.72.3" - checksum: 10/70eb659105a585e651f9c9a538b98014476212a1023308b88012317a5c64e58b4a2d920891c131e763d449823cb8d1e126a4041ff73a803b5593702f43c08e8c - languageName: node - linkType: hard - -"@xmtp/node-sdk@npm:0.0.47": - version: 0.0.47 - resolution: "@xmtp/node-sdk@npm:0.0.47" +"@xmtp/node-sdk@npm:1.0.0-rc1": + version: 1.0.0-rc1 + resolution: "@xmtp/node-sdk@npm:1.0.0-rc1" dependencies: "@xmtp/content-type-group-updated": "npm:^2.0.0" "@xmtp/content-type-primitives": "npm:^2.0.0" "@xmtp/content-type-text": "npm:^2.0.0" - "@xmtp/node-bindings": "npm:^0.0.41" + "@xmtp/node-bindings": "npm:^1.0.0-rc2" "@xmtp/proto": "npm:^3.72.3" - checksum: 10/bf3b5e59cc5be0b9ec02acd2d7cf59bcae5f478971b5ffc772e6153c8d59515032c95436faf2c741e1de334d9572dc1991098395d9813ec5364f0eb09666a815 + checksum: 10/0f79fd211e56a627250015104c90605ca4b4cf39716877761311bc067c9dcf61b31e687a88880809a6a89d8fdb2729a271b309a961001660a53fec88ae2afbce languageName: node linkType: hard @@ -3882,7 +3842,7 @@ __metadata: "@ianvs/prettier-plugin-sort-imports": "npm:^4.4.1" "@types/eslint__js": "npm:^8.42.3" "@types/node": "npm:^22.13.0" - "@xmtp/node-sdk": "npm:0.0.45" + "@xmtp/node-sdk": "npm:1.0.0-rc1" alchemy-sdk: "npm:^3.0.0" eslint: "npm:^9.19.0" eslint-config-prettier: "npm:^10.0.1"