mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-05-30 23:26:49 +00:00
Merge branch 'main' into feature/vercel-ai-sdk
This commit is contained in:
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: "BALANCE_ACTION",
|
||||
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: "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: "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: "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: "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: "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: "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: "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: "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: "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: "GET_MAIN_ALL_DOMAINS_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: "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: "GET_OWNED_DOMAINS_FOR_TLD",
|
||||
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: "GET_PRIMARY_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: "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: "GET_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 = {
|
||||
"DEPLOY_TOKEN_ACTION" : deployTokenAction,
|
||||
"BALANCE_ACTION" : balanceAction,
|
||||
"TRANSFER_ACTION" : transferAction,
|
||||
"DEPLOY_COLLECTION_ACTION" : deployCollectionAction,
|
||||
"MINT_NFT_ACTION" : mintNFTAction,
|
||||
"TRADE_ACTION" : tradeAction,
|
||||
"REQUEST_FUNDS_ACTION" : requestFundsAction,
|
||||
"RESOLVE_DOMAIN_ACTION" : resolveDomainAction,
|
||||
"GET_TOKEN_DATA_ACTION" : getTokenDataAction,
|
||||
"GET_TPS_ACTION" : getTPSAction,
|
||||
"FETCH_PRICE_ACTION" : fetchPriceAction,
|
||||
"STAKE_WITH_JUP_ACTION" : stakeWithJupAction,
|
||||
"REGISTER_DOMAIN_ACTION" : registerDomainAction,
|
||||
"LEND_ASSET_ACTION" : lendAssetAction,
|
||||
"CREATE_GIBWORK_TASK_ACTION" : createGibworkTaskAction,
|
||||
"RESOLVE_SOL_DOMAIN_ACTION" : resolveSolDomainAction,
|
||||
"PYTH_FETCH_PRICE_ACTION" : pythFetchPriceAction,
|
||||
"GET_OWNED_DOMAINS_FOR_TLD_ACTION" : getOwnedDomainsForTLDAction,
|
||||
"GET_PRIMARY_DOMAIN_ACTION" : getPrimaryDomainAction,
|
||||
"GET_ALL_DOMAINS_TLDS_ACTION" : getAllDomainsTLDsAction,
|
||||
"GET_OWNED_ALL_DOMAINS_ACTION" : getOwnedAllDomainsAction,
|
||||
"CREATE_IMAGE_ACTION" : createImageAction,
|
||||
"GET_MAIN_ALL_DOMAINS_DOMAIN_ACTION" : getMainAllDomainsDomainAction,
|
||||
"GET_ALL_REGISTERED_ALL_DOMAINS_ACTION" : getAllRegisteredAllDomainsAction,
|
||||
"RAYDIUM_CREATE_CPMM_ACTION" : raydiumCreateCpmmAction,
|
||||
"RAYDIUM_CREATE_AMM_V4_ACTION" : raydiumCreateAmmV4Action,
|
||||
"CREATE_ORCA_SINGLE_SIDED_WHIRLPOOL_ACTION" : createOrcaSingleSidedWhirlpoolAction,
|
||||
"LAUNCH_PUMPFUN_TOKEN_ACTION" : 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: "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: "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: "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: "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_AMM_V4",
|
||||
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: "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: "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: "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: "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: "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: "STAKE_WITH_JUPITER",
|
||||
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: "GET_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: "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: "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;
|
||||
@@ -2,6 +2,7 @@ import { Connection, Keypair, PublicKey } from "@solana/web3.js";
|
||||
import bs58 from "bs58";
|
||||
import Decimal from "decimal.js";
|
||||
import { DEFAULT_OPTIONS } from "../constants";
|
||||
import { Config } from "../types";
|
||||
import {
|
||||
deploy_collection,
|
||||
deploy_token,
|
||||
@@ -14,12 +15,16 @@ import {
|
||||
lendAsset,
|
||||
mintCollectionNFT,
|
||||
openbookCreateMarket,
|
||||
manifestCreateMarket,
|
||||
raydiumCreateAmmV4,
|
||||
raydiumCreateClmm,
|
||||
raydiumCreateCpmm,
|
||||
registerDomain,
|
||||
request_faucet_funds,
|
||||
trade,
|
||||
limitOrder,
|
||||
cancelAllOrders,
|
||||
withdrawAll,
|
||||
transfer,
|
||||
getTokenDataByAddress,
|
||||
getTokenDataByTicker,
|
||||
@@ -43,6 +48,8 @@ import {
|
||||
orcaFetchPositions,
|
||||
rock_paper_scissor,
|
||||
create_TipLink,
|
||||
listNFTForSale,
|
||||
cancelListing,
|
||||
} from "../tools";
|
||||
|
||||
import {
|
||||
@@ -64,22 +71,39 @@ import { BN } from "@coral-xyz/anchor";
|
||||
* @property {Connection} connection - Solana RPC connection
|
||||
* @property {Keypair} wallet - Wallet keypair for signing transactions
|
||||
* @property {PublicKey} wallet_address - Public key of the wallet
|
||||
* @property {Config} config - Configuration object
|
||||
*/
|
||||
export class SolanaAgentKit {
|
||||
public connection: Connection;
|
||||
public wallet: Keypair;
|
||||
public wallet_address: PublicKey;
|
||||
public openai_api_key: string | null;
|
||||
public config: Config;
|
||||
|
||||
/**
|
||||
* @deprecated Using openai_api_key directly in constructor is deprecated.
|
||||
* Please use the new constructor with Config object instead:
|
||||
* @example
|
||||
* const agent = new SolanaAgentKit(privateKey, rpcUrl, {
|
||||
* OPENAI_API_KEY: 'your-key'
|
||||
* });
|
||||
*/
|
||||
constructor(private_key: string, rpc_url: string, openai_api_key: string | null);
|
||||
constructor(private_key: string, rpc_url: string, config: Config);
|
||||
constructor(
|
||||
private_key: string,
|
||||
rpc_url = "https://api.mainnet-beta.solana.com",
|
||||
openai_api_key: string | null = null,
|
||||
rpc_url: string,
|
||||
configOrKey: Config | string | null,
|
||||
) {
|
||||
this.connection = new Connection(rpc_url);
|
||||
this.connection = new Connection(rpc_url || "https://api.mainnet-beta.solana.com");
|
||||
this.wallet = Keypair.fromSecretKey(bs58.decode(private_key));
|
||||
this.wallet_address = this.wallet.publicKey;
|
||||
this.openai_api_key = openai_api_key;
|
||||
|
||||
// Handle both old and new patterns
|
||||
if (typeof configOrKey === 'string' || configOrKey === null) {
|
||||
this.config = { OPENAI_API_KEY: configOrKey || '' };
|
||||
} else {
|
||||
this.config = configOrKey;
|
||||
}
|
||||
}
|
||||
|
||||
// Tool methods
|
||||
@@ -151,6 +175,23 @@ export class SolanaAgentKit {
|
||||
return trade(this, outputMint, inputAmount, inputMint, slippageBps);
|
||||
}
|
||||
|
||||
async limitOrder(
|
||||
marketId: PublicKey,
|
||||
quantity: number,
|
||||
side: string,
|
||||
price: number,
|
||||
): Promise<string> {
|
||||
return limitOrder(this, marketId, quantity, side, price);
|
||||
}
|
||||
|
||||
async cancelAllOrders(marketId: PublicKey): Promise<string> {
|
||||
return cancelAllOrders(this, marketId);
|
||||
}
|
||||
|
||||
async withdrawAll(marketId: PublicKey): Promise<string> {
|
||||
return withdrawAll(this, marketId);
|
||||
}
|
||||
|
||||
async lendAssets(amount: number): Promise<string> {
|
||||
return lendAsset(this, amount);
|
||||
}
|
||||
@@ -295,8 +336,7 @@ export class SolanaAgentKit {
|
||||
return getOwnedDomainsForTLD(this, tld);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
async getAllDomainsTLDs(): Promise<String[]> {
|
||||
async getAllDomainsTLDs(): Promise<string[]> {
|
||||
return getAllDomainsTLDs(this);
|
||||
}
|
||||
|
||||
@@ -378,6 +418,13 @@ export class SolanaAgentKit {
|
||||
);
|
||||
}
|
||||
|
||||
async manifestCreateMarket(
|
||||
baseMint: PublicKey,
|
||||
quoteMint: PublicKey,
|
||||
): Promise<string[]> {
|
||||
return manifestCreateMarket(this, baseMint, quoteMint);
|
||||
}
|
||||
|
||||
async pythFetchPrice(priceFeedID: string): Promise<string> {
|
||||
return pythFetchPrice(priceFeedID);
|
||||
}
|
||||
@@ -412,4 +459,12 @@ export class SolanaAgentKit {
|
||||
async createTiplink(amount: number, splmintAddress?: PublicKey) {
|
||||
return create_TipLink(this, amount, splmintAddress);
|
||||
}
|
||||
|
||||
async tensorListNFT(nftMint: PublicKey, price: number): Promise<string> {
|
||||
return listNFTForSale(this, nftMint, price);
|
||||
}
|
||||
|
||||
async tensorCancelListing(nftMint: PublicKey): Promise<string> {
|
||||
return cancelListing(this, nftMint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,12 @@ export const TOKENS = {
|
||||
export const DEFAULT_OPTIONS = {
|
||||
SLIPPAGE_BPS: 300,
|
||||
TOKEN_DECIMALS: 9,
|
||||
RERERRAL_FEE: 200,
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Jupiter API URL
|
||||
*/
|
||||
export const JUP_API = "https://quote-api.jup.ag/v6";
|
||||
export const JUP_REFERRAL_ADDRESS =
|
||||
"REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3";
|
||||
|
||||
@@ -6,3 +6,7 @@ export { SolanaAgentKit, createSolanaTools, createVercelAITools };
|
||||
|
||||
// Optional: Export types that users might need
|
||||
export * from "./types";
|
||||
|
||||
// Export action system
|
||||
export { ACTIONS } from "./actions";
|
||||
export * from "./utils/actionExecutor";
|
||||
|
||||
@@ -46,7 +46,7 @@ export class SolanaBalanceTool extends Tool {
|
||||
|
||||
export class SolanaBalanceOtherTool extends Tool {
|
||||
name = "solana_balance_other";
|
||||
description = `Get the balance of a Solana wallet or token account different from the agent's wallet.
|
||||
description = `Get the balance of a Solana wallet or token account which is different from the agent's wallet.
|
||||
|
||||
If no tokenAddress is provided, the SOL balance of the wallet will be returned.
|
||||
|
||||
@@ -306,6 +306,114 @@ export class SolanaTradeTool extends Tool {
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaLimitOrderTool extends Tool {
|
||||
name = "solana_limit_order";
|
||||
description = `This tool can be used to place limit orders using Manifest.
|
||||
|
||||
Inputs ( input is a JSON string ):
|
||||
marketId: PublicKey, eg "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ" for SOL/USDC (required)
|
||||
quantity: number, eg 1 or 0.01 (required)
|
||||
side: string, eg "Buy" or "Sell" (required)
|
||||
price: number, in tokens eg 200 for SOL/USDC (required)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const parsedInput = JSON.parse(input);
|
||||
|
||||
const tx = await this.solanaKit.limitOrder(
|
||||
new PublicKey(parsedInput.marketId),
|
||||
parsedInput.quantity,
|
||||
parsedInput.side,
|
||||
parsedInput.price,
|
||||
);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Trade executed successfully",
|
||||
transaction: tx,
|
||||
marketId: parsedInput.marketId,
|
||||
quantity: parsedInput.quantity,
|
||||
side: parsedInput.side,
|
||||
price: parsedInput.price,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaCancelAllOrdersTool extends Tool {
|
||||
name = "solana_cancel_all_orders";
|
||||
description = `This tool can be used to cancel all orders from a Manifest market.
|
||||
|
||||
Input ( input is a JSON string ):
|
||||
marketId: string, eg "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ" for SOL/USDC (required)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const marketId = new PublicKey(input.trim());
|
||||
const tx = await this.solanaKit.cancelAllOrders(marketId);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Cancel orders successfully",
|
||||
transaction: tx,
|
||||
marketId,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaWithdrawAllTool extends Tool {
|
||||
name = "solana_withdraw_all";
|
||||
description = `This tool can be used to withdraw all funds from a Manifest market.
|
||||
|
||||
Input ( input is a JSON string ):
|
||||
marketId: string, eg "ENhU8LsaR7vDD2G1CsWcsuSGNrih9Cv5WZEk7q9kPapQ" for SOL/USDC (required)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const marketId = new PublicKey(input.trim());
|
||||
const tx = await this.solanaKit.withdrawAll(marketId);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Withdrew successfully",
|
||||
transaction: tx,
|
||||
marketId,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaRequestFundsTool extends Tool {
|
||||
name = "solana_request_funds";
|
||||
description = "Request SOL from Solana faucet (devnet/testnet only)";
|
||||
@@ -796,7 +904,7 @@ export class SolanaCompressedAirdropTool extends Tool {
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaClosePostition extends Tool {
|
||||
export class SolanaClosePosition extends Tool {
|
||||
name = "orca_close_position";
|
||||
description = `Closes an existing liquidity position in an Orca Whirlpool. This function fetches the position
|
||||
details using the provided mint address and closes the position with a 1% slippage.
|
||||
@@ -1078,7 +1186,7 @@ export class SolanaOrcaOpenSingleSidedPosition extends Tool {
|
||||
|
||||
export class SolanaRaydiumCreateAmmV4 extends Tool {
|
||||
name = "raydium_create_ammV4";
|
||||
description = `Raydium's Legacy AMM that requiers an OpenBook marketID
|
||||
description = `Raydium's Legacy AMM that requires an OpenBook marketID
|
||||
|
||||
Inputs (input is a json string):
|
||||
marketId: string (required)
|
||||
@@ -1104,7 +1212,7 @@ export class SolanaRaydiumCreateAmmV4 extends Tool {
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Create raydium amm v4 pool successfully",
|
||||
message: "Raydium amm v4 pool created successfully",
|
||||
transaction: tx,
|
||||
});
|
||||
} catch (error: any) {
|
||||
@@ -1149,7 +1257,7 @@ export class SolanaRaydiumCreateClmm extends Tool {
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Create raydium clmm pool successfully",
|
||||
message: "Raydium clmm pool created successfully",
|
||||
transaction: tx,
|
||||
});
|
||||
} catch (error: any) {
|
||||
@@ -1197,7 +1305,7 @@ export class SolanaRaydiumCreateCpmm extends Tool {
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Create raydium cpmm pool successfully",
|
||||
message: "Raydium cpmm pool created successfully",
|
||||
transaction: tx,
|
||||
});
|
||||
} catch (error: any) {
|
||||
@@ -1239,7 +1347,7 @@ export class SolanaOpenbookCreateMarket extends Tool {
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Create openbook market successfully",
|
||||
message: "Openbook market created successfully",
|
||||
transaction: tx,
|
||||
});
|
||||
} catch (error: any) {
|
||||
@@ -1252,6 +1360,44 @@ export class SolanaOpenbookCreateMarket extends Tool {
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaManifestCreateMarket extends Tool {
|
||||
name = "solana_manifest_create_market";
|
||||
description = `Manifest market
|
||||
|
||||
Inputs (input is a json string):
|
||||
baseMint: string (required)
|
||||
quoteMint: string (required)
|
||||
`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const inputFormat = JSON.parse(input);
|
||||
|
||||
const tx = await this.solanaKit.manifestCreateMarket(
|
||||
new PublicKey(inputFormat.baseMint),
|
||||
new PublicKey(inputFormat.quoteMint),
|
||||
);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "Create manifest market successfully",
|
||||
transaction: tx[0],
|
||||
marketId: tx[1],
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaPythFetchPrice extends Tool {
|
||||
name = "solana_pyth_fetch_price";
|
||||
description = `Fetch the price of a given price feed from Pyth's Hermes service
|
||||
@@ -1590,6 +1736,95 @@ export class SolanaTipLinkTool extends Tool {
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaListNFTForSaleTool extends Tool {
|
||||
name = "solana_list_nft_for_sale";
|
||||
description = `List an NFT for sale on Tensor Trade.
|
||||
|
||||
Inputs (input is a JSON string):
|
||||
nftMint: string, the mint address of the NFT (required)
|
||||
price: number, price in SOL (required)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const parsedInput = JSON.parse(input);
|
||||
|
||||
// Validate NFT ownership first
|
||||
const nftAccount =
|
||||
await this.solanaKit.connection.getTokenAccountsByOwner(
|
||||
this.solanaKit.wallet_address,
|
||||
{ mint: new PublicKey(parsedInput.nftMint) },
|
||||
);
|
||||
|
||||
if (nftAccount.value.length === 0) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message:
|
||||
"NFT not found in wallet. Please make sure you own this NFT.",
|
||||
code: "NFT_NOT_FOUND",
|
||||
});
|
||||
}
|
||||
|
||||
const tx = await this.solanaKit.tensorListNFT(
|
||||
new PublicKey(parsedInput.nftMint),
|
||||
parsedInput.price,
|
||||
);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "NFT listed for sale successfully",
|
||||
transaction: tx,
|
||||
price: parsedInput.price,
|
||||
nftMint: parsedInput.nftMint,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SolanaCancelNFTListingTool extends Tool {
|
||||
name = "solana_cancel_nft_listing";
|
||||
description = `Cancel an NFT listing on Tensor Trade.
|
||||
|
||||
Inputs (input is a JSON string):
|
||||
nftMint: string, the mint address of the NFT (required)`;
|
||||
|
||||
constructor(private solanaKit: SolanaAgentKit) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async _call(input: string): Promise<string> {
|
||||
try {
|
||||
const parsedInput = JSON.parse(input);
|
||||
|
||||
const tx = await this.solanaKit.tensorCancelListing(
|
||||
new PublicKey(parsedInput.nftMint),
|
||||
);
|
||||
|
||||
return JSON.stringify({
|
||||
status: "success",
|
||||
message: "NFT listing cancelled successfully",
|
||||
transaction: tx,
|
||||
nftMint: parsedInput.nftMint,
|
||||
});
|
||||
} catch (error: any) {
|
||||
return JSON.stringify({
|
||||
status: "error",
|
||||
message: error.message,
|
||||
code: error.code || "UNKNOWN_ERROR",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createSolanaTools(solanaKit: SolanaAgentKit) {
|
||||
return [
|
||||
new SolanaBalanceTool(solanaKit),
|
||||
@@ -1616,7 +1851,11 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
|
||||
new SolanaRaydiumCreateClmm(solanaKit),
|
||||
new SolanaRaydiumCreateCpmm(solanaKit),
|
||||
new SolanaOpenbookCreateMarket(solanaKit),
|
||||
new SolanaClosePostition(solanaKit),
|
||||
new SolanaManifestCreateMarket(solanaKit),
|
||||
new SolanaLimitOrderTool(solanaKit),
|
||||
new SolanaCancelAllOrdersTool(solanaKit),
|
||||
new SolanaWithdrawAllTool(solanaKit),
|
||||
new SolanaClosePosition(solanaKit),
|
||||
new SolanaOrcaCreateCLMM(solanaKit),
|
||||
new SolanaOrcaCreateSingleSideLiquidityPool(solanaKit),
|
||||
new SolanaOrcaFetchPositions(solanaKit),
|
||||
@@ -1632,5 +1871,7 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
|
||||
new SolanaCreateGibworkTask(solanaKit),
|
||||
new SolanaRockPaperScissorsTool(solanaKit),
|
||||
new SolanaTipLinkTool(solanaKit),
|
||||
new SolanaListNFTForSaleTool(solanaKit),
|
||||
new SolanaCancelNFTListingTool(solanaKit),
|
||||
];
|
||||
}
|
||||
|
||||
37
src/tools/cancel_all_orders.ts
Normal file
37
src/tools/cancel_all_orders.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {
|
||||
PublicKey,
|
||||
sendAndConfirmTransaction,
|
||||
Transaction,
|
||||
} from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { ManifestClient } from "@cks-systems/manifest-sdk";
|
||||
|
||||
/**
|
||||
* Cancels all orders from Manifest
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param marketId Public key for the manifest market
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function cancelAllOrders(
|
||||
agent: SolanaAgentKit,
|
||||
marketId: PublicKey,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const mfxClient = await ManifestClient.getClientForMarket(
|
||||
agent.connection,
|
||||
marketId,
|
||||
agent.wallet,
|
||||
);
|
||||
|
||||
const cancelAllOrdersIx = await mfxClient.cancelAllIx();
|
||||
const signature = await sendAndConfirmTransaction(
|
||||
agent.connection,
|
||||
new Transaction().add(cancelAllOrdersIx),
|
||||
[agent.wallet],
|
||||
);
|
||||
|
||||
return signature;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Cancel all orders failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
@@ -16,12 +16,12 @@ export async function create_image(
|
||||
n: number = 1,
|
||||
) {
|
||||
try {
|
||||
if (!agent.openai_api_key) {
|
||||
if (!agent.config.OPENAI_API_KEY) {
|
||||
throw new Error("OpenAI API key not found in agent configuration");
|
||||
}
|
||||
|
||||
const openai = new OpenAI({
|
||||
apiKey: agent.openai_api_key,
|
||||
apiKey: agent.config.OPENAI_API_KEY,
|
||||
});
|
||||
|
||||
const response = await openai.images.generate({
|
||||
|
||||
@@ -8,11 +8,10 @@ import { getAllTld } from "@onsol/tldparser";
|
||||
*/
|
||||
export async function getAllDomainsTLDs(
|
||||
agent: SolanaAgentKit,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
): Promise<String[]> {
|
||||
): Promise<string[]> {
|
||||
try {
|
||||
const tlds = await getAllTld(agent.connection);
|
||||
return tlds.map((tld) => tld.tld);
|
||||
return tlds.map((tld) => String(tld.tld));
|
||||
} catch (error: any) {
|
||||
throw new Error(`Failed to fetch TLDs: ${error.message}`);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ export * from "./get_balance_other";
|
||||
export * from "./mint_nft";
|
||||
export * from "./transfer";
|
||||
export * from "./trade";
|
||||
export * from "./limit_order";
|
||||
export * from "./cancel_all_orders";
|
||||
export * from "./withdraw_all";
|
||||
export * from "./register_domain";
|
||||
export * from "./resolve_sol_domain";
|
||||
export * from "./get_primary_domain";
|
||||
@@ -40,9 +43,12 @@ export * from "./raydium_create_ammV4";
|
||||
export * from "./raydium_create_clmm";
|
||||
export * from "./raydium_create_cpmm";
|
||||
export * from "./openbook_create_market";
|
||||
export * from "./manifest_create_market";
|
||||
export * from "./pyth_fetch_price";
|
||||
|
||||
export * from "./create_gibwork_task";
|
||||
|
||||
export * from "./rock_paper_scissor";
|
||||
export * from "./create_tiplinks";
|
||||
|
||||
export * from "./tensor_trade";
|
||||
|
||||
61
src/tools/limit_order.ts
Normal file
61
src/tools/limit_order.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import {
|
||||
PublicKey,
|
||||
Transaction,
|
||||
sendAndConfirmTransaction,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import {
|
||||
ManifestClient,
|
||||
WrapperPlaceOrderParamsExternal,
|
||||
} from "@cks-systems/manifest-sdk";
|
||||
import { OrderType } from "@cks-systems/manifest-sdk/client/ts/src/wrapper/types/OrderType";
|
||||
|
||||
/**
|
||||
* Place limit orders using Manifest
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param marketId Public key for the manifest market
|
||||
* @param quantity Amount to trade in tokens
|
||||
* @param side Buy or Sell
|
||||
* @param price Price in tokens ie. SOL/USDC
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function limitOrder(
|
||||
agent: SolanaAgentKit,
|
||||
marketId: PublicKey,
|
||||
quantity: number,
|
||||
side: string,
|
||||
price: number,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const mfxClient = await ManifestClient.getClientForMarket(
|
||||
agent.connection,
|
||||
marketId,
|
||||
agent.wallet,
|
||||
);
|
||||
|
||||
const orderParams: WrapperPlaceOrderParamsExternal = {
|
||||
numBaseTokens: quantity,
|
||||
tokenPrice: price,
|
||||
isBid: side === "Buy",
|
||||
lastValidSlot: 0,
|
||||
orderType: OrderType.Limit,
|
||||
clientOrderId: Number(Math.random() * 1000),
|
||||
};
|
||||
|
||||
const depositPlaceOrderIx: TransactionInstruction[] =
|
||||
await mfxClient.placeOrderWithRequiredDepositIx(
|
||||
agent.wallet.publicKey,
|
||||
orderParams,
|
||||
);
|
||||
const signature = await sendAndConfirmTransaction(
|
||||
agent.connection,
|
||||
new Transaction().add(...depositPlaceOrderIx),
|
||||
[agent.wallet],
|
||||
);
|
||||
|
||||
return signature;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Limit Order failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
43
src/tools/manifest_create_market.ts
Normal file
43
src/tools/manifest_create_market.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { ManifestClient } from "@cks-systems/manifest-sdk";
|
||||
import {
|
||||
Keypair,
|
||||
PublicKey,
|
||||
sendAndConfirmTransaction,
|
||||
SystemProgram,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
|
||||
export async function manifestCreateMarket(
|
||||
agent: SolanaAgentKit,
|
||||
baseMint: PublicKey,
|
||||
quoteMint: PublicKey,
|
||||
): Promise<string[]> {
|
||||
const marketKeypair: Keypair = Keypair.generate();
|
||||
const FIXED_MANIFEST_HEADER_SIZE: number = 256;
|
||||
const createAccountIx: TransactionInstruction = SystemProgram.createAccount({
|
||||
fromPubkey: agent.wallet.publicKey,
|
||||
newAccountPubkey: marketKeypair.publicKey,
|
||||
space: FIXED_MANIFEST_HEADER_SIZE,
|
||||
lamports: await agent.connection.getMinimumBalanceForRentExemption(
|
||||
FIXED_MANIFEST_HEADER_SIZE,
|
||||
),
|
||||
programId: new PublicKey("MNFSTqtC93rEfYHB6hF82sKdZpUDFWkViLByLd1k1Ms"),
|
||||
});
|
||||
const createMarketIx = ManifestClient["createMarketIx"](
|
||||
agent.wallet.publicKey,
|
||||
baseMint,
|
||||
quoteMint,
|
||||
marketKeypair.publicKey,
|
||||
);
|
||||
|
||||
const tx: Transaction = new Transaction();
|
||||
tx.add(createAccountIx);
|
||||
tx.add(createMarketIx);
|
||||
const signature = await sendAndConfirmTransaction(agent.connection, tx, [
|
||||
agent.wallet,
|
||||
marketKeypair,
|
||||
]);
|
||||
return [signature, marketKeypair.publicKey.toBase58()];
|
||||
}
|
||||
108
src/tools/tensor_trade.ts
Normal file
108
src/tools/tensor_trade.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { TensorSwapSDK } from "@tensor-oss/tensorswap-sdk";
|
||||
import { PublicKey, Transaction } from "@solana/web3.js";
|
||||
import { AnchorProvider, Wallet } from "@coral-xyz/anchor";
|
||||
import { BN } from "bn.js";
|
||||
import {
|
||||
getAssociatedTokenAddress,
|
||||
TOKEN_PROGRAM_ID,
|
||||
getAccount,
|
||||
} from "@solana/spl-token";
|
||||
|
||||
export async function listNFTForSale(
|
||||
agent: SolanaAgentKit,
|
||||
nftMint: PublicKey,
|
||||
price: number,
|
||||
): Promise<string> {
|
||||
try {
|
||||
if (!PublicKey.isOnCurve(nftMint)) {
|
||||
throw new Error("Invalid NFT mint address");
|
||||
}
|
||||
|
||||
const mintInfo = await agent.connection.getAccountInfo(nftMint);
|
||||
if (!mintInfo) {
|
||||
throw new Error(`NFT mint ${nftMint.toString()} does not exist`);
|
||||
}
|
||||
|
||||
const ata = await getAssociatedTokenAddress(nftMint, agent.wallet_address);
|
||||
|
||||
try {
|
||||
const tokenAccount = await getAccount(agent.connection, ata);
|
||||
|
||||
if (!tokenAccount || tokenAccount.amount <= 0) {
|
||||
throw new Error(`You don't own this NFT (${nftMint.toString()})`);
|
||||
}
|
||||
} catch (error: any) {
|
||||
throw new Error(
|
||||
`No token account found for mint ${nftMint.toString()}. Make sure you own this NFT.`,
|
||||
);
|
||||
}
|
||||
|
||||
const provider = new AnchorProvider(
|
||||
agent.connection,
|
||||
new Wallet(agent.wallet),
|
||||
AnchorProvider.defaultOptions(),
|
||||
);
|
||||
|
||||
const tensorSwapSdk = new TensorSwapSDK({ provider });
|
||||
const priceInLamports = new BN(price * 1e9);
|
||||
const nftSource = await getAssociatedTokenAddress(
|
||||
nftMint,
|
||||
agent.wallet_address,
|
||||
);
|
||||
|
||||
const { tx } = await tensorSwapSdk.list({
|
||||
nftMint,
|
||||
nftSource,
|
||||
owner: agent.wallet_address,
|
||||
price: priceInLamports,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
payer: agent.wallet_address,
|
||||
});
|
||||
|
||||
const transaction = new Transaction();
|
||||
transaction.add(...tx.ixs);
|
||||
return await agent.connection.sendTransaction(transaction, [
|
||||
agent.wallet,
|
||||
...tx.extraSigners,
|
||||
]);
|
||||
} catch (error: any) {
|
||||
console.error("Full error details:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function cancelListing(
|
||||
agent: SolanaAgentKit,
|
||||
nftMint: PublicKey,
|
||||
): Promise<string> {
|
||||
const provider = new AnchorProvider(
|
||||
agent.connection,
|
||||
new Wallet(agent.wallet),
|
||||
AnchorProvider.defaultOptions(),
|
||||
);
|
||||
|
||||
const tensorSwapSdk = new TensorSwapSDK({ provider });
|
||||
const nftDest = await getAssociatedTokenAddress(
|
||||
nftMint,
|
||||
agent.wallet_address,
|
||||
false,
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
|
||||
const { tx } = await tensorSwapSdk.delist({
|
||||
nftMint,
|
||||
nftDest,
|
||||
owner: agent.wallet_address,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
payer: agent.wallet_address,
|
||||
authData: null,
|
||||
});
|
||||
|
||||
const transaction = new Transaction();
|
||||
transaction.add(...tx.ixs);
|
||||
return await agent.connection.sendTransaction(transaction, [
|
||||
agent.wallet,
|
||||
...tx.extraSigners,
|
||||
]);
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
import { VersionedTransaction, PublicKey } from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { TOKENS, DEFAULT_OPTIONS, JUP_API } from "../constants";
|
||||
import {
|
||||
TOKENS,
|
||||
DEFAULT_OPTIONS,
|
||||
JUP_API,
|
||||
JUP_REFERRAL_ADDRESS,
|
||||
} from "../constants";
|
||||
import { getMint } from "@solana/spl-token";
|
||||
/**
|
||||
* Swap tokens using Jupiter Exchange
|
||||
@@ -11,6 +16,7 @@ import { getMint } from "@solana/spl-token";
|
||||
* @param slippageBps Slippage tolerance in basis points (default: 300 = 3%)
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
|
||||
export async function trade(
|
||||
agent: SolanaAgentKit,
|
||||
outputMint: PublicKey,
|
||||
@@ -38,11 +44,24 @@ export async function trade(
|
||||
`&amount=${scaledAmount}` +
|
||||
`&slippageBps=${slippageBps}` +
|
||||
`&onlyDirectRoutes=true` +
|
||||
`&maxAccounts=20`,
|
||||
`&maxAccounts=20` +
|
||||
`${agent.config.JUPITER_FEE_BPS ? `&platformFeeBps=${agent.config.JUPITER_FEE_BPS}` : ""}`,
|
||||
)
|
||||
).json();
|
||||
|
||||
// Get serialized transaction
|
||||
let feeAccount;
|
||||
if (agent.config.JUPITER_REFERRAL_ACCOUNT) {
|
||||
[feeAccount] = PublicKey.findProgramAddressSync(
|
||||
[
|
||||
Buffer.from("referral_ata"),
|
||||
new PublicKey(agent.config.JUPITER_REFERRAL_ACCOUNT).toBuffer(),
|
||||
TOKENS.SOL.toBuffer(),
|
||||
],
|
||||
new PublicKey(JUP_REFERRAL_ADDRESS),
|
||||
);
|
||||
}
|
||||
|
||||
const { swapTransaction } = await (
|
||||
await fetch("https://quote-api.jup.ag/v6/swap", {
|
||||
method: "POST",
|
||||
@@ -55,6 +74,7 @@ export async function trade(
|
||||
wrapAndUnwrapSol: true,
|
||||
dynamicComputeUnitLimit: true,
|
||||
prioritizationFeeLamports: "auto",
|
||||
feeAccount: feeAccount ? feeAccount.toString() : null,
|
||||
}),
|
||||
})
|
||||
).json();
|
||||
|
||||
37
src/tools/withdraw_all.ts
Normal file
37
src/tools/withdraw_all.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {
|
||||
PublicKey,
|
||||
sendAndConfirmTransaction,
|
||||
Transaction,
|
||||
} from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../index";
|
||||
import { ManifestClient } from "@cks-systems/manifest-sdk";
|
||||
|
||||
/**
|
||||
* Withdraws all funds from Manifest
|
||||
* @param agent SolanaAgentKit instance
|
||||
* @param marketId Public key for the manifest market
|
||||
* @returns Transaction signature
|
||||
*/
|
||||
export async function withdrawAll(
|
||||
agent: SolanaAgentKit,
|
||||
marketId: PublicKey,
|
||||
): Promise<string> {
|
||||
try {
|
||||
const mfxClient = await ManifestClient.getClientForMarket(
|
||||
agent.connection,
|
||||
marketId,
|
||||
agent.wallet,
|
||||
);
|
||||
|
||||
const withdrawAllIx = await mfxClient.withdrawAllIx();
|
||||
const signature = await sendAndConfirmTransaction(
|
||||
agent.connection,
|
||||
new Transaction().add(...withdrawAllIx),
|
||||
[agent.wallet],
|
||||
);
|
||||
|
||||
return signature;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Withdraw all failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -1,4 +1,12 @@
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
|
||||
export interface Config {
|
||||
OPENAI_API_KEY?: string;
|
||||
JUPITER_REFERRAL_ACCOUNT?: string;
|
||||
JUPITER_FEE_BPS?: number;
|
||||
}
|
||||
|
||||
export interface Creator {
|
||||
address: string;
|
||||
@@ -91,3 +99,57 @@ export interface GibworkCreateTaskReponse {
|
||||
taskId?: string | undefined;
|
||||
signature?: string | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
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 Object.values(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");
|
||||
}
|
||||
Reference in New Issue
Block a user