Skip to content

Commit

Permalink
Merge pull request #82 from ephemeraHQ/updates_v11
Browse files Browse the repository at this point in the history
Updates v11
  • Loading branch information
fabriguespe authored Aug 31, 2024
2 parents a175b0f + 01d8727 commit 0251788
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 55 deletions.
6 changes: 4 additions & 2 deletions packages/docs/pages/concepts/structure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ export const commands = [
];
```

_To learn more on how to define commands, go to [commands](./commands) section_
_To learn more on how to define commands, go to [commands](/concepts/commands) section_

## Environment variables

Each app should have an `.env` file that contains the following:

```bash [.env]
KEY= # 0x... the private key of the bot wallet (with the 0x prefix)
KEY= # 0x... the private key of the bot wallet, like any normal wallet private key. (with the 0x prefix)
MSG_LOG=false # logs the message on the console (optional)
XMTP_ENV=production # dev or production (optional)
```
89 changes: 57 additions & 32 deletions packages/docs/pages/frames/frameworks/Framesjs.mdx
Original file line number Diff line number Diff line change
@@ -1,49 +1,74 @@
# Frames.js

Discover how Frog seamlessly incorporates XMTP payloads
Discover how Frames.js seamlessly incorporates XMTP payloads

- [Frames.js](https://framesjs.org/reference/js/xmtp): Official Frames.js Documentation.
- [Quickstart](https:/ephemeraHQ/open-frames-starter-framesjs/): OnchainKit quickstart that integrates XMTP.
- [Offical Docs](https://framesjs.org/guides/open-frames): Official Frames.js Documentation.
- [Frames.js Quickstart](https:/ephemeraHQ/open-frames-starter-framesjs/): Frames.js quickstart that integrates XMTP.

## Metadata

First add the metadata indicating which protocols you support.

```jsx
const acceptedProtocols: ClientProtocolId[] = [
{
id: "xmtp",
version: "vNext",
},
{
id: "farcaster",
version: "vNext",
},
];
// ...
import { openframes } from "frames.js/middleware";

const frames = createFrames({
// ...
middleware: [
openframes({
clientProtocol: {
id: "my-protocol",
version: "1.0.0",
},
handler: {
isValidPayload: (body: JSON) => {
// Check if the request body is a valid Open Frames action
// ...
return isValid; // true or false
},
getFrameMessage: async (body: JSON) => {
// Parse the data in the request body and return a Frame message
// ...
return frameMessage;
},
},
}),
],
});
```

## Validate incoming messages

Now validate the incoming message.

```jsx
let fid: number | undefined;
let walletAddress: string | undefined;

import {
isXmtpFrameRequest,
getXmtpFrameMessage,
} from "@coinbase/onchainkit/xmtp";
import { NextResponse } from "next/server";
import type { FrameRequest } from "@coinbase/onchainkit";

async function getResponse(req: any): Promise<NextResponse> {
const body: FrameRequest = await req.json();
if (isXmtpFrameRequest(body)) {
const { isValid, message } = await getXmtpFrameMessage(body);
walletAddress = message?.verifiedWalletAddress;
} else {
// ...
}
}
/* eslint-disable react/jsx-key */
import { openframes } from "frames.js/middleware";
import { createFrames } from "frames.js/next";
import { getXmtpFrameMessage, isXmtpFrameActionPayload } from "frames.js/xmtp";

export const frames = createFrames({
middleware: [
openframes({
clientProtocol: {
id: "xmtp",
version: "2024-02-09",
},
handler: {
isValidPayload: (body: JSON) => isXmtpFrameActionPayload(body),
getFrameMessage: async (body: JSON) => {
if (isXmtpFrameActionPayload(body)) {
return undefined;
}
// payload is an XMTP frame action payload
const result = await getXmtpFrameMessage(body);
// ... do something with the verifiedWalletAddress
const { verifiedWalletAddress } = result;
return { ...result };
},
},
}),
],
});
```
4 changes: 2 additions & 2 deletions packages/docs/pages/frames/frameworks/Frog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

Discover how Frog seamlessly incorporates XMTP payloads

- [Frog](https://frog.fm/concepts/middleware#xmtp-frames-middleware): XMTP Frog official middleware
- [Quickstart](https:/ephemeraHQ/open-frames-starter-frog): Frog XMTP quickstart
- [Official Docs](https://frog.fm/concepts/middleware#xmtp-frames-middleware): XMTP Frog official middleware
- [Frog Quickstart](https:/ephemeraHQ/open-frames-starter-frog): Frog XMTP quickstart

## Metadata

Expand Down
4 changes: 2 additions & 2 deletions packages/docs/pages/frames/frameworks/OnchainKit.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

Onchain Kit incorporates XMTP payloads

- [Onchain Kit](https://onchainkit.xyz/xmtp/introduction): Official Onchain Kit documentation.
- [Quickstart](https:/ephemeraHQ/open-frames-starter-onchainkit/): Onchain Kit quickstart that integrates XMTP.
- [Official Docs](https://onchainkit.xyz/xmtp/introduction): Official Onchain Kit documentation.
- [OnchainKit Quickstart](https:/ephemeraHQ/open-frames-starter-onchainkit/): Onchain Kit quickstart that integrates XMTP.

## Metadata

Expand Down
53 changes: 46 additions & 7 deletions packages/docs/pages/use-cases/group/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,40 @@ export const commands: CommandGroup[] = [
},
],
},
{
name: "Loyalty",
icon: "🔓",
description: "Manage group members and metadata.",
commands: [
{
command: "/points",
description: "Check your points.",
params: {},
},
{
command: "/leaderboard",
description: "Check the points of a user.",
params: {},
},
],
},
{
name: "Agent",
icon: "🤖",
description: "Manage agent commands.",
commands: [
{
command: "/agent [prompt]",
description: "Manage agent commands.",
params: {
prompt: {
default: "",
type: "string",
},
},
},
],
},
{
name: "Admin",
icon: "🔐",
Expand Down Expand Up @@ -232,18 +266,22 @@ import { handler as bet } from "./handler/betting.js";
import { handler as tipping } from "./handler/tipping.js";
import { handler as agent } from "./handler/agent.js";
import { handler as transaction } from "./handler/transaction.js";
import { handler as splitpayment } from "./handler/payments.js";
import { handler as splitpayment } from "./handler/payment.js";
import { handler as games } from "./handler/game.js";
import { handler as admin } from "./handler/admin.js";
import { handler as loyalty } from "./handler/loyalty.js";

// Define command handlers
const commandHandlers: CommandHandlers = {
"/tip": tipping,
"/agent": agent,
"/bet": bet,
"/send": transaction,
"/swap": transaction,
"/mint": transaction,
"/show": transaction,
"/points": loyalty,
"/leaderboard": loyalty,
"/game": games,
"/add": admin,
"/remove": admin,
Expand Down Expand Up @@ -286,23 +324,25 @@ run(async (context: HandlerContext) => {
const {
message: { typeId },
} = context;

try {
switch (typeId) {
case "reaction":
handleReaction(context);
loyalty(context);
break;
case "reply":
handleReply(context);
break;
case "group_updated":
await admin(context);
admin(context);
loyalty(context);
break;
case "remoteStaticAttachment":
await handleAttachment(context);
handleAttachment(context);
break;
case "text":
await handleTextMessage(context);
handleTextMessage(context);
loyalty(context, true);
break;
default:
console.warn(`Unhandled message type: ${typeId}`);
Expand All @@ -328,8 +368,7 @@ async function handleReply(context: HandlerContext) {
const {
content: { content: reply },
} = context.message;

if (reply.includes("$degen")) {
if (reply.includes("degen")) {
await tipping(context);
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/message-kit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@xmtp/message-kit",
"version": "0.0.10",
"version": "0.0.11",
"license": "MIT",
"type": "module",
"exports": {
Expand Down
19 changes: 14 additions & 5 deletions packages/message-kit/src/helpers/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,17 @@ export function extractCommandValues(
} = expectedParams[param];
let valueFound = false;

if (type === "quoted") {
// Handle string type with no possible values
if (type === "string" && possibleValues.length === 0) {
const stringIndex = parts.findIndex(
(part, idx) => !usedIndices.has(idx) && idx > 0,
);
if (stringIndex !== -1) {
values.params[param] = parts[stringIndex];
usedIndices.add(stringIndex);
valueFound = true;
}
} else if (type === "quoted") {
const quotedIndex = parts.findIndex(
(part, idx) => /^["'`].*["'`]$/.test(part) && !usedIndices.has(idx),
);
Expand All @@ -91,6 +101,9 @@ export function extractCommandValues(
usedIndices.add(quotedIndex);
valueFound = true;
}
} else if (type === "prompt") {
values.params[param] = parts.slice(1).join(" ");
valueFound = true;
} else if (type === "address") {
const addressIndex = parts.findIndex(
(part, idx) =>
Expand All @@ -112,10 +125,6 @@ export function extractCommandValues(
usedIndices.add(index);
valueFound = true;
}
} else if (param === "prompt") {
// Extract everything after the command as the prompt
values.params[param] = parts.slice(1).join(" ");
valueFound = true;
} else {
const indices = parts.reduce<number[]>((acc, part, idx) => {
if (
Expand Down
2 changes: 1 addition & 1 deletion packages/message-kit/src/helpers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export type Config = {
};
export interface CommandParamConfig {
default?: any;
type: "number" | "string" | "username" | "quoted" | "address";
type: "number" | "string" | "username" | "quoted" | "address" | "prompt";
values?: string[]; // Accepted values for the parameter
}

Expand Down
11 changes: 10 additions & 1 deletion packages/message-kit/src/tests/Commands.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import "dotenv/config";
import { commands } from "./commands";
import { fakeUsers as users } from "../helpers/usernames";
import { textGeneration } from "../helpers/openai";
import { extractCommandValues } from "../helpers/commands";

describe("Command extraction tests", () => {
test("Extract values from /help2 command", () => {
const inputContent = "/help2 hey";
const extractedValues = extractCommandValues(inputContent, commands, users);
expect(extractedValues).toEqual({
command: "help2",
params: expect.objectContaining({
cmd: "hey",
}),
});
});
test("Extract values from /tip command", () => {
const inputContent = "/tip @bo @alix 15";
const extractedValues = extractCommandValues(inputContent, commands, users);
Expand Down
21 changes: 19 additions & 2 deletions packages/message-kit/src/tests/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,18 +153,35 @@ export const commands: CommandGroup[] = [
},
],
},
{
name: "General Commands",
icon: "🔧",
description: "Command for managing default behaviours.",
commands: [
{
command: "/help2 [cmd]",
description: "Manage agent commands.",
params: {
cmd: {
default: "",
type: "string",
},
},
},
],
},
{
name: "Agent",
icon: "🤖",
description: "Manage agent commands.",
commands: [
{
command: "/agent [type]",
command: "/agent [prompt]",
description: "Manage agent commands.",
params: {
prompt: {
default: "",
type: "string",
type: "prompt",
},
},
},
Expand Down

0 comments on commit 0251788

Please sign in to comment.