-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathindex.ts
160 lines (138 loc) · 5.35 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import "dotenv/config";
import { createSigner, getEncryptionKeyFromHex } from "@helpers";
import { Client, type Group, type XmtpEnv } from "@xmtp/node-sdk";
import { Alchemy, Network } from "alchemy-sdk";
const settings = {
apiKey: process.env.ALCHEMY_API_KEY,
network: Network.BASE_MAINNET,
};
/* Get the wallet key associated to the public key of
* the agent and the encryption key for the local db
* that stores your agent's messages */
const { WALLET_KEY, ENCRYPTION_KEY } = process.env;
if (!WALLET_KEY) {
throw new Error("WALLET_KEY must be set");
}
if (!ENCRYPTION_KEY) {
throw new Error("ENCRYPTION_KEY must be set");
}
/* Create the signer using viem and parse the encryption key for the local db */
const signer = createSigner(WALLET_KEY);
const encryptionKey = getEncryptionKeyFromHex(ENCRYPTION_KEY);
/* Set the environment to local, dev or production */
const env: XmtpEnv = process.env.XMTP_ENV as XmtpEnv;
async function main() {
console.log(`Creating client on the '${env}' network...`);
const client = await Client.create(signer, encryptionKey, {
env,
});
console.log("Syncing conversations...");
await client.conversations.sync();
const identifier = await signer.getIdentifier();
const address = identifier.identifier;
console.log(
`Agent initialized on ${address}\nSend a message on http://xmtp.chat/dm/${address}?env=${env}`,
);
console.log("Waiting for messages...");
const stream = client.conversations.streamAllMessages();
for await (const message of await stream) {
/* Ignore messages from the same agent or non-text messages */
if (
message?.senderInboxId.toLowerCase() === client.inboxId.toLowerCase() ||
message?.contentType?.typeId !== "text"
) {
continue;
}
console.log(
`Received message: ${message.content as string} by ${message.senderInboxId}`,
);
const conversation = client.conversations.getDmByInboxId(
message.senderInboxId,
);
if (!conversation) {
console.log("Unable to find conversation, skipping");
continue;
}
/* This example works by parsing slash commands to create a new group or add a member to a group
* /create - create a new group
* /add <group_id> <wallet_address> - add a member to a group */
if (message.content === "/create") {
console.log("Creating group");
const group = await client.conversations.newGroup([]);
console.log("Group created", group.id);
// First add the sender to the group
await group.addMembers([message.senderInboxId]);
// Then make the sender a super admin
await group.addSuperAdmin(message.senderInboxId);
console.log(
"Sender is superAdmin",
group.isSuperAdmin(message.senderInboxId),
);
await group.send(
`Welcome to the new group!\nYou are now the admin of this group as well as the bot`,
);
await conversation.send(
`Group created!\n- ID: ${group.id}\n- Group URL: https://xmtp.chat/conversations/${group.id}: \n- This url will deeplink to the group created\n- Once in the other group you can share the invite with your friends.\n- You can add more members to the group by using the /add <group_id> <wallet_address>.`,
);
return;
} else if (
typeof message.content === "string" &&
message.content.startsWith("/add")
) {
const groupId = message.content.split(" ")[1];
if (!groupId) {
await conversation.send("Please provide a group id");
return;
}
const group = await client.conversations.getConversationById(groupId);
if (!group) {
await conversation.send("Please provide a valid group id");
return;
}
const walletAddress = message.content.split(" ")[2];
if (!walletAddress) {
await conversation.send("Please provide a wallet address");
return;
}
const result = await checkNft(walletAddress, "XMTPeople");
if (!result) {
console.log("User can't be added to the group");
return;
} else {
await (group as Group).addMembers([walletAddress]);
await conversation.send(
`User added to the group\n- Group ID: ${groupId}\n- Wallet Address: ${walletAddress}`,
);
}
} else {
await conversation.send(
"👋 Welcome to the Gated Bot Group!\nTo get started, type /create to set up a new group. 🚀\nThis example will check if the user has a particular nft and add them to the group if they do.\nOnce your group is created, you'll receive a unique Group ID and URL.\nShare the URL with friends to invite them to join your group!",
);
}
}
}
main().catch(console.error);
/**
* Check if the user has the NFT
* @param walletAddress - The wallet address of the user
* @param collectionSlug - The slug of the collection
* @returns true if the user has the NFT, false otherwise
*/
async function checkNft(
walletAddress: string,
collectionSlug: string,
): Promise<boolean> {
const alchemy = new Alchemy(settings);
try {
const nfts = await alchemy.nft.getNftsForOwner(walletAddress);
const ownsNft = nfts.ownedNfts.some(
(nft) =>
nft.contract.name?.toLowerCase() === collectionSlug.toLowerCase(),
);
console.log("is the nft owned: ", ownsNft);
return ownsNft;
} catch (error) {
console.error("Error fetching NFTs from Alchemy:", error);
}
return false;
}