mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-05-13 23:16:55 +00:00
feat: Implement framework-independent Action interface (#72)
This PR implements a framework-independent Action interface inspired by Eliza, making the tools more flexible and reusable across different frameworks. Changes: - Created independent actions under `src/actions/` - Implemented Zod validation for type safety - Converted all LangChain tools to use actions - Added natural language matching with similes - Improved error handling and response formats
This commit is contained in:
@@ -53,7 +53,8 @@
|
||||
"form-data": "^4.0.1",
|
||||
"langchain": "^0.3.8",
|
||||
"openai": "^4.77.0",
|
||||
"typedoc": "^0.27.6"
|
||||
"typedoc": "^0.27.6",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bn.js": "^5.1.6",
|
||||
|
||||
21
pnpm-lock.yaml
generated
21
pnpm-lock.yaml
generated
@@ -107,6 +107,9 @@ importers:
|
||||
typedoc:
|
||||
specifier: ^0.27.6
|
||||
version: 0.27.6(typescript@5.7.2)
|
||||
zod:
|
||||
specifier: ^3.24.1
|
||||
version: 3.24.1
|
||||
devDependencies:
|
||||
'@types/bn.js':
|
||||
specifier: ^5.1.6
|
||||
@@ -588,15 +591,9 @@ packages:
|
||||
'@shikijs/engine-javascript@1.24.4':
|
||||
resolution: {integrity: sha512-TClaQOLvo9WEMJv6GoUsykQ6QdynuKszuORFWCke8qvi6PeLm7FcD9+7y45UenysxEWYpDL5KJaVXTngTE+2BA==}
|
||||
|
||||
'@shikijs/engine-oniguruma@1.24.3':
|
||||
resolution: {integrity: sha512-iNnx950gs/5Nk+zrp1LuF+S+L7SKEhn8k9eXgFYPGhVshKppsYwRmW8tpmAMvILIMSDfrgqZ0w+3xWVQB//1Xw==}
|
||||
|
||||
'@shikijs/engine-oniguruma@1.24.4':
|
||||
resolution: {integrity: sha512-Do2ry6flp2HWdvpj2XOwwa0ljZBRy15HKZITzPcNIBOGSeprnA8gOooA/bLsSPuy8aJBa+Q/r34dMmC3KNL/zw==}
|
||||
|
||||
'@shikijs/types@1.24.3':
|
||||
resolution: {integrity: sha512-FPMrJ69MNxhRtldRk69CghvaGlbbN3pKRuvko0zvbfa2dXp4pAngByToqS5OY5jvN8D7LKR4RJE8UvzlCOuViw==}
|
||||
|
||||
'@shikijs/types@1.24.4':
|
||||
resolution: {integrity: sha512-0r0XU7Eaow0PuDxuWC1bVqmWCgm3XqizIaT7SM42K03vc69LGooT0U8ccSR44xP/hGlNx4FKhtYpV+BU6aaKAA==}
|
||||
|
||||
@@ -2724,7 +2721,7 @@ snapshots:
|
||||
|
||||
'@gerrit0/mini-shiki@1.24.4':
|
||||
dependencies:
|
||||
'@shikijs/engine-oniguruma': 1.24.3
|
||||
'@shikijs/engine-oniguruma': 1.24.4
|
||||
'@shikijs/types': 1.24.4
|
||||
'@shikijs/vscode-textmate': 9.3.1
|
||||
|
||||
@@ -3273,21 +3270,11 @@ snapshots:
|
||||
'@shikijs/vscode-textmate': 9.3.1
|
||||
oniguruma-to-es: 0.8.1
|
||||
|
||||
'@shikijs/engine-oniguruma@1.24.3':
|
||||
dependencies:
|
||||
'@shikijs/types': 1.24.3
|
||||
'@shikijs/vscode-textmate': 9.3.1
|
||||
|
||||
'@shikijs/engine-oniguruma@1.24.4':
|
||||
dependencies:
|
||||
'@shikijs/types': 1.24.4
|
||||
'@shikijs/vscode-textmate': 9.3.1
|
||||
|
||||
'@shikijs/types@1.24.3':
|
||||
dependencies:
|
||||
'@shikijs/vscode-textmate': 9.3.1
|
||||
'@types/hast': 3.0.4
|
||||
|
||||
'@shikijs/types@1.24.4':
|
||||
dependencies:
|
||||
'@shikijs/vscode-textmate': 9.3.1
|
||||
|
||||
62
src/actions/balance.ts
Normal file
62
src/actions/balance.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { get_balance } from "../tools";
|
||||
|
||||
const balanceAction: Action = {
|
||||
name: "solana_balance",
|
||||
similes: [
|
||||
"check balance",
|
||||
"get wallet balance",
|
||||
"view balance",
|
||||
"show balance",
|
||||
"check token balance",
|
||||
],
|
||||
description: `Get the balance of a Solana wallet or token account.
|
||||
If you want to get the balance of your wallet, you don't need to provide the tokenAddress.
|
||||
If no tokenAddress is provided, the balance will be in SOL.`,
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {},
|
||||
output: {
|
||||
status: "success",
|
||||
balance: "100",
|
||||
token: "SOL",
|
||||
},
|
||||
explanation: "Get SOL balance of the wallet",
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
input: {
|
||||
tokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
balance: "1000",
|
||||
token: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
},
|
||||
explanation: "Get USDC token balance",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
tokenAddress: z.string().optional(),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
const balance = await get_balance(
|
||||
agent,
|
||||
input.tokenAddress && new PublicKey(input.tokenAddress),
|
||||
);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
balance: balance,
|
||||
token: input.tokenAddress || "SOL",
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export default balanceAction;
|
||||
104
src/actions/compressedAirdrop.ts
Normal file
104
src/actions/compressedAirdrop.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { sendCompressedAirdrop } from "../tools";
|
||||
|
||||
const compressedAirdropAction: Action = {
|
||||
name: "solana_compressed_airdrop",
|
||||
similes: [
|
||||
"ZK Compressed airdrop",
|
||||
"Airdrop tokens with compression",
|
||||
"Send compressed SPL airdrop",
|
||||
"Airdrop to multiple recipients",
|
||||
],
|
||||
description:
|
||||
"Airdrop SPL tokens with ZK Compression (also known as airdropping tokens) to multiple recipients",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
mintAddress: "JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN",
|
||||
amount: 42,
|
||||
decimals: 6,
|
||||
recipients: [
|
||||
"1nc1nerator11111111111111111111111111111111",
|
||||
"BrFndAe111111111111111111111111111111111",
|
||||
],
|
||||
priorityFeeInLamports: 30000,
|
||||
shouldLog: true,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
message: "Airdropped 42 tokens to 2 recipients.",
|
||||
transactionHashes: ["4uyfBN...", "9XsF2N..."],
|
||||
},
|
||||
explanation:
|
||||
"Airdrops 42 tokens (with 6 decimals) to 2 recipients, optionally logging progress to stdout.",
|
||||
},
|
||||
],
|
||||
],
|
||||
// Validate inputs with zod
|
||||
schema: z.object({
|
||||
mintAddress: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("Mint address of the token, e.g., 'JUPy...'"),
|
||||
amount: z
|
||||
.number()
|
||||
.positive()
|
||||
.describe("Number of tokens to airdrop per recipient, e.g., 42"),
|
||||
decimals: z
|
||||
.number()
|
||||
.nonnegative()
|
||||
.int()
|
||||
.describe("Decimals of the token, e.g., 6"),
|
||||
recipients: z
|
||||
.array(z.string())
|
||||
.nonempty()
|
||||
.describe("Array of recipient addresses, e.g., ['1nc1n...']"),
|
||||
priorityFeeInLamports: z
|
||||
.number()
|
||||
.optional()
|
||||
.describe("Priority fee in lamports (default is 30_000)"),
|
||||
shouldLog: z
|
||||
.boolean()
|
||||
.optional()
|
||||
.describe("Whether to log progress to stdout (default is false)"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const {
|
||||
mintAddress,
|
||||
amount,
|
||||
decimals,
|
||||
recipients,
|
||||
priorityFeeInLamports,
|
||||
shouldLog,
|
||||
} = input;
|
||||
|
||||
// Call your airdrop method on the SolanaAgentKit
|
||||
const txs = await sendCompressedAirdrop(
|
||||
mintAddress,
|
||||
amount,
|
||||
decimals,
|
||||
recipients,
|
||||
priorityFeeInLamports || 30_000,
|
||||
shouldLog || false,
|
||||
);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
message: `Airdropped ${amount} tokens to ${recipients.length} recipients.`,
|
||||
transactionHashes: txs,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to airdrop tokens: ${error.message}`,
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default compressedAirdropAction;
|
||||
86
src/actions/createGibworkTask.ts
Normal file
86
src/actions/createGibworkTask.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { create_gibwork_task } from "../tools";
|
||||
|
||||
const createGibworkTaskAction: Action = {
|
||||
name: "solana_create_gibwork_task",
|
||||
similes: [
|
||||
"create task",
|
||||
"post job",
|
||||
"create gig",
|
||||
"post task",
|
||||
"create work",
|
||||
"new task on gibwork",
|
||||
],
|
||||
description:
|
||||
"Create a new task on the Gibwork platform with payment in SPL tokens",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
title: "Build a Solana dApp",
|
||||
content: "Create a simple Solana dApp with React frontend",
|
||||
requirements: "Experience with Rust and React",
|
||||
tags: ["solana", "rust", "react"],
|
||||
tokenMintAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
tokenAmount: 100,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
taskId: "task_123",
|
||||
signature: "3YKpM1...",
|
||||
message: "Successfully created task: Build a Solana dApp",
|
||||
},
|
||||
explanation: "Create a new task on Gibwork with 100 USDC payment",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
title: z.string().min(1).describe("Title of the task"),
|
||||
content: z.string().min(1).describe("Description of the task"),
|
||||
requirements: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("Requirements to complete the task"),
|
||||
tags: z
|
||||
.array(z.string())
|
||||
.min(1)
|
||||
.describe("List of tags associated with the task"),
|
||||
tokenMintAddress: z.string().describe("Token mint address for payment"),
|
||||
tokenAmount: z.number().positive().describe("Payment amount for the task"),
|
||||
payer: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Optional payer address (defaults to wallet address)"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const responseData = await create_gibwork_task(
|
||||
agent,
|
||||
input.title,
|
||||
input.content,
|
||||
input.requirements,
|
||||
input.tags,
|
||||
new PublicKey(input.tokenMintAddress),
|
||||
input.tokenAmount,
|
||||
input.payer ? new PublicKey(input.payer) : undefined,
|
||||
);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
taskId: responseData.taskId,
|
||||
signature: responseData.signature,
|
||||
message: `Successfully created task: ${input.title}`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to create task: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default createGibworkTaskAction;
|
||||
101
src/actions/createImage.ts
Normal file
101
src/actions/createImage.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { create_image } from "../tools/create_image";
|
||||
|
||||
const createImageAction: Action = {
|
||||
name: "solana_create_image",
|
||||
similes: [
|
||||
"generate image",
|
||||
"create artwork",
|
||||
"make image",
|
||||
"generate artwork",
|
||||
"create picture",
|
||||
"generate picture",
|
||||
],
|
||||
description:
|
||||
"Create an AI-generated image based on a text prompt using OpenAI's DALL-E models",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
prompt: "A beautiful sunset over a mountain landscape",
|
||||
model: "dall-e-3",
|
||||
size: "1024x1024",
|
||||
quality: "standard",
|
||||
style: "natural",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
imageUrl: "https://example.com/image.png",
|
||||
message: "Successfully generated image",
|
||||
},
|
||||
explanation: "Generate an image of a sunset landscape using DALL-E 3",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
prompt: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(1000)
|
||||
.describe("The text description of the image to generate"),
|
||||
model: z
|
||||
.enum(["dall-e-3"])
|
||||
.default("dall-e-3")
|
||||
.describe("The AI model to use for generation"),
|
||||
size: z
|
||||
.enum(["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"])
|
||||
.default("1024x1024")
|
||||
.describe("The size of the generated image"),
|
||||
quality: z
|
||||
.enum(["standard", "hd"])
|
||||
.default("standard")
|
||||
.describe("The quality level of the generated image"),
|
||||
style: z
|
||||
.enum(["natural", "vivid"])
|
||||
.default("natural")
|
||||
.describe("The style of the generated image"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
if (!agent.config.OPENAI_API_KEY) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "OpenAI API key not found in agent configuration",
|
||||
};
|
||||
}
|
||||
|
||||
const { prompt, model, size } = input;
|
||||
const response = await create_image(agent, prompt, model, size);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
imageUrl: response.images[0].url,
|
||||
message: "Successfully generated image",
|
||||
};
|
||||
} catch (error: any) {
|
||||
// Handle specific OpenAI error types
|
||||
if (error.response) {
|
||||
const { status, data } = error.response;
|
||||
if (status === 429) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Rate limit exceeded. Please try again later.",
|
||||
};
|
||||
}
|
||||
return {
|
||||
status: "error",
|
||||
message: `OpenAI API error: ${data.error?.message || error.message}`,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to generate image: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default createImageAction;
|
||||
80
src/actions/createOpenbookMarket.ts
Normal file
80
src/actions/createOpenbookMarket.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { openbookCreateMarket } from "../tools";
|
||||
|
||||
const createOpenbookMarketAction: Action = {
|
||||
name: "solana_create_openbook_market",
|
||||
similes: [
|
||||
"create openbook market",
|
||||
"setup trading market",
|
||||
"new openbook market",
|
||||
"create trading pair",
|
||||
"setup dex market",
|
||||
"new trading market",
|
||||
],
|
||||
description: "Create a new trading market on Openbook DEX",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
baseMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC
|
||||
quoteMint: "So11111111111111111111111111111111111111112", // SOL
|
||||
lotSize: 1,
|
||||
tickSize: 0.01,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
signatures: ["2ZE7Rz...", "3YKpM1..."],
|
||||
message: "Successfully created Openbook market",
|
||||
},
|
||||
explanation:
|
||||
"Create a new USDC/SOL market on Openbook with default lot and tick sizes",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
baseMint: z.string().min(1).describe("The base token's mint address"),
|
||||
quoteMint: z.string().min(1).describe("The quote token's mint address"),
|
||||
lotSize: z
|
||||
.number()
|
||||
.positive()
|
||||
.default(1)
|
||||
.describe("The minimum order size (lot size)"),
|
||||
tickSize: z
|
||||
.number()
|
||||
.positive()
|
||||
.default(0.01)
|
||||
.describe("The minimum price increment (tick size)"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const baseMint = new PublicKey(input.baseMint);
|
||||
const quoteMint = new PublicKey(input.quoteMint);
|
||||
const lotSize = input.lotSize || 1;
|
||||
const tickSize = input.tickSize || 0.01;
|
||||
|
||||
const signatures = await openbookCreateMarket(
|
||||
agent,
|
||||
baseMint,
|
||||
quoteMint,
|
||||
lotSize,
|
||||
tickSize,
|
||||
);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
signatures,
|
||||
message: "Successfully created Openbook market",
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to create Openbook market: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default createOpenbookMarketAction;
|
||||
117
src/actions/createOrcaSingleSidedWhirlpool.ts
Normal file
117
src/actions/createOrcaSingleSidedWhirlpool.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { BN } from "@coral-xyz/anchor";
|
||||
import { Decimal } from "decimal.js";
|
||||
import { orcaCreateSingleSidedLiquidityPool } from "../tools";
|
||||
|
||||
// Fee tiers mapping from the original tool
|
||||
const FEE_TIERS = {
|
||||
0.01: 1,
|
||||
0.02: 2,
|
||||
0.04: 4,
|
||||
0.05: 8,
|
||||
0.16: 16,
|
||||
0.3: 64,
|
||||
0.65: 96,
|
||||
1.0: 128,
|
||||
2.0: 256,
|
||||
} as const;
|
||||
|
||||
const createOrcaSingleSidedWhirlpoolAction: Action = {
|
||||
name: "solana_create_orca_single_sided_whirlpool",
|
||||
similes: [
|
||||
"create orca whirlpool",
|
||||
"setup orca single sided pool",
|
||||
"initialize orca whirlpool",
|
||||
"create orca concentrated pool",
|
||||
"setup orca concentrated liquidity",
|
||||
"create orca trading pair",
|
||||
],
|
||||
description:
|
||||
"Create a new single-sided whirlpool on Orca with concentrated liquidity",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
depositTokenAmount: "1000000000000", // 1 million tokens with 6 decimals
|
||||
depositTokenMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC
|
||||
otherTokenMint: "So11111111111111111111111111111111111111112", // SOL
|
||||
initialPrice: "0.001",
|
||||
maxPrice: "5.0",
|
||||
feeTier: 0.3,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
signature: "2ZE7Rz...",
|
||||
message: "Successfully created Orca single-sided whirlpool",
|
||||
},
|
||||
explanation:
|
||||
"Create a USDC/SOL whirlpool with 1M USDC initial liquidity",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
depositTokenAmount: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe(
|
||||
"The amount of deposit token to provide as liquidity (including decimals)",
|
||||
),
|
||||
depositTokenMint: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("The mint address of the token being deposited"),
|
||||
otherTokenMint: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("The mint address of the other token in the pool"),
|
||||
initialPrice: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("Initial price of deposit token in terms of the other token"),
|
||||
maxPrice: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("Maximum price at which liquidity is added"),
|
||||
feeTier: z
|
||||
.number()
|
||||
.refine((val) => val in FEE_TIERS, "Invalid fee tier")
|
||||
.describe("Fee tier percentage for the pool (e.g., 0.3 for 0.3%)"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const depositTokenAmount = Number(input.depositTokenAmount);
|
||||
const depositTokenMint = new PublicKey(input.depositTokenMint);
|
||||
const otherTokenMint = new PublicKey(input.otherTokenMint);
|
||||
const initialPrice = new Decimal(input.initialPrice);
|
||||
const maxPrice = new Decimal(input.maxPrice);
|
||||
const feeTier = input.feeTier
|
||||
|
||||
// Create the whirlpool
|
||||
const signature = await orcaCreateSingleSidedLiquidityPool(
|
||||
agent,
|
||||
depositTokenAmount,
|
||||
depositTokenMint,
|
||||
otherTokenMint,
|
||||
initialPrice,
|
||||
maxPrice,
|
||||
feeTier,
|
||||
);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
signature,
|
||||
message: "Successfully created Orca single-sided whirlpool",
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to create whirlpool: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default createOrcaSingleSidedWhirlpoolAction;
|
||||
78
src/actions/deployCollection.ts
Normal file
78
src/actions/deployCollection.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { deploy_collection } from "../tools";
|
||||
|
||||
interface CollectionOptions {
|
||||
name: string;
|
||||
uri: string;
|
||||
royaltyBasisPoints?: number;
|
||||
}
|
||||
|
||||
const deployCollectionAction: Action = {
|
||||
name: "solana_deploy_collection",
|
||||
similes: [
|
||||
"create collection",
|
||||
"launch collection",
|
||||
"deploy nft collection",
|
||||
"create nft collection",
|
||||
"mint collection",
|
||||
],
|
||||
description: `Deploy a new NFT collection on Solana blockchain.`,
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
name: "My Collection",
|
||||
uri: "https://example.com/collection.json",
|
||||
royaltyBasisPoints: 500,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
message: "Collection deployed successfully",
|
||||
collectionAddress: "7nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkN",
|
||||
name: "My Collection",
|
||||
},
|
||||
explanation: "Deploy an NFT collection with 5% royalty",
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
input: {
|
||||
name: "Basic Collection",
|
||||
uri: "https://example.com/basic.json",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
message: "Collection deployed successfully",
|
||||
collectionAddress: "8nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkM",
|
||||
name: "Basic Collection",
|
||||
},
|
||||
explanation: "Deploy a basic NFT collection without royalties",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
name: z.string().min(1, "Name is required"),
|
||||
uri: z.string().url("URI must be a valid URL"),
|
||||
royaltyBasisPoints: z.number().min(0).max(10000).optional(),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
const options: CollectionOptions = {
|
||||
name: input.name,
|
||||
uri: input.uri,
|
||||
royaltyBasisPoints: input.royaltyBasisPoints,
|
||||
};
|
||||
|
||||
const result = await deploy_collection(agent, options);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
message: "Collection deployed successfully",
|
||||
collectionAddress: result.collectionAddress.toString(),
|
||||
name: input.name,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export default deployCollectionAction;
|
||||
83
src/actions/deployToken.ts
Normal file
83
src/actions/deployToken.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { deploy_token } from "../tools";
|
||||
|
||||
const deployTokenAction: Action = {
|
||||
name: "deploy_token",
|
||||
similes: [
|
||||
"create token",
|
||||
"launch token",
|
||||
"deploy new token",
|
||||
"create new token",
|
||||
"mint token",
|
||||
],
|
||||
description:
|
||||
"Deploy a new SPL token on the Solana blockchain with specified parameters",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
name: "My Token",
|
||||
uri: "https://example.com/token.json",
|
||||
symbol: "MTK",
|
||||
decimals: 9,
|
||||
initialSupply: 1000000,
|
||||
},
|
||||
output: {
|
||||
mint: "7nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkN",
|
||||
status: "success",
|
||||
message: "Token deployed successfully",
|
||||
},
|
||||
explanation: "Deploy a token with initial supply and metadata",
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
input: {
|
||||
name: "Basic Token",
|
||||
uri: "https://example.com/basic.json",
|
||||
symbol: "BASIC",
|
||||
},
|
||||
output: {
|
||||
mint: "8nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkM",
|
||||
status: "success",
|
||||
message: "Token deployed successfully",
|
||||
},
|
||||
explanation: "Deploy a basic token with minimal parameters",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
name: z.string().min(1, "Name is required"),
|
||||
uri: z.string().url("URI must be a valid URL"),
|
||||
symbol: z.string().min(1, "Symbol is required"),
|
||||
decimals: z.number().optional(),
|
||||
initialSupply: z.number().optional(),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const result = await deploy_token(
|
||||
agent,
|
||||
input.name,
|
||||
input.uri,
|
||||
input.symbol,
|
||||
input.decimals,
|
||||
input.initialSupply,
|
||||
);
|
||||
|
||||
return {
|
||||
mint: result.mint.toString(),
|
||||
status: "success",
|
||||
message: "Token deployed successfully",
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Token deployment failed: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default deployTokenAction;
|
||||
57
src/actions/fetchPrice.ts
Normal file
57
src/actions/fetchPrice.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { fetchPrice } from "../tools";
|
||||
|
||||
const fetchPriceAction: Action = {
|
||||
name: "solana_fetch_price",
|
||||
similes: [
|
||||
"get token price",
|
||||
"check price",
|
||||
"token value",
|
||||
"price check",
|
||||
"get price in usd",
|
||||
],
|
||||
description:
|
||||
"Fetch the current price of a Solana token in USDC using Jupiter API",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
tokenAddress: "So11111111111111111111111111111111111111112",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
price: "23.45",
|
||||
message: "Current price: $23.45 USDC",
|
||||
},
|
||||
explanation: "Get the current price of SOL token in USDC",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
tokenAddress: z
|
||||
.string()
|
||||
.describe("The mint address of the token to fetch the price for"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const tokenId = new PublicKey(input.tokenAddress);
|
||||
const price = await fetchPrice(tokenId);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
price,
|
||||
message: `Current price: $${price} USDC`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to fetch price: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default fetchPriceAction;
|
||||
52
src/actions/getAllDomainsTLDs.ts
Normal file
52
src/actions/getAllDomainsTLDs.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { getAllDomainsTLDs } from "../tools";
|
||||
|
||||
const getAllDomainsTLDsAction: Action = {
|
||||
name: "solana_get_all_tlds",
|
||||
similes: [
|
||||
"list domain tlds",
|
||||
"get domain extensions",
|
||||
"fetch domain tlds",
|
||||
"get top level domains",
|
||||
"list available tlds",
|
||||
"get domain suffixes",
|
||||
],
|
||||
description:
|
||||
"Get a list of all available top-level domains (TLDs) for Solana domains",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {},
|
||||
output: {
|
||||
status: "success",
|
||||
tlds: [".sol", ".abc", ".backpack", ".bonk"],
|
||||
message: "Successfully retrieved all domain TLDs",
|
||||
},
|
||||
explanation:
|
||||
"Get a list of all available TLDs that can be used for Solana domains",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({}),
|
||||
handler: async (agent: SolanaAgentKit) => {
|
||||
try {
|
||||
// Get all domain TLDs
|
||||
const tlds = await getAllDomainsTLDs(agent);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
tlds,
|
||||
message: "Successfully retrieved all domain TLDs",
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to get domain TLDs: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default getAllDomainsTLDsAction;
|
||||
70
src/actions/getAllRegisteredAllDomains.ts
Normal file
70
src/actions/getAllRegisteredAllDomains.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { getAllRegisteredAllDomains } from "../tools";
|
||||
|
||||
const getAllRegisteredAllDomainsAction: Action = {
|
||||
name: "solana_get_all_registered_all_domains",
|
||||
similes: [
|
||||
"list registered domains",
|
||||
"get all domains",
|
||||
"fetch registered domains",
|
||||
"get domain list",
|
||||
"list active domains",
|
||||
"get registered names",
|
||||
],
|
||||
description: "Get a list of all registered domains across all TLDs",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
limit: 100,
|
||||
offset: 0,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
domains: ["solana.sol", "bonk.abc", "wallet.backpack"],
|
||||
total: 3,
|
||||
message: "Successfully retrieved registered domains",
|
||||
},
|
||||
explanation: "Get the first 100 registered domains across all TLDs",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
limit: z
|
||||
.number()
|
||||
.positive()
|
||||
.max(1000)
|
||||
.default(100)
|
||||
.describe("Maximum number of domains to return"),
|
||||
offset: z
|
||||
.number()
|
||||
.nonnegative()
|
||||
.default(0)
|
||||
.describe("Number of domains to skip"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const limit = input.limit || 100;
|
||||
const offset = input.offset || 0;
|
||||
|
||||
// Get all registered domains
|
||||
const domains = await getAllRegisteredAllDomains(agent);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
domains: domains.slice(offset, offset + limit),
|
||||
total: domains.length,
|
||||
message: "Successfully retrieved registered domains",
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to get registered domains: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default getAllRegisteredAllDomainsAction;
|
||||
67
src/actions/getMainAllDomainsDomain.ts
Normal file
67
src/actions/getMainAllDomainsDomain.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { getMainAllDomainsDomain } from "../tools";
|
||||
|
||||
const getMainAllDomainsDomainAction: Action = {
|
||||
name: "solana_get_main_domain",
|
||||
similes: [
|
||||
"get main domain",
|
||||
"fetch primary domain",
|
||||
"get default domain",
|
||||
"get main address name",
|
||||
"get primary name",
|
||||
"get main domain name",
|
||||
],
|
||||
description: "Get the main domain associated with a wallet address",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
address: "7nxQB...",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
domain: "solana.sol",
|
||||
message: "Successfully retrieved main domain",
|
||||
},
|
||||
explanation: "Get the main domain name for a given wallet address",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
address: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("The wallet address to get the main domain for"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const mainDomain = await getMainAllDomainsDomain(
|
||||
agent,
|
||||
new PublicKey(input.address),
|
||||
);
|
||||
|
||||
if (!mainDomain) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "No main domain found for this address",
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
domain: mainDomain,
|
||||
message: "Successfully retrieved main domain",
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to get main domain: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default getMainAllDomainsDomainAction;
|
||||
63
src/actions/getOwnedAllDomains.ts
Normal file
63
src/actions/getOwnedAllDomains.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { getOwnedAllDomains } from "../tools";
|
||||
|
||||
const getOwnedAllDomainsAction: Action = {
|
||||
name: "solana_get_owned_all_domains",
|
||||
similes: [
|
||||
"list owned domains",
|
||||
"get my domains",
|
||||
"fetch wallet domains",
|
||||
"get owned names",
|
||||
"list my domains",
|
||||
"get address domains",
|
||||
],
|
||||
description:
|
||||
"Get all domains owned by a specific wallet address across all TLDs",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
address: "7nxQB...",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
domains: ["solana.sol", "wallet.abc", "user.backpack"],
|
||||
total: 3,
|
||||
message: "Successfully retrieved owned domains",
|
||||
},
|
||||
explanation: "Get all domain names owned by a specific wallet address",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
address: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("The wallet address to get owned domains for"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const address = new PublicKey(input.address);
|
||||
|
||||
// Get owned domains
|
||||
const domains = await getOwnedAllDomains(agent, address);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
domains,
|
||||
total: domains.length,
|
||||
message: `Successfully retrieved ${domains.length} owned domain${domains.length === 1 ? "" : "s"}`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to get owned domains: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default getOwnedAllDomainsAction;
|
||||
63
src/actions/getOwnedDomainsForTLD.ts
Normal file
63
src/actions/getOwnedDomainsForTLD.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { getOwnedDomainsForTLD } from "../tools";
|
||||
|
||||
const getOwnedDomainsForTLDAction: Action = {
|
||||
name: "solana_get_owned_tld_domains",
|
||||
similes: [
|
||||
"list owned domains for tld",
|
||||
"get my domains for extension",
|
||||
"fetch wallet domains by tld",
|
||||
"get owned names by extension",
|
||||
"list my domains by tld",
|
||||
"get address domains for tld",
|
||||
],
|
||||
description:
|
||||
"Get all domains owned by a specific wallet address for a given top-level domain (TLD)",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
tld: "sol",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
domains: ["solana.sol", "wallet.sol", "user.sol"],
|
||||
total: 3,
|
||||
message: "Successfully retrieved owned domains for .sol",
|
||||
},
|
||||
explanation:
|
||||
"Get all .sol domain names owned by a specific wallet address",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
tld: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("The top-level domain to filter by (e.g., 'sol', 'abc')"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const tld = input.tld.toLowerCase();
|
||||
|
||||
// Get owned domains for TLD
|
||||
const domains = await getOwnedDomainsForTLD(agent, tld);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
domains,
|
||||
total: domains.length,
|
||||
message: `Successfully retrieved ${domains.length} owned domain${domains.length === 1 ? "" : "s"} for .${tld}`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to get owned domains: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default getOwnedDomainsForTLDAction;
|
||||
57
src/actions/getPrimaryDomain.ts
Normal file
57
src/actions/getPrimaryDomain.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { getPrimaryDomain } from "../tools";
|
||||
|
||||
const getPrimaryDomainAction: Action = {
|
||||
name: "solana_get_domain",
|
||||
similes: [
|
||||
"get primary domain",
|
||||
"lookup primary domain",
|
||||
"check primary domain",
|
||||
"find primary domain",
|
||||
"get main domain",
|
||||
"primary sol domain",
|
||||
],
|
||||
description:
|
||||
"Get the primary .sol domain associated with a Solana wallet address",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
account: "7nxQB...",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
domain: "vitalik.sol",
|
||||
message: "Primary domain: vitalik.sol",
|
||||
},
|
||||
explanation: "Get the primary .sol domain for a wallet address",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
account: z.string().min(1).describe("The Solana wallet address to lookup"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const account = new PublicKey(input.account);
|
||||
|
||||
const response = await getPrimaryDomain(agent, account);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
domain: response,
|
||||
message: `Primary domain: ${response}`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to get primary domain: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default getPrimaryDomainAction;
|
||||
48
src/actions/getTPS.ts
Normal file
48
src/actions/getTPS.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { getTPS } from "../tools";
|
||||
|
||||
const getTPSAction: Action = {
|
||||
name: "solana_get_tps",
|
||||
similes: [
|
||||
"get transactions per second",
|
||||
"check network speed",
|
||||
"network performance",
|
||||
"transaction throughput",
|
||||
"network tps",
|
||||
],
|
||||
description:
|
||||
"Get the current transactions per second (TPS) of the Solana network",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {},
|
||||
output: {
|
||||
status: "success",
|
||||
tps: 3500,
|
||||
message: "Current network TPS: 3500",
|
||||
},
|
||||
explanation: "Get the current TPS of the Solana network",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({}), // No input parameters required
|
||||
handler: async (agent: SolanaAgentKit, _input: Record<string, any>) => {
|
||||
try {
|
||||
const response = await getTPS(agent);
|
||||
return {
|
||||
status: "success",
|
||||
response,
|
||||
message: `Current network TPS: ${response}`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to get TPS: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default getTPSAction;
|
||||
98
src/actions/getTokenData.ts
Normal file
98
src/actions/getTokenData.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { JupiterTokenData } from "../types";
|
||||
import { getTokenAddressFromTicker, getTokenDataByAddress } from "../tools";
|
||||
|
||||
const getTokenDataAction: Action = {
|
||||
name: "solana_token_data",
|
||||
similes: [
|
||||
"get token info",
|
||||
"token details",
|
||||
"lookup token",
|
||||
"find token",
|
||||
"token data",
|
||||
],
|
||||
description: "Get token data from either a token address or ticker symbol",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
token: {
|
||||
name: "USD Coin",
|
||||
symbol: "USDC",
|
||||
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
decimals: 6,
|
||||
},
|
||||
},
|
||||
explanation: "Get token data using the token's address",
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
input: {
|
||||
ticker: "SOL",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
token: {
|
||||
name: "Wrapped SOL",
|
||||
symbol: "SOL",
|
||||
address: "So11111111111111111111111111111111111111112",
|
||||
decimals: 9,
|
||||
},
|
||||
},
|
||||
explanation: "Get token data using the token's ticker symbol",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z
|
||||
.object({
|
||||
address: z.string().optional().describe("The token's mint address"),
|
||||
ticker: z.string().optional().describe("The token's ticker symbol"),
|
||||
})
|
||||
.refine((data) => data.address || data.ticker, {
|
||||
message: "Either address or ticker must be provided",
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
let tokenData: JupiterTokenData | undefined;
|
||||
if (input.address) {
|
||||
tokenData = await getTokenDataByAddress(new PublicKey(input.address));
|
||||
} else if (input.ticker) {
|
||||
const address = await getTokenAddressFromTicker(input.ticker);
|
||||
if (address) {
|
||||
tokenData = await getTokenDataByAddress(new PublicKey(address));
|
||||
}
|
||||
}
|
||||
if (!tokenData) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Token not found or not verified",
|
||||
};
|
||||
}
|
||||
return {
|
||||
status: "success",
|
||||
token: {
|
||||
name: tokenData.name,
|
||||
symbol: tokenData.symbol,
|
||||
address: tokenData.address,
|
||||
decimals: tokenData.decimals,
|
||||
logoURI: tokenData.logoURI,
|
||||
},
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to get token data: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default getTokenDataAction;
|
||||
61
src/actions/index.ts
Normal file
61
src/actions/index.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import deployTokenAction from "./deployToken";
|
||||
import balanceAction from "./balance";
|
||||
import transferAction from "./transfer";
|
||||
import deployCollectionAction from "./deployCollection";
|
||||
import mintNFTAction from "./mintNFT";
|
||||
import tradeAction from "./trade";
|
||||
import requestFundsAction from "./requestFunds";
|
||||
import resolveDomainAction from "./resolveDomain";
|
||||
import getTokenDataAction from "./getTokenData";
|
||||
import getTPSAction from "./getTPS";
|
||||
import fetchPriceAction from "./fetchPrice";
|
||||
import stakeWithJupAction from "./stakeWithJup";
|
||||
import registerDomainAction from "./registerDomain";
|
||||
import lendAssetAction from "./lendAsset";
|
||||
import createGibworkTaskAction from "./createGibworkTask";
|
||||
import resolveSolDomainAction from "./resolveSolDomain";
|
||||
import pythFetchPriceAction from "./pythFetchPrice";
|
||||
import getOwnedDomainsForTLDAction from "./getOwnedDomainsForTLD";
|
||||
import getPrimaryDomainAction from "./getPrimaryDomain";
|
||||
import getAllDomainsTLDsAction from "./getAllDomainsTLDs";
|
||||
import getOwnedAllDomainsAction from "./getOwnedAllDomains";
|
||||
import createImageAction from "./createImage";
|
||||
import getMainAllDomainsDomainAction from "./getMainAllDomainsDomain";
|
||||
import getAllRegisteredAllDomainsAction from "./getAllRegisteredAllDomains";
|
||||
import raydiumCreateCpmmAction from "./raydiumCreateCpmm";
|
||||
import raydiumCreateAmmV4Action from "./raydiumCreateAmmV4";
|
||||
import createOrcaSingleSidedWhirlpoolAction from "./createOrcaSingleSidedWhirlpool";
|
||||
import launchPumpfunTokenAction from "./launchPumpfunToken";
|
||||
|
||||
export const actions = [
|
||||
deployTokenAction,
|
||||
balanceAction,
|
||||
transferAction,
|
||||
deployCollectionAction,
|
||||
mintNFTAction,
|
||||
tradeAction,
|
||||
requestFundsAction,
|
||||
resolveDomainAction,
|
||||
getTokenDataAction,
|
||||
getTPSAction,
|
||||
fetchPriceAction,
|
||||
stakeWithJupAction,
|
||||
registerDomainAction,
|
||||
lendAssetAction,
|
||||
createGibworkTaskAction,
|
||||
resolveSolDomainAction,
|
||||
pythFetchPriceAction,
|
||||
getOwnedDomainsForTLDAction,
|
||||
getPrimaryDomainAction,
|
||||
getAllDomainsTLDsAction,
|
||||
getOwnedAllDomainsAction,
|
||||
createImageAction,
|
||||
getMainAllDomainsDomainAction,
|
||||
getAllRegisteredAllDomainsAction,
|
||||
raydiumCreateCpmmAction,
|
||||
raydiumCreateAmmV4Action,
|
||||
createOrcaSingleSidedWhirlpoolAction,
|
||||
launchPumpfunTokenAction,
|
||||
];
|
||||
|
||||
export type { Action, ActionExample, Handler } from "../types/action";
|
||||
106
src/actions/launchPumpfunToken.ts
Normal file
106
src/actions/launchPumpfunToken.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { launchPumpFunToken } from "../tools";
|
||||
|
||||
const launchPumpfunTokenAction: Action = {
|
||||
name: "solana_launch_pumpfun_token",
|
||||
similes: [
|
||||
"create pumpfun token",
|
||||
"launch token on pumpfun",
|
||||
"deploy pumpfun token",
|
||||
"create meme token",
|
||||
"launch memecoin",
|
||||
"create pump token",
|
||||
],
|
||||
description:
|
||||
"Launch a new token on Pump.fun with customizable metadata and initial liquidity",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
tokenName: "Sample Token",
|
||||
tokenTicker: "SMPL",
|
||||
description: "A sample token for demonstration",
|
||||
imageUrl: "https://example.com/token.png",
|
||||
twitter: "@sampletoken",
|
||||
telegram: "t.me/sampletoken",
|
||||
website: "https://sampletoken.com",
|
||||
initialLiquiditySOL: 0.1,
|
||||
slippageBps: 10,
|
||||
priorityFee: 0.0001,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
signature: "2ZE7Rz...",
|
||||
mint: "7nxQB...",
|
||||
metadataUri: "https://arweave.net/...",
|
||||
message: "Successfully launched token on Pump.fun",
|
||||
},
|
||||
explanation:
|
||||
"Launch a new token with custom metadata and 0.1 SOL initial liquidity",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
tokenName: z.string().min(1).max(32).describe("Name of the token"),
|
||||
tokenTicker: z
|
||||
.string()
|
||||
.min(2)
|
||||
.max(10)
|
||||
.describe("Ticker symbol of the token"),
|
||||
description: z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(1000)
|
||||
.describe("Description of the token"),
|
||||
imageUrl: z.string().url().describe("URL of the token image"),
|
||||
twitter: z.string().optional().describe("Twitter handle (optional)"),
|
||||
telegram: z.string().optional().describe("Telegram group link (optional)"),
|
||||
website: z.string().url().optional().describe("Website URL (optional)"),
|
||||
initialLiquiditySOL: z
|
||||
.number()
|
||||
.min(0.0001)
|
||||
.default(0.0001)
|
||||
.describe("Initial liquidity in SOL"),
|
||||
slippageBps: z
|
||||
.number()
|
||||
.min(1)
|
||||
.max(1000)
|
||||
.default(5)
|
||||
.describe("Slippage tolerance in basis points"),
|
||||
priorityFee: z
|
||||
.number()
|
||||
.min(0.00001)
|
||||
.default(0.00005)
|
||||
.describe("Priority fee in SOL"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const { tokenName, tokenTicker, description, imageUrl } = input;
|
||||
const result = await launchPumpFunToken(
|
||||
agent,
|
||||
tokenName,
|
||||
tokenTicker,
|
||||
description,
|
||||
imageUrl,
|
||||
input,
|
||||
);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
signature: result.signature,
|
||||
mint: result.mint,
|
||||
metadataUri: result.metadataUri,
|
||||
message: "Successfully launched token on Pump.fun",
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to launch token: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default launchPumpfunTokenAction;
|
||||
55
src/actions/lendAsset.ts
Normal file
55
src/actions/lendAsset.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { lendAsset } from "../tools";
|
||||
|
||||
const lendAssetAction: Action = {
|
||||
name: "solana_lend_asset",
|
||||
similes: [
|
||||
"lend usdc",
|
||||
"deposit for yield",
|
||||
"earn yield",
|
||||
"lend with lulo",
|
||||
"deposit usdc",
|
||||
"lending",
|
||||
],
|
||||
description: "Lend USDC tokens to earn yield using Lulo protocol",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
amount: 100,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
signature: "4xKpN2...",
|
||||
message: "Successfully lent 100 USDC",
|
||||
},
|
||||
explanation: "Lend 100 USDC to earn yield on Lulo",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
amount: z.number().positive().describe("Amount of USDC to lend"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const amount = input.amount as number;
|
||||
|
||||
const response = await lendAsset(agent, amount);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
signature: response,
|
||||
message: `Successfully lent ${amount} USDC`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Lending failed: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default lendAssetAction;
|
||||
90
src/actions/mintNFT.ts
Normal file
90
src/actions/mintNFT.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { mintCollectionNFT } from "../tools";
|
||||
|
||||
const mintNFTAction: Action = {
|
||||
name: "solana_mint_nft",
|
||||
similes: [
|
||||
"mint nft",
|
||||
"create nft",
|
||||
"mint token",
|
||||
"create token",
|
||||
"add nft to collection",
|
||||
],
|
||||
description: `Mint a new NFT in a collection on Solana blockchain.`,
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
collectionMint: "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w",
|
||||
name: "My NFT",
|
||||
uri: "https://example.com/nft.json",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
message: "NFT minted successfully",
|
||||
mintAddress: "7nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkN",
|
||||
metadata: {
|
||||
name: "My NFT",
|
||||
uri: "https://example.com/nft.json",
|
||||
},
|
||||
recipient: "7nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkN",
|
||||
},
|
||||
explanation: "Mint an NFT to the default wallet",
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
input: {
|
||||
collectionMint: "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w",
|
||||
name: "Gift NFT",
|
||||
uri: "https://example.com/gift.json",
|
||||
recipient: "9aUn5swQzUTRanaaTwmszxiv89cvFwUCjEBv1vZCoT1u",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
message: "NFT minted successfully",
|
||||
mintAddress: "8nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkM",
|
||||
metadata: {
|
||||
name: "Gift NFT",
|
||||
uri: "https://example.com/gift.json",
|
||||
},
|
||||
recipient: "9aUn5swQzUTRanaaTwmszxiv89cvFwUCjEBv1vZCoT1u",
|
||||
},
|
||||
explanation: "Mint an NFT to a specific recipient",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
collectionMint: z.string().min(32, "Invalid collection mint address"),
|
||||
name: z.string().min(1, "Name is required"),
|
||||
uri: z.string().url("URI must be a valid URL"),
|
||||
recipient: z.string().min(32, "Invalid recipient address"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
const result = await mintCollectionNFT(
|
||||
agent,
|
||||
new PublicKey(input.collectionMint),
|
||||
{
|
||||
name: input.name,
|
||||
uri: input.uri,
|
||||
},
|
||||
input.recipient ? new PublicKey(input.recipient) : undefined,
|
||||
);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
message: "NFT minted successfully",
|
||||
mintAddress: result.mint.toString(),
|
||||
metadata: {
|
||||
name: input.name,
|
||||
uri: input.uri,
|
||||
},
|
||||
recipient: input.recipient || result.mint.toString(),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export default mintNFTAction;
|
||||
56
src/actions/pythFetchPrice.ts
Normal file
56
src/actions/pythFetchPrice.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { pythFetchPrice } from "../tools";
|
||||
|
||||
const pythFetchPriceAction: Action = {
|
||||
name: "solana_pyth_fetch_price",
|
||||
similes: [
|
||||
"get pyth price",
|
||||
"check pyth price",
|
||||
"pyth oracle price",
|
||||
"fetch from pyth",
|
||||
"pyth price feed",
|
||||
"oracle price",
|
||||
],
|
||||
description: "Fetch the current price from a Pyth oracle price feed",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
priceFeedId: "Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD", // SOL/USD price feed
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
price: "23.45",
|
||||
message: "Current price: $23.45",
|
||||
},
|
||||
explanation: "Get the current SOL/USD price from Pyth oracle",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
priceFeedId: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("The Pyth price feed ID to fetch the price from"),
|
||||
}),
|
||||
handler: async (_agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const priceFeedId = input.tokenId as string;
|
||||
const priceStr = await pythFetchPrice(priceFeedId);
|
||||
return {
|
||||
status: "success",
|
||||
price: priceStr,
|
||||
message: `Current price: $${priceStr}`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to fetch price from Pyth: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default pythFetchPriceAction;
|
||||
91
src/actions/raydiumCreateAmmV4.ts
Normal file
91
src/actions/raydiumCreateAmmV4.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import BN from "bn.js";
|
||||
import { raydiumCreateAmmV4 } from "../tools";
|
||||
|
||||
const raydiumCreateAmmV4Action: Action = {
|
||||
name: "raydium_create_ammV4",
|
||||
similes: [
|
||||
"create raydium v4 pool",
|
||||
"setup raydium v4 liquidity pool",
|
||||
"initialize raydium v4 amm",
|
||||
"create raydium v4 market maker",
|
||||
"setup raydium v4 pool",
|
||||
"create raydium v4 trading pair",
|
||||
],
|
||||
description:
|
||||
"Create a new AMM V4 pool on Raydium with advanced features and improved efficiency",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
baseMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC
|
||||
quoteMint: "So11111111111111111111111111111111111111112", // SOL
|
||||
baseAmount: 1000,
|
||||
quoteAmount: 10,
|
||||
startPrice: 100, // 1 SOL = 100 USDC
|
||||
openTime: 1672531200, // Unix timestamp
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
signature: "2ZE7Rz...",
|
||||
poolId: "7nxQB...",
|
||||
message: "Successfully created Raydium AMM V4 pool",
|
||||
},
|
||||
explanation:
|
||||
"Create a USDC-SOL V4 pool with initial liquidity and price",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
baseMint: z.string().min(1).describe("The base token mint address"),
|
||||
quoteMint: z.string().min(1).describe("The quote token mint address"),
|
||||
baseAmount: z
|
||||
.number()
|
||||
.positive()
|
||||
.describe("Initial base token amount to provide as liquidity"),
|
||||
quoteAmount: z
|
||||
.number()
|
||||
.positive()
|
||||
.describe("Initial quote token amount to provide as liquidity"),
|
||||
startPrice: z
|
||||
.number()
|
||||
.positive()
|
||||
.describe("Initial price of quote token in base token units"),
|
||||
openTime: z
|
||||
.number()
|
||||
.positive()
|
||||
.describe("Unix timestamp when trading should start"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const marketId = new PublicKey(input.marketId);
|
||||
const baseAmount = new BN(input.baseAmount);
|
||||
const quoteAmount = new BN(input.quoteAmount);
|
||||
const startTime = new BN(input.startTime);
|
||||
|
||||
const txId = await raydiumCreateAmmV4(
|
||||
agent,
|
||||
marketId,
|
||||
baseAmount,
|
||||
quoteAmount,
|
||||
startTime,
|
||||
);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
signature: txId,
|
||||
message: "Successfully created Raydium AMM V4 pool",
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to create AMM V4 pool: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default raydiumCreateAmmV4Action;
|
||||
76
src/actions/raydiumCreateClmm.ts
Normal file
76
src/actions/raydiumCreateClmm.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { BN } from "@coral-xyz/anchor";
|
||||
import Decimal from "decimal.js";
|
||||
import { raydiumCreateClmm } from "../tools";
|
||||
|
||||
const raydiumCreateClmmAction: Action = {
|
||||
name: "raydium_create_clmm",
|
||||
similes: [
|
||||
"create clmm pool",
|
||||
"create concentrated liquidity pool",
|
||||
"raydium clmm setup",
|
||||
"launch concentrated liquidity market maker",
|
||||
],
|
||||
description: `Create a Raydium Concentrated Liquidity Market Maker (CLMM) pool with custom ranges, providing increased capital efficiency`,
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
mint1: "9xU1vzz456... (PublicKey)",
|
||||
mint2: "EfrsBcG98... (PublicKey)",
|
||||
configId: "D6yTTr... (Config PublicKey)",
|
||||
initialPrice: 123.12,
|
||||
startTime: 0, // or current UNIX timestamp
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
message: "Create raydium clmm pool successfully",
|
||||
transaction: "3skCN8... (transaction signature)",
|
||||
},
|
||||
explanation:
|
||||
"Creates a CLMM pool between mint1 and mint2 at an initial price of 123.12 and start time of 0.",
|
||||
},
|
||||
],
|
||||
],
|
||||
// Validate tool inputs using zod
|
||||
schema: z.object({
|
||||
mint1: z.string().min(1).describe("First token mint address (public key)"),
|
||||
mint2: z.string().min(1).describe("Second token mint address (public key)"),
|
||||
configId: z.string().min(1).describe("Raydium configId (public key)"),
|
||||
initialPrice: z.number().describe("Initial price for the CLMM pool"),
|
||||
startTime: z
|
||||
.number()
|
||||
.describe("Start time in seconds (UNIX timestamp or zero)"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const { mint1, mint2, configId, initialPrice, startTime } = input;
|
||||
|
||||
const tx = await raydiumCreateClmm(
|
||||
agent,
|
||||
new PublicKey(mint1),
|
||||
new PublicKey(mint2),
|
||||
new PublicKey(configId),
|
||||
new Decimal(initialPrice),
|
||||
new BN(startTime),
|
||||
);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
message: "Create raydium clmm pool successfully",
|
||||
transaction: tx,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to create CLMM pool: ${error.message}`,
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default raydiumCreateClmmAction;
|
||||
90
src/actions/raydiumCreateCpmm.ts
Normal file
90
src/actions/raydiumCreateCpmm.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import BN from "bn.js";
|
||||
import { raydiumCreateCpmm } from "../tools";
|
||||
|
||||
const raydiumCreateCpmmAction: Action = {
|
||||
name: "solana_raydium_create_cpmm",
|
||||
similes: [
|
||||
"create raydium pool",
|
||||
"setup raydium liquidity pool",
|
||||
"initialize raydium amm",
|
||||
"create constant product market maker",
|
||||
"setup raydium cpmm",
|
||||
"create raydium trading pair",
|
||||
],
|
||||
description:
|
||||
"Create a new Constant Product Market Maker (CPMM) pool on Raydium",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
baseMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC
|
||||
quoteMint: "So11111111111111111111111111111111111111112", // SOL
|
||||
baseAmount: 1000,
|
||||
quoteAmount: 10,
|
||||
startTime: 1672531200, // Unix timestamp
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
signature: "2ZE7Rz...",
|
||||
poolId: "7nxQB...",
|
||||
message: "Successfully created Raydium CPMM pool",
|
||||
},
|
||||
explanation:
|
||||
"Create a USDC-SOL pool with initial liquidity of 1000 USDC and 10 SOL",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
baseMint: z.string().min(1).describe("The base token mint address"),
|
||||
quoteMint: z.string().min(1).describe("The quote token mint address"),
|
||||
baseAmount: z
|
||||
.number()
|
||||
.positive()
|
||||
.describe("Initial base token amount to provide as liquidity"),
|
||||
quoteAmount: z
|
||||
.number()
|
||||
.positive()
|
||||
.describe("Initial quote token amount to provide as liquidity"),
|
||||
startTime: z
|
||||
.number()
|
||||
.positive()
|
||||
.describe("Unix timestamp when trading should start"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const mintA = new PublicKey(input.baseMint);
|
||||
const mintB = new PublicKey(input.quoteMint);
|
||||
const configId = new PublicKey(input.configId);
|
||||
const mintAAmount = new BN(input.baseAmount);
|
||||
const mintBAmount = new BN(input.quoteAmount);
|
||||
const startTime = new BN(input.startTime);
|
||||
|
||||
const txId = await raydiumCreateCpmm(
|
||||
agent,
|
||||
mintA,
|
||||
mintB,
|
||||
configId,
|
||||
mintAAmount,
|
||||
mintBAmount,
|
||||
startTime,
|
||||
);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
signature: txId,
|
||||
message: "Successfully created Raydium CPMM pool",
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to create CPMM pool: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default raydiumCreateCpmmAction;
|
||||
63
src/actions/registerDomain.ts
Normal file
63
src/actions/registerDomain.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { registerDomain } from "../tools";
|
||||
|
||||
const registerDomainAction: Action = {
|
||||
name: "solana_register_domain",
|
||||
similes: [
|
||||
"register domain",
|
||||
"buy domain",
|
||||
"get domain name",
|
||||
"register .sol",
|
||||
"purchase domain",
|
||||
"domain registration",
|
||||
],
|
||||
description: "Register a .sol domain name using Bonfida Name Service",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
name: "mydomain",
|
||||
spaceKB: 1,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
signature: "2ZE7Rz...",
|
||||
message: "Successfully registered mydomain.sol",
|
||||
},
|
||||
explanation: "Register a new .sol domain with 1KB storage space",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
name: z.string().min(1).describe("Domain name to register (without .sol)"),
|
||||
spaceKB: z
|
||||
.number()
|
||||
.min(1)
|
||||
.max(10)
|
||||
.default(1)
|
||||
.describe("Space allocation in KB (max 10KB)"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const name = input.name as string;
|
||||
const spaceKB = (input.spaceKB as number) || 1;
|
||||
|
||||
const signature = await registerDomain(agent, name, spaceKB);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
signature,
|
||||
message: `Successfully registered ${name}.sol`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Domain registration failed: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default registerDomainAction;
|
||||
41
src/actions/requestFunds.ts
Normal file
41
src/actions/requestFunds.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { request_faucet_funds } from "../tools";
|
||||
|
||||
const requestFundsAction: Action = {
|
||||
name: "solana_request_funds",
|
||||
similes: [
|
||||
"request sol",
|
||||
"get test sol",
|
||||
"use faucet",
|
||||
"request test tokens",
|
||||
"get devnet sol",
|
||||
],
|
||||
description: "Request SOL from Solana faucet (devnet/testnet only)",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {},
|
||||
output: {
|
||||
status: "success",
|
||||
message: "Successfully requested faucet funds",
|
||||
network: "devnet.solana.com",
|
||||
},
|
||||
explanation: "Request SOL from the devnet faucet",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({}), // No input parameters required
|
||||
handler: async (agent: SolanaAgentKit, _input: Record<string, any>) => {
|
||||
await request_faucet_funds(agent);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
message: "Successfully requested faucet funds",
|
||||
network: agent.connection.rpcEndpoint.split("/")[2],
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export default requestFundsAction;
|
||||
51
src/actions/resolveDomain.ts
Normal file
51
src/actions/resolveDomain.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { resolveAllDomains } from "../tools";
|
||||
|
||||
const resolveDomainAction: Action = {
|
||||
name: "solana_resolve_all_domains",
|
||||
similes: [
|
||||
"resolve domain",
|
||||
"lookup domain",
|
||||
"get domain owner",
|
||||
"check domain",
|
||||
"find domain owner",
|
||||
],
|
||||
description: "Resolve a Solana domain name to get its owner's public key",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
domain: "example.sol",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
owner: "7nxQB...",
|
||||
},
|
||||
explanation: "Resolve a .sol domain name to get the owner's public key",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
domain: z.string().min(1).describe("The domain name to resolve"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const domain = input.domain as string;
|
||||
const tld = await resolveAllDomains(agent, domain);
|
||||
return {
|
||||
status: "success",
|
||||
owner: tld,
|
||||
message: `Successfully resolved domain ${domain}`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to resolve domain: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default resolveDomainAction;
|
||||
59
src/actions/resolveSolDomain.ts
Normal file
59
src/actions/resolveSolDomain.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { resolveSolDomain } from "../tools";
|
||||
|
||||
const resolveSolDomainAction: Action = {
|
||||
name: "solana_resolve_sol_domain",
|
||||
similes: [
|
||||
"resolve sol domain",
|
||||
"lookup sol domain",
|
||||
"get sol domain owner",
|
||||
"check sol domain",
|
||||
"find sol domain owner",
|
||||
"resolve .sol",
|
||||
],
|
||||
description:
|
||||
"Resolve a .sol domain to its corresponding Solana wallet address using Bonfida Name Service",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
domain: "vitalik.sol",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
owner: "7nxQB...",
|
||||
message: "Successfully resolved vitalik.sol",
|
||||
},
|
||||
explanation: "Resolve a .sol domain to get the owner's wallet address",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
domain: z
|
||||
.string()
|
||||
.min(1)
|
||||
.describe("The .sol domain to resolve (with or without .sol suffix)"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const domain = input.domain as string;
|
||||
|
||||
const res = await resolveSolDomain(agent, domain);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
owner: res.toString(),
|
||||
message: `Successfully resolved ${res}`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to resolve domain: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default resolveSolDomainAction;
|
||||
55
src/actions/stakeWithJup.ts
Normal file
55
src/actions/stakeWithJup.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { stakeWithJup } from "../tools";
|
||||
|
||||
const stakeWithJupAction: Action = {
|
||||
name: "solana_stake_with_jup",
|
||||
similes: [
|
||||
"stake sol",
|
||||
"stake with jupiter",
|
||||
"jup staking",
|
||||
"stake with jup",
|
||||
"liquid staking",
|
||||
"get jupsol",
|
||||
],
|
||||
description:
|
||||
"Stake SOL tokens with Jupiter's liquid staking protocol to receive jupSOL",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
amount: 1.5,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
signature: "5KtPn3...",
|
||||
message: "Successfully staked 1.5 SOL for jupSOL",
|
||||
},
|
||||
explanation: "Stake 1.5 SOL to receive jupSOL tokens",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
amount: z.number().positive().describe("Amount of SOL to stake"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const amount = input.amount as number;
|
||||
|
||||
const res = await stakeWithJup(agent, amount);
|
||||
return {
|
||||
status: "success",
|
||||
res,
|
||||
message: `Successfully staked ${amount} SOL for jupSOL`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `jupSOL staking failed: ${error.message}`,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default stakeWithJupAction;
|
||||
60
src/actions/tokenDataByTicker.ts
Normal file
60
src/actions/tokenDataByTicker.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { getTokenDataByTicker } from "../tools";
|
||||
|
||||
const tokenDataByTickerAction: Action = {
|
||||
name: "solana_token_data_by_ticker",
|
||||
similes: [
|
||||
"token data by ticker",
|
||||
"fetch token info by ticker",
|
||||
"lookup token ticker info",
|
||||
"get token info by ticker",
|
||||
],
|
||||
description: "Get the token data for a given token ticker",
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
ticker: "USDC",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
tokenData: {
|
||||
// Some placeholder example data
|
||||
symbol: "USDC",
|
||||
name: "USD Coin",
|
||||
decimals: 6,
|
||||
mintAddress: "FhRg...",
|
||||
},
|
||||
},
|
||||
explanation: "Fetches metadata for the USDC token by its ticker.",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
ticker: z.string().min(1).describe("Ticker of the token, e.g. 'USDC'"),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const ticker = input.ticker as string;
|
||||
|
||||
// Use agent’s method to get token data by ticker
|
||||
const tokenData = await getTokenDataByTicker(ticker);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
tokenData: tokenData,
|
||||
message: `Successfully fetched token data for ticker: ${ticker}`,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to fetch token data for ticker: ${input.ticker || ""}. ${error.message}`,
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default tokenDataByTickerAction;
|
||||
85
src/actions/trade.ts
Normal file
85
src/actions/trade.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { trade } from "../tools";
|
||||
|
||||
const tradeAction: Action = {
|
||||
name: "solana_trade",
|
||||
similes: [
|
||||
"swap tokens",
|
||||
"exchange tokens",
|
||||
"trade tokens",
|
||||
"convert tokens",
|
||||
"swap sol",
|
||||
],
|
||||
description: `This tool can be used to swap tokens to another token (It uses Jupiter Exchange).`,
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
outputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
inputAmount: 1,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
message: "Trade executed successfully",
|
||||
transaction:
|
||||
"5UfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKgvHYmXJgqJKxEqy9k4Rz9LpXrHF9kUZB7",
|
||||
inputAmount: 1,
|
||||
inputToken: "SOL",
|
||||
outputToken: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
},
|
||||
explanation: "Swap 1 SOL for USDC",
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
input: {
|
||||
outputMint: "So11111111111111111111111111111111111111112",
|
||||
inputAmount: 100,
|
||||
inputMint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
slippageBps: 100,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
message: "Trade executed successfully",
|
||||
transaction:
|
||||
"4VfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKgvHYmXJgqJKxEqy9k4Rz9LpXrHF9kUZB7",
|
||||
inputAmount: 100,
|
||||
inputToken: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
outputToken: "So11111111111111111111111111111111111111112",
|
||||
},
|
||||
explanation: "Swap 100 USDC for SOL with 1% slippage",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
outputMint: z.string().min(32, "Invalid output mint address"),
|
||||
inputAmount: z.number().positive("Input amount must be positive"),
|
||||
inputMint: z.string().min(32, "Invalid input mint address").optional(),
|
||||
slippageBps: z.number().min(0).max(10000).optional(),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
const tx = await trade(
|
||||
agent,
|
||||
new PublicKey(input.outputMint),
|
||||
input.inputAmount,
|
||||
input.inputMint
|
||||
? new PublicKey(input.inputMint)
|
||||
: new PublicKey("So11111111111111111111111111111111111111112"),
|
||||
input.slippageBps,
|
||||
);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
message: "Trade executed successfully",
|
||||
transaction: tx,
|
||||
inputAmount: input.inputAmount,
|
||||
inputToken: input.inputMint || "SOL",
|
||||
outputToken: input.outputMint,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export default tradeAction;
|
||||
78
src/actions/transfer.ts
Normal file
78
src/actions/transfer.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { transfer } from "../tools";
|
||||
|
||||
const transferAction: Action = {
|
||||
name: "solana_transfer",
|
||||
similes: [
|
||||
"send tokens",
|
||||
"transfer funds",
|
||||
"send money",
|
||||
"send sol",
|
||||
"transfer tokens",
|
||||
],
|
||||
description: `Transfer tokens or SOL to another address (also called as wallet address).`,
|
||||
examples: [
|
||||
[
|
||||
{
|
||||
input: {
|
||||
to: "8x2dR8Mpzuz2YqyZyZjUbYWKSWesBo5jMx2Q9Y86udVk",
|
||||
amount: 1,
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
message: "Transfer completed successfully",
|
||||
amount: 1,
|
||||
recipient: "8x2dR8Mpzuz2YqyZyZjUbYWKSWesBo5jMx2Q9Y86udVk",
|
||||
token: "SOL",
|
||||
transaction:
|
||||
"5UfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKgvHYmXJgqJKxEqy9k4Rz9LpXrHF9kUZB7",
|
||||
},
|
||||
explanation: "Transfer 1 SOL to the recipient address",
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
input: {
|
||||
to: "8x2dR8Mpzuz2YqyZyZjUbYWKSWesBo5jMx2Q9Y86udVk",
|
||||
amount: 100,
|
||||
mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
},
|
||||
output: {
|
||||
status: "success",
|
||||
message: "Transfer completed successfully",
|
||||
amount: 100,
|
||||
recipient: "8x2dR8Mpzuz2YqyZyZjUbYWKSWesBo5jMx2Q9Y86udVk",
|
||||
token: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
||||
transaction:
|
||||
"4VfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKgvHYmXJgqJKxEqy9k4Rz9LpXrHF9kUZB7",
|
||||
},
|
||||
explanation: "Transfer 100 USDC tokens to the recipient address",
|
||||
},
|
||||
],
|
||||
],
|
||||
schema: z.object({
|
||||
to: z.string().min(32, "Invalid Solana address"),
|
||||
amount: z.number().positive("Amount must be positive"),
|
||||
mint: z.string().optional(),
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
const recipient = new PublicKey(input.to);
|
||||
const mintAddress = input.mint ? new PublicKey(input.mint) : undefined;
|
||||
|
||||
const tx = await transfer(agent, recipient, input.amount, mintAddress);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
message: "Transfer completed successfully",
|
||||
amount: input.amount,
|
||||
recipient: input.to,
|
||||
token: input.mint || "SOL",
|
||||
transaction: tx,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export default transferAction;
|
||||
@@ -5,3 +5,8 @@ export { SolanaAgentKit, createSolanaTools };
|
||||
|
||||
// Optional: Export types that users might need
|
||||
export * from "./types";
|
||||
|
||||
// Export action system
|
||||
export * from "./actions";
|
||||
export * from "./types/action";
|
||||
export * from "./utils/actionExecutor";
|
||||
|
||||
56
src/types/action.ts
Normal file
56
src/types/action.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* Example of an action with input and output
|
||||
*/
|
||||
export interface ActionExample {
|
||||
input: Record<string, any>;
|
||||
output: Record<string, any>;
|
||||
explanation: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler function type for executing the action
|
||||
*/
|
||||
export type Handler = (
|
||||
agent: SolanaAgentKit,
|
||||
input: Record<string, any>,
|
||||
) => Promise<Record<string, any>>;
|
||||
|
||||
/**
|
||||
* Main Action interface inspired by ELIZA
|
||||
* This interface makes it easier to implement actions across different frameworks
|
||||
*/
|
||||
export interface Action {
|
||||
/**
|
||||
* Unique name of the action
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* Alternative names/phrases that can trigger this action
|
||||
*/
|
||||
similes: string[];
|
||||
|
||||
/**
|
||||
* Detailed description of what the action does
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* Array of example inputs and outputs for the action
|
||||
* Each inner array represents a group of related examples
|
||||
*/
|
||||
examples: ActionExample[][];
|
||||
|
||||
/**
|
||||
* Zod schema for input validation
|
||||
*/
|
||||
schema: z.ZodType<any>;
|
||||
|
||||
/**
|
||||
* Function that executes the action
|
||||
*/
|
||||
handler: Handler;
|
||||
}
|
||||
@@ -97,3 +97,4 @@ export interface GibworkCreateTaskReponse {
|
||||
taskId?: string | undefined;
|
||||
signature?: string | undefined;
|
||||
}
|
||||
|
||||
|
||||
68
src/utils/actionExecutor.ts
Normal file
68
src/utils/actionExecutor.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { actions } from "../actions";
|
||||
|
||||
/**
|
||||
* Find an action by its name or one of its similes
|
||||
*/
|
||||
export function findAction(query: string): Action | undefined {
|
||||
const normalizedQuery = query.toLowerCase().trim();
|
||||
return actions.find(
|
||||
(action) =>
|
||||
action.name.toLowerCase() === normalizedQuery ||
|
||||
action.similes.some((simile) => simile.toLowerCase() === normalizedQuery),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute an action with the given input
|
||||
*/
|
||||
export async function executeAction(
|
||||
action: Action,
|
||||
agent: SolanaAgentKit,
|
||||
input: Record<string, any>,
|
||||
): Promise<Record<string, any>> {
|
||||
try {
|
||||
// Validate input using Zod schema
|
||||
const validatedInput = action.schema.parse(input);
|
||||
|
||||
// Execute the action with validated input
|
||||
const result = await action.handler(agent, validatedInput);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
...result,
|
||||
};
|
||||
} catch (error: any) {
|
||||
// Handle Zod validation errors specially
|
||||
if (error.errors) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Validation error",
|
||||
details: error.errors,
|
||||
code: "VALIDATION_ERROR",
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "EXECUTION_ERROR",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get examples for an action
|
||||
*/
|
||||
export function getActionExamples(action: Action): string {
|
||||
return action.examples
|
||||
.flat()
|
||||
.map((example) => {
|
||||
return `Input: ${JSON.stringify(example.input, null, 2)}
|
||||
Output: ${JSON.stringify(example.output, null, 2)}
|
||||
Explanation: ${example.explanation}
|
||||
---`;
|
||||
})
|
||||
.join("\n");
|
||||
}
|
||||
@@ -59,6 +59,7 @@ async function initializeAgent() {
|
||||
);
|
||||
|
||||
const tools = createSolanaTools(solanaAgent);
|
||||
|
||||
const memory = new MemorySaver();
|
||||
const config = { configurable: { thread_id: "Solana Agent Kit!" } };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user