create-message-kit 1.2.21 → 1.2.23
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.
- package/README.md +2 -5
- package/index.js +7 -3
- package/package.json +2 -2
- package/templates/coinbase-agent/src/index.ts +5 -7
- package/templates/ens/src/index.ts +4 -24
- package/templates/ens/src/skills/info.ts +6 -3
- package/templates/faucet/src/index.ts +5 -16
- package/templates/gated-group/src/index.ts +2 -2
- package/templates/gm/src/index.ts +15 -7
- package/templates/hackathon-store/.env.example +6 -0
- package/templates/{thegeneralstore → hackathon-store}/package.json +1 -5
- package/templates/hackathon-store/src/index.ts +47 -0
- package/templates/{thegeneralstore → hackathon-store}/src/plugins/notion.ts +0 -29
- package/templates/hackathon-store/src/prompt.md +27 -0
- package/templates/playground/src/index.ts +9 -8
- package/templates/playground/src/vibes/chill.ts +9 -0
- package/templates/playground/src/vibes/friendly.ts +9 -0
- package/templates/playground/src/vibes/inquisitive.ts +10 -0
- package/templates/playground/src/vibes/playful.ts +10 -0
- package/templates/playground/src/vibes/professional.ts +9 -0
- package/templates/simple/src/index.ts +10 -9
- package/templates/toss/.env.example +1 -0
- package/templates/toss/src/index.ts +7 -10
- package/templates/toss/src/skills/toss.ts +0 -114
- package/templates/toss/src/skills/waas.ts +116 -0
- package/templates.json +58 -0
- package/templates/thegeneralstore/.env.example +0 -9
- package/templates/thegeneralstore/src/data/db.json +0 -812
- package/templates/thegeneralstore/src/index.ts +0 -37
- package/templates/thegeneralstore/src/plugins/learnweb3.ts +0 -96
- package/templates/thegeneralstore/src/plugins/lowdb.ts +0 -11
- package/templates/thegeneralstore/src/plugins/redis.ts +0 -15
- package/templates/thegeneralstore/src/prompt.md +0 -51
- package/templates/thegeneralstore/src/prompt.ts +0 -3
- package/templates/thegeneralstore/src/skills/faucet.ts +0 -114
- package/templates/thegeneralstore/src/skills/notion.ts +0 -17
- package/templates/thegeneralstore/src/skills/poap.ts +0 -48
- package/templates/thegeneralstore/src/skills.ts +0 -37
- /package/templates/{thegeneralstore → hackathon-store}/.cursorrules +0 -0
- /package/templates/{thegeneralstore → hackathon-store}/.yarnrc.yml +0 -0
@@ -1,37 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
agentReply,
|
3
|
-
XMTPContext,
|
4
|
-
replaceVariables,
|
5
|
-
run,
|
6
|
-
} from "@xmtp/message-kit";
|
7
|
-
import { downloadPage } from "./plugins/notion.js";
|
8
|
-
import fs from "fs";
|
9
|
-
|
10
|
-
setupFiles();
|
11
|
-
|
12
|
-
run(async (context: XMTPContext) => {
|
13
|
-
const {
|
14
|
-
message: { sender },
|
15
|
-
agent,
|
16
|
-
} = context;
|
17
|
-
let systemPrompt = await getPrompt();
|
18
|
-
let prompt = await replaceVariables(systemPrompt, sender.address, agent);
|
19
|
-
await agentReply(context, prompt);
|
20
|
-
});
|
21
|
-
|
22
|
-
async function getPrompt() {
|
23
|
-
if (fs.existsSync(".data/prompt.md"))
|
24
|
-
return fs.readFileSync(".data/prompt.md", "utf8");
|
25
|
-
else return fs.readFileSync("src/prompt.md", "utf8");
|
26
|
-
}
|
27
|
-
async function setupFiles() {
|
28
|
-
if (!fs.existsSync(".data/db.json")) {
|
29
|
-
const dbfile = fs.readFileSync("src/data/db.json", "utf8");
|
30
|
-
fs.writeFileSync(".data/db.json", dbfile);
|
31
|
-
console.log("DB file created");
|
32
|
-
}
|
33
|
-
|
34
|
-
const page = await downloadPage();
|
35
|
-
fs.writeFileSync("src/prompt.md", page);
|
36
|
-
console.log("Notion DB updated");
|
37
|
-
}
|
@@ -1,96 +0,0 @@
|
|
1
|
-
import axios from "axios";
|
2
|
-
|
3
|
-
export const SUPPORTED_NETWORKS = [
|
4
|
-
"arbitrum_goerli",
|
5
|
-
"arbitrum_sepolia",
|
6
|
-
"base_goerli",
|
7
|
-
"base_sepolia",
|
8
|
-
"base_sepolia_usdc",
|
9
|
-
"celo_alfajores",
|
10
|
-
"fantom_testnet",
|
11
|
-
"goerli",
|
12
|
-
"holesky",
|
13
|
-
"linea_goerli",
|
14
|
-
"linea_sepolia",
|
15
|
-
"manta_testnet",
|
16
|
-
"mode_sepolia",
|
17
|
-
"morph_sepolia",
|
18
|
-
"optimism_goerli",
|
19
|
-
"optimism_sepolia",
|
20
|
-
"polygon_amoy",
|
21
|
-
"polygon_mumbai",
|
22
|
-
"polygon_zkevm",
|
23
|
-
"scroll_sepolia",
|
24
|
-
"sepolia",
|
25
|
-
"taiko_jolnir",
|
26
|
-
"zksync_sepolia",
|
27
|
-
"zora_sepolia",
|
28
|
-
] as const;
|
29
|
-
|
30
|
-
export const CLAIM_EVERY = 24 * 60 * 60 * 1000; // 24 hours
|
31
|
-
|
32
|
-
export const ONE_DAY = 24 * 60 * 60 * 1000; // 24 hours
|
33
|
-
|
34
|
-
export const FIVE_MINUTES = 5 * 60 * 1000; // 5 minutes
|
35
|
-
|
36
|
-
export const EVM_TOKENS = ["ETH", "MATIC", "USDC", "CELO", "BERA"];
|
37
|
-
|
38
|
-
export interface Network {
|
39
|
-
networkId: string;
|
40
|
-
networkName: string;
|
41
|
-
networkLogo: string;
|
42
|
-
tokenName: string;
|
43
|
-
dripAmount: number;
|
44
|
-
address: string;
|
45
|
-
isERC20: boolean;
|
46
|
-
erc20Address?: string;
|
47
|
-
erc20Decimals?: number;
|
48
|
-
isActive: boolean;
|
49
|
-
balance: string;
|
50
|
-
}
|
51
|
-
export interface DripTokensResponse {
|
52
|
-
ok: boolean;
|
53
|
-
error?: string;
|
54
|
-
value?: string;
|
55
|
-
}
|
56
|
-
|
57
|
-
export class LearnWeb3Client {
|
58
|
-
public BASE_URL = "https://learnweb3.io/api/faucet";
|
59
|
-
private apiKey = process.env.LEARN_WEB3_API_KEY;
|
60
|
-
constructor() {
|
61
|
-
if (!process.env.LEARN_WEB3_API_KEY) {
|
62
|
-
throw new Error("Please set the LEARN_WEB3_API_KEY environment variable");
|
63
|
-
}
|
64
|
-
this.apiKey = process.env.LEARN_WEB3_API_KEY;
|
65
|
-
}
|
66
|
-
|
67
|
-
async getNetworks(onlyEvm = true): Promise<Network[]> {
|
68
|
-
const response = await axios(`${this.BASE_URL}/networks`);
|
69
|
-
const data: Network[] = response.data;
|
70
|
-
if (onlyEvm) {
|
71
|
-
return data.filter(
|
72
|
-
(network) =>
|
73
|
-
EVM_TOKENS.some((t) =>
|
74
|
-
network.tokenName.toLowerCase().includes(t.toLowerCase())
|
75
|
-
) && network.isActive
|
76
|
-
);
|
77
|
-
}
|
78
|
-
return data.filter((network) => network.isActive);
|
79
|
-
}
|
80
|
-
|
81
|
-
async dripTokens(
|
82
|
-
networkId: string,
|
83
|
-
recipientAddress: string
|
84
|
-
): Promise<DripTokensResponse> {
|
85
|
-
const response = await axios.post(
|
86
|
-
`${this.BASE_URL}/drip`,
|
87
|
-
{ networkId, recipientAddress },
|
88
|
-
{
|
89
|
-
headers: {
|
90
|
-
authorization: `Bearer ${this.apiKey}`,
|
91
|
-
},
|
92
|
-
}
|
93
|
-
);
|
94
|
-
return response.data;
|
95
|
-
}
|
96
|
-
}
|
@@ -1,11 +0,0 @@
|
|
1
|
-
import { Low } from "lowdb";
|
2
|
-
import { JSONFile } from "lowdb/node";
|
3
|
-
|
4
|
-
const adapter = new JSONFile<{
|
5
|
-
poaps: Record<string, string>[]; // URL, Address
|
6
|
-
}>(".data/db.json");
|
7
|
-
export const db = new Low<{
|
8
|
-
poaps: Record<string, string>[]; // URL, Address
|
9
|
-
}>(adapter, {
|
10
|
-
poaps: [],
|
11
|
-
});
|
@@ -1,15 +0,0 @@
|
|
1
|
-
import { createClient } from "@redis/client";
|
2
|
-
import { RedisClientType } from "@redis/client";
|
3
|
-
|
4
|
-
export const getRedisClient = async () => {
|
5
|
-
const client = createClient({
|
6
|
-
url: process.env.REDIS_CONNECTION_STRING,
|
7
|
-
});
|
8
|
-
|
9
|
-
client.on("error", (err) => {
|
10
|
-
console.error("Redis client error:", err);
|
11
|
-
});
|
12
|
-
|
13
|
-
await client.connect();
|
14
|
-
return client as RedisClientType;
|
15
|
-
};
|
@@ -1,51 +0,0 @@
|
|
1
|
-
You are a helpful agent that lives inside a messaging app. You manage the general store from XMTP that delivers goodies, POAPs and testnet funds.
|
2
|
-
|
3
|
-
{rules}
|
4
|
-
|
5
|
-
{user_context}
|
6
|
-
|
7
|
-
{skills}
|
8
|
-
|
9
|
-
### Goodies
|
10
|
-
|
11
|
-
- When greeted for the first time, give the full menu.
|
12
|
-
- The user can select the option by number or name
|
13
|
-
- Once the option is selected confirm the order
|
14
|
-
|
15
|
-
### Testnet funds
|
16
|
-
|
17
|
-
- For each user you can deliver testnet funds using the learnweb3 api.
|
18
|
-
- Check the available networks triggering the command before showing them.
|
19
|
-
- Users can select the desired testnet network for the transfer of funds by number or name.
|
20
|
-
|
21
|
-
### Poap Delivery
|
22
|
-
|
23
|
-
- For each user you'll deliver only one POAP.
|
24
|
-
- Don't forget to use commands to deliver POAPs.
|
25
|
-
- Poaps are unique URLs basically
|
26
|
-
|
27
|
-
## Response Scenarios:
|
28
|
-
|
29
|
-
- Welcome message:
|
30
|
-
Welcome to The General Store powered by ENS + XMTP, where web3 builders can get supplies, anytime, day or night.
|
31
|
-
Below is our menu. Let us know the number of the item you want, and it's yours. If it's a digital good, our bot will deliver those items right to your wallet.
|
32
|
-
- Chewing Gum
|
33
|
-
- TicTacs
|
34
|
-
- Deodorant
|
35
|
-
- RedBull
|
36
|
-
- Toothbrush
|
37
|
-
- Toothpaste
|
38
|
-
- XMTP Swag
|
39
|
-
- Testnet funds
|
40
|
-
- POAP
|
41
|
-
Please reply with the item or number of the item you want
|
42
|
-
- Delivering a POAP:
|
43
|
-
You've selected a POAP. I will deliver it to your address:
|
44
|
-
Processing your request now...
|
45
|
-
/poap 0x42AB57335941eb00535e95CbF64D78654Cb0F66A
|
46
|
-
- Delivering testnet
|
47
|
-
You've selected Testnet funds. Let me check the available networks for you.
|
48
|
-
Processing your request now...
|
49
|
-
/networks
|
50
|
-
- Delivering goodies
|
51
|
-
Let me get your TicTacs... Your order is confirmed. Enjoy!
|
@@ -1,114 +0,0 @@
|
|
1
|
-
import { XMTPContext, clearMemory } from "@xmtp/message-kit";
|
2
|
-
import { getRedisClient } from "../plugins/redis.js";
|
3
|
-
import {
|
4
|
-
FIVE_MINUTES,
|
5
|
-
LearnWeb3Client,
|
6
|
-
Network,
|
7
|
-
} from "../plugins/learnweb3.js";
|
8
|
-
|
9
|
-
export async function handleFaucet(context: XMTPContext) {
|
10
|
-
const { message } = context;
|
11
|
-
const redisClient = await getRedisClient();
|
12
|
-
const {
|
13
|
-
content: { skill, params },
|
14
|
-
sender,
|
15
|
-
} = message;
|
16
|
-
|
17
|
-
// Initialize LearnWeb3Client
|
18
|
-
const learnWeb3Client = new LearnWeb3Client();
|
19
|
-
|
20
|
-
// Fetch supported networks from Redis cache or API
|
21
|
-
let supportedNetworks: Network[];
|
22
|
-
const cachedSupportedNetworksData = await redisClient.get(
|
23
|
-
"supported-networks"
|
24
|
-
);
|
25
|
-
supportedNetworks = JSON.parse(
|
26
|
-
cachedSupportedNetworksData!
|
27
|
-
).supportedNetworks;
|
28
|
-
|
29
|
-
if (skill === "networks") {
|
30
|
-
if (
|
31
|
-
!cachedSupportedNetworksData ||
|
32
|
-
Date.now() >
|
33
|
-
parseInt(JSON.parse(cachedSupportedNetworksData).lastSyncedAt) +
|
34
|
-
FIVE_MINUTES
|
35
|
-
) {
|
36
|
-
console.log("Cleared cache");
|
37
|
-
const updatedSupportedNetworksData = await learnWeb3Client.getNetworks();
|
38
|
-
await redisClient.set(
|
39
|
-
"supported-networks",
|
40
|
-
JSON.stringify({
|
41
|
-
lastSyncedAt: Date.now(),
|
42
|
-
supportedNetworks: updatedSupportedNetworksData,
|
43
|
-
})
|
44
|
-
);
|
45
|
-
supportedNetworks = updatedSupportedNetworksData;
|
46
|
-
} else {
|
47
|
-
supportedNetworks = JSON.parse(
|
48
|
-
cachedSupportedNetworksData!
|
49
|
-
).supportedNetworks;
|
50
|
-
}
|
51
|
-
|
52
|
-
supportedNetworks = supportedNetworks.filter(
|
53
|
-
(n) =>
|
54
|
-
!n.networkId.toLowerCase().includes("starknet") &&
|
55
|
-
!n.networkId.toLowerCase().includes("fuel") &&
|
56
|
-
!n.networkId.toLowerCase().includes("mode")
|
57
|
-
);
|
58
|
-
|
59
|
-
const networkList = supportedNetworks.map((n, index) => {
|
60
|
-
return `${index + 1}. ${n.networkId
|
61
|
-
.replace(/_/g, " ")
|
62
|
-
.replace(/\b\w/g, (l) => l.toUpperCase())}`;
|
63
|
-
});
|
64
|
-
|
65
|
-
return {
|
66
|
-
message: `Available networks:\n\n${networkList.join("\n")}`,
|
67
|
-
code: 200,
|
68
|
-
};
|
69
|
-
} else if (skill === "faucet") {
|
70
|
-
const { network } = params;
|
71
|
-
const selectedNetwork = supportedNetworks.find(
|
72
|
-
(n) => n.networkId === network
|
73
|
-
);
|
74
|
-
|
75
|
-
if (!selectedNetwork) {
|
76
|
-
await context.send("Invalid network. Please select a valid option.");
|
77
|
-
return;
|
78
|
-
}
|
79
|
-
|
80
|
-
await context.send(
|
81
|
-
"Your testnet tokens are being processed. Please wait a moment for the transaction to process."
|
82
|
-
);
|
83
|
-
|
84
|
-
const result = await learnWeb3Client.dripTokens(
|
85
|
-
selectedNetwork.networkId,
|
86
|
-
sender.address
|
87
|
-
);
|
88
|
-
|
89
|
-
if (!result.ok) {
|
90
|
-
await context.send(
|
91
|
-
`❌ Sorry, there was an error processing your request:\n\n"${result.error!}"`
|
92
|
-
);
|
93
|
-
// Clear any in-memory cache or state related to the prompt
|
94
|
-
clearMemory();
|
95
|
-
return;
|
96
|
-
}
|
97
|
-
|
98
|
-
await context.send("Here's your transaction receipt:");
|
99
|
-
await context.send(
|
100
|
-
`${process.env.FRAME_BASE_URL}?txLink=${result.value}&networkLogo=${
|
101
|
-
selectedNetwork?.networkLogo
|
102
|
-
}&networkName=${selectedNetwork?.networkName.replaceAll(
|
103
|
-
" ",
|
104
|
-
"-"
|
105
|
-
)}&tokenName=${selectedNetwork?.tokenName}&amount=${
|
106
|
-
selectedNetwork?.dripAmount
|
107
|
-
}`
|
108
|
-
);
|
109
|
-
// Clear any in-memory cache or state related to the prompt
|
110
|
-
clearMemory();
|
111
|
-
} else {
|
112
|
-
await context.send("Unknown skill. Please use 'list' or 'drip'.");
|
113
|
-
}
|
114
|
-
}
|
@@ -1,17 +0,0 @@
|
|
1
|
-
import { XMTPContext } from "@xmtp/message-kit";
|
2
|
-
import { downloadPage } from "../plugins/notion.js";
|
3
|
-
import fs from "fs";
|
4
|
-
|
5
|
-
export async function handleNotion(context: XMTPContext) {
|
6
|
-
const {
|
7
|
-
message: {
|
8
|
-
content: { skill },
|
9
|
-
},
|
10
|
-
} = context;
|
11
|
-
|
12
|
-
if (skill === "update") {
|
13
|
-
const page = await downloadPage();
|
14
|
-
fs.writeFileSync("src/prompt.md", page);
|
15
|
-
await context.reply("Notion DB updated");
|
16
|
-
}
|
17
|
-
}
|
@@ -1,48 +0,0 @@
|
|
1
|
-
import { XMTPContext } from "@xmtp/message-kit";
|
2
|
-
import { db } from "../plugins/lowdb.js";
|
3
|
-
await db.read();
|
4
|
-
|
5
|
-
export async function handlePoap(context: XMTPContext) {
|
6
|
-
const {
|
7
|
-
message: {
|
8
|
-
content: { skill, params },
|
9
|
-
},
|
10
|
-
} = context;
|
11
|
-
|
12
|
-
if (skill == "list") {
|
13
|
-
const poapTable = db?.data?.poaps;
|
14
|
-
const claimed = poapTable.filter((poap) => poap.Address);
|
15
|
-
return {
|
16
|
-
code: 200,
|
17
|
-
message: `You have claimed ${claimed.length} POAPs out of ${poapTable.length}`,
|
18
|
-
};
|
19
|
-
} else if (skill == "poap") {
|
20
|
-
const { address } = params;
|
21
|
-
await db.read();
|
22
|
-
const poapTable = db?.data?.poaps;
|
23
|
-
const poap = poapTable.find((poap) => poap.Address == address);
|
24
|
-
|
25
|
-
if (!poap) {
|
26
|
-
const emptyPoap = poapTable.find((poap) => !poap.Address);
|
27
|
-
if (emptyPoap) {
|
28
|
-
db?.data?.poaps?.push({ URL: emptyPoap?.URL, Address: address });
|
29
|
-
//?user_address=${address}`
|
30
|
-
return {
|
31
|
-
code: 200,
|
32
|
-
message: `Here is your POAP ${emptyPoap?.URL}`,
|
33
|
-
};
|
34
|
-
} else {
|
35
|
-
return {
|
36
|
-
code: 200,
|
37
|
-
message: "No more POAPs available",
|
38
|
-
};
|
39
|
-
}
|
40
|
-
} else {
|
41
|
-
//?user_address=${address}`
|
42
|
-
return {
|
43
|
-
code: 200,
|
44
|
-
message: `You have already claimed this POAP ${poap?.URL}`,
|
45
|
-
};
|
46
|
-
}
|
47
|
-
}
|
48
|
-
}
|
@@ -1,37 +0,0 @@
|
|
1
|
-
import type { Agent } from "@xmtp/message-kit";
|
2
|
-
import { handlePoap } from "./skills/poap.js";
|
3
|
-
import { handleFaucet } from "./skills/faucet.js";
|
4
|
-
import { handleNotion } from "./skills/notion.js";
|
5
|
-
|
6
|
-
export const agent: Agent = {
|
7
|
-
name: "Poap Bot",
|
8
|
-
description: "Get your POAP.",
|
9
|
-
tag: "@store",
|
10
|
-
skills: [
|
11
|
-
{
|
12
|
-
skill: "/poap [address]",
|
13
|
-
handler: handlePoap,
|
14
|
-
examples: ["/poap 0x1234567890123456789012345678901234567890"],
|
15
|
-
description: "Get your POAP.",
|
16
|
-
params: {
|
17
|
-
address: {
|
18
|
-
type: "string",
|
19
|
-
},
|
20
|
-
},
|
21
|
-
},
|
22
|
-
{
|
23
|
-
skill: "/list",
|
24
|
-
handler: handlePoap,
|
25
|
-
examples: ["/list"],
|
26
|
-
description: "List all POAPs.",
|
27
|
-
params: {},
|
28
|
-
},
|
29
|
-
{
|
30
|
-
skill: "/update",
|
31
|
-
handler: handleNotion,
|
32
|
-
examples: ["/update"],
|
33
|
-
description: "Update your Notion prompt.",
|
34
|
-
params: {},
|
35
|
-
},
|
36
|
-
],
|
37
|
-
};
|
File without changes
|
File without changes
|