Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.2.33 #161

Merged
merged 31 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 0 additions & 209 deletions .cursorrules
Original file line number Diff line number Diff line change
@@ -1,209 +0,0 @@
# MessageKit

# Skill Examples

### Check if a Domain is Available


import { ensUrl } from "../index.js";
import { Context } from "@xmtp/message-kit";
import type { Skill } from "@xmtp/message-kit";

// Define Skill
export const checkDomain: Skill[] = [
{
skill: "check",
handler: handler,
examples: ["/check vitalik.eth", "/check fabri.base.eth"],
description: "Check if a domain is available.",
params: {
domain: {
type: "string",
},
},
},
];

// Handler Implementation
export async function handler(context: Context) {
const {
message: {
content: {
params: { domain },
},
},
} = context;

const data = await getUserInfo(domain);

if (!data?.address) {
let message = `Looks like ${domain} is available! Here you can register it: ${ensUrl}${domain} or would you like to see some cool alternatives?`;
return {
code: 200,
message,
};
} else {
let message = `Looks like ${domain} is already registered!`;
await context.executeSkill("/cool " + domain);
return {
code: 404,
message,
};
}
}

### Generate a payment request


import { Context } from "@xmtp/message-kit";
import type { Skill } from "@xmtp/message-kit";

// Define Skill
export const paymentRequest: Skill[] = [
{
skill: "pay",
examples: [
"/pay 10 vitalik.eth",
"/pay 1 usdc to 0xC60E6Bb79322392761BFe3081E302aEB79B30B03",
],
description:
"Send a specified amount of a cryptocurrency to a destination address. \nWhen tipping, you can assume it's 1 USDC.",
handler: handler,
params: {
amount: {
default: 10,
type: "number",
},
token: {
default: "usdc",
type: "string",
values: ["eth", "dai", "usdc", "degen"], // Accepted tokens
},
username: {
default: "",
type: "username",
},
address: {
default: "",
type: "address",
},
},
},
];

// Handler Implementation
export async function handler(context: Context) {
const {
message: {
content: {
params: { amount, token, username, address },
},
},
} = context;
let receiverAddress = address;
if (username) {
receiverAddress = (await getUserInfo(username))?.address;
}
if (address) {
// Prioritize address over username
receiverAddress = address;
}

await context.framekit.requestPayment(receiverAddress, amount, token);
}


# Docs

# Structure

## File structure

Each app consists of the following files:

```
agent/
├── src/
│ └── index.ts
│ └── prompt.ts # Optional
│ └── plugins/ # Optional
│ └── ...
│ └── skills/ # Optional
│ └── ...
│ └── vibes/ # Optional
│ └── ...
├── tsconfig.json
├── package.json
└── .env
```

## Agent

This is the main function that runs the listener.

```jsx
import { Agent, run, Context } from "@xmtp/message-kit";

const agent: Agent = {
name: "Agent Name",
tag: "@bot",
description: "Agent Description",
skills: [skill1, skill2],
onMessage: async (context: Context) => {
/* Logs every message in a conversation.
If not declared, the agent will automatically use the defined skills.
Alternatively, you can implement your own logic here. */
},
config: {
// Optional parameters
},
};
//starts the agent
run(agent);
```

#### Config parameters

- `privateKey`: the private key of the agent wallet, like any normal wallet private key.
- `experimental`: experimental features like logging all group messages. Default is `false`.
- `attachments`: to receive attachments. Default is `false`.
- `gptModel`: model to be used. Default is `gpt-4o`.
- `client`: Optional parameters to pass to the XMTP client.
- `agent`: Custom agent to be used. Default is to create the skills in the `src/skills.ts` file.
- `hideInitLogMessage`: hide the init log message with messagekit logo and stuff
- `memberChange`: if true, member changes will be enabled, like adding members to the group

## Skills

Skills are the actions of the agent. They are defined in the `src/skills/your-skill.ts` file.

```tsx
import { Skill } from "@xmtp/message-kit";

export const checkDomain: Skill[] = [
{
skill: // name of the skill
handler: // function to handle the skill
examples: // examples of the skill
description: // description of the skill
params: // params of the skill
},
];
```

## Vibes

Vibes are the personalities of the agent. They are defined in the `src/vibes/your-vibe.ts` file.

```tsx
import { Vibe } from "@xmtp/message-kit";

export const chill: Vibe = {
vibe: // name of the vibe
description: // description of the vibe
tone: // tone of the vibe
style: // style of the vibe
};
```

> See [Vibes](/community/vibes) for more information.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "message-kit-monorepo",
"version": "1.2.32",
"version": "1.2.33",
"private": true,
"type": "module",
"workspaces": [
Expand Down
2 changes: 1 addition & 1 deletion packages/create-message-kit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { default as fs } from "fs-extra";
import { isCancel } from "@clack/prompts";
import { detect } from "detect-package-manager";
import pc from "picocolors";
const defVersion = "1.2.32";
const defVersion = "1.2.33";
const __dirname = dirname(fileURLToPath(import.meta.url));

// Read package.json to get the version
Expand Down
2 changes: 1 addition & 1 deletion packages/create-message-kit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-message-kit",
"version": "1.2.32",
"version": "1.2.33",
"license": "MIT",
"type": "module",
"main": "index.js",
Expand Down
42 changes: 42 additions & 0 deletions packages/docs/pages/plugins/circle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,48 @@

The `WalletService` class in MessageKit provides a way to create agent wallets that can perform gasless payments and transfers on Base.

- Gasless
- Onramp
- Offramp
- Swaps
- Transfers

## Wallet Management

The `getWallet` method will retrieve an existing wallet or create a new one if it doesn't exist:

```tsx
// Get the wallet service
const { walletService } = context;

// Get or create a wallet
const wallet = await walletService.getWallet(identifier or address);

// Explicitly create a new wallet
const isCreated = await walletService.createWallet(identifier or address);

// Delete a wallet
await walletService.deleteWallet(identifier or address);
Comment on lines +20 to +26
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve parameter documentation in code examples.

The parameter identifier or address is ambiguous. Consider documenting the expected format and type of each parameter.

 // Get or create a wallet
-const wallet = await walletService.getWallet(identifier or address);
+const wallet = await walletService.getWallet(identifierOrAddress: string);
 
 // Explicitly create a new wallet
-const isCreated = await walletService.createWallet(identifier or address);
+const isCreated = await walletService.createWallet(identifierOrAddress: string);
 
 // Delete a wallet
-await walletService.deleteWallet(identifier or address);
+await walletService.deleteWallet(identifierOrAddress: string);

Consider adding a Properties section:

Properties:
- `identifierOrAddress`: (string) The wallet identifier or Ethereum address
Returns:
- `wallet`: (WalletResponse) The wallet object containing address and balance
- `isCreated`: (boolean) Whether the wallet was created successfully

```

## Actions

Perform actions on the Agent Wallet like transfers and swaps or checking the balance.

```tsx
// Get the wallet service
const { walletService } = context;

// Check balance
const { address, balance } = await walletService.checkBalance(identifier or address);

// Transfer between wallets
await walletService.transfer(identifier or address, identifier or address, amount);

// Swap assets (USDC and ETH)
await walletService.swap(identifier or address, fromAssetId, toAssetId, amount);
Comment on lines +37 to +44
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling examples and return type documentation.

The code examples should include error handling and document the return types for better developer experience.

 // Check balance
-const { address, balance } = await walletService.checkBalance(identifier or address);
+try {
+  const { address, balance } = await walletService.checkBalance(identifierOrAddress);
+  // balance is in wei (1e18)
+} catch (error) {
+  if (error instanceof WalletNotFoundError) {
+    // Handle wallet not found
+  }
+}

 // Transfer between wallets
-await walletService.transfer(identifier or address, identifier or address, amount);
+try {
+  const txHash = await walletService.transfer(
+    fromAddress: string,
+    toAddress: string,
+    amount: BigNumber
+  );
+} catch (error) {
+  // Handle insufficient funds or network errors
+}

 // Swap assets (USDC and ETH)
-await walletService.swap(identifier or address, fromAssetId, toAssetId, amount);
+try {
+  const txHash = await walletService.swap(
+    address: string,
+    fromAssetId: string,
+    toAssetId: string,
+    amount: BigNumber
+  );
+} catch (error) {
+  // Handle insufficient liquidity or price impact errors
+}

Committable suggestion skipped: line range outside the PR's diff.

```

## Requirements

Visit the [Circle Developer Portal](https://developer.circle.com/) to create an API key and entity secret.
Expand Down
55 changes: 47 additions & 8 deletions packages/docs/pages/plugins/framekit.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ You can request payments using the payment frame:

```typescript
// Request 1 USDC payment to a specific address
await framekit.requestPayment(recipientAddress, 1, "USDC");
const url = await FrameKit.requestPayment(recipientAddress, 1, "USDC");

// Send the url to the user
await context.send(url);
```

## Wallet details
Expand All @@ -22,7 +25,12 @@ You can send agent wallet info using the `sendWallet` method:

```typescript
// Send agent wallet info
await framekit.sendWallet("0x93E2fc3e99dFb1238eB9e0eF2580EFC5809C7204");
const url = await FrameKit.sendWallet(
"0x93E2fc3e99dFb1238eB9e0eF2580EFC5809C7204",
);

// Send the url to the user
await context.send(url);
```

Properties:
Expand All @@ -37,24 +45,52 @@ You can request receipts using the receipt frame:

```typescript
// Request a receipt
await framekit.sendReceipt(urlOfTransaction);
// ie https://sepolia.basescan.org/tx/0x1234567890abcdef
const url = await FrameKit.sendReceipt(urlOfTransaction);

// Send the url to the user
await context.send(url);
```

Properties:

- `url`: URL of the transaction receipt scanner like basescan, etherscan, etc.

## Dm and Groups on Converse
## Converse

You can send messages to a user or group on Converse using the `sendConverseDmFrame` and `sendConverseGroupFrame` methods.

```typescript
// Send a message to a user
const url = await FrameKit.converseLink(userAddress);

// Send the url to the user
await context.send(url);

// Send a message to a user with an optional pretext
await framekit.sendConverseDmFrame("userAddress", "Hello, how are you?");
const url = await FrameKit.converseLink(userAddress, "Hello, how are you?");

// Send the url to the user
await context.send(url);

// Send a message to a group
const url = await FrameKit.converseGroup(groupId);

// Send a message to a group with an optional pretext
await framekit.sendConverseGroupFrame("groupId", "gm all!");
const url = await FrameKit.converseGroup(groupId, "gm all!");

// Send the url to the user
await context.send(url);
```

## Coinbase

:::warning
Coinbase does not render frames but you can deeplink into other users inside the wallet.
:::

```typescript
// Send a message to a user with an optional pretext
await context.coinbaseLink(userAddress);
```

## Custom
Expand All @@ -79,7 +115,10 @@ const frame = {
image: "https://example.com/weather.png",
};

await framekit.sendCustomFrame(frame);
const url = await FrameKit.sendCustomFrame(frame);

// Send the url to the user
await context.send(url);
```

Properties:
Expand Down
1 change: 1 addition & 0 deletions packages/docs/pages/plugins/resolver.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ The resolver returns a `UserInfo` object containing:
The resolver implements automatic caching to improve performance and reduce API calls. You can manage the cache using:

```typescript
// Clear cache for specific address
context.clearCache(address);

// or import directly
Expand Down
Loading
Loading