mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-05-14 07:26:46 +00:00
feat: Refactor actions to use tool functions for improved code clarity and maintainability
This commit is contained in:
@@ -2,6 +2,7 @@ import { PublicKey } from "@solana/web3.js";
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { get_balance } from "../tools";
|
||||
|
||||
const balanceAction: Action = {
|
||||
name: "solana_balance",
|
||||
@@ -45,8 +46,7 @@ const balanceAction: Action = {
|
||||
tokenAddress: z.string().optional()
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
const tokenAddress = input.tokenAddress ? new PublicKey(input.tokenAddress) : undefined;
|
||||
const balance = await agent.getBalance(tokenAddress);
|
||||
const balance = await get_balance(agent, input.tokenAddress && new PublicKey(input.tokenAddress));
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey, VersionedTransaction } from "@solana/web3.js";
|
||||
import { create_gibwork_task } from "../tools";
|
||||
|
||||
const createGibworkTaskAction: Action = {
|
||||
name: "solana_create_gibwork_task",
|
||||
@@ -62,65 +63,21 @@ const createGibworkTaskAction: Action = {
|
||||
const tokenMintAddress = new PublicKey(input.tokenMintAddress);
|
||||
const payer = input.payer ? new PublicKey(input.payer) : undefined;
|
||||
|
||||
const apiResponse = await fetch(
|
||||
"https://api2.gib.work/tasks/public/transaction",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
title: input.title,
|
||||
content: input.content,
|
||||
requirements: input.requirements,
|
||||
tags: input.tags,
|
||||
payer: payer?.toBase58() || agent.wallet.publicKey.toBase58(),
|
||||
token: {
|
||||
mintAddress: tokenMintAddress.toBase58(),
|
||||
amount: input.tokenAmount,
|
||||
},
|
||||
}),
|
||||
}
|
||||
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
|
||||
);
|
||||
|
||||
if (!apiResponse.ok) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to create task: ${apiResponse.statusText}`
|
||||
};
|
||||
}
|
||||
|
||||
const responseData = await apiResponse.json();
|
||||
if (!responseData.taskId || !responseData.serializedTransaction) {
|
||||
return {
|
||||
status: "error",
|
||||
message: responseData.message || "Invalid response from Gibwork API"
|
||||
};
|
||||
}
|
||||
|
||||
const serializedTransaction = Buffer.from(
|
||||
responseData.serializedTransaction,
|
||||
"base64"
|
||||
);
|
||||
const tx = VersionedTransaction.deserialize(serializedTransaction);
|
||||
|
||||
tx.sign([agent.wallet]);
|
||||
const signature = await agent.connection.sendTransaction(tx, {
|
||||
preflightCommitment: "confirmed",
|
||||
maxRetries: 3,
|
||||
});
|
||||
|
||||
const latestBlockhash = await agent.connection.getLatestBlockhash();
|
||||
await agent.connection.confirmTransaction({
|
||||
signature,
|
||||
blockhash: latestBlockhash.blockhash,
|
||||
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
|
||||
});
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
taskId: responseData.taskId,
|
||||
signature,
|
||||
signature: responseData.signature,
|
||||
message: `Successfully created task: ${input.title}`
|
||||
};
|
||||
} catch (error: any) {
|
||||
|
||||
@@ -2,6 +2,8 @@ import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import OpenAI from "openai";
|
||||
import { create } from "domain";
|
||||
import { create_image } from "../tools/create_image";
|
||||
|
||||
const createImageAction: Action = {
|
||||
name: "solana_create_image",
|
||||
@@ -60,31 +62,17 @@ const createImageAction: Action = {
|
||||
};
|
||||
}
|
||||
|
||||
const { prompt, model, size, quality, style } = input;
|
||||
const { prompt, model, size } = input;
|
||||
|
||||
const openai = new OpenAI({
|
||||
apiKey: agent.openai_api_key
|
||||
});
|
||||
|
||||
const response = await openai.images.generate({
|
||||
prompt,
|
||||
model,
|
||||
n: 1,
|
||||
size,
|
||||
quality,
|
||||
style
|
||||
});
|
||||
|
||||
if (!response.data || response.data.length === 0) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "No image was generated"
|
||||
};
|
||||
}
|
||||
const response = await create_image(agent, prompt, model, size);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
imageUrl: response.data[0].url,
|
||||
imageUrl: response.images[0].url,
|
||||
message: "Successfully generated image"
|
||||
};
|
||||
} catch (error: any) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { z } from "zod";
|
||||
import { OPEN_BOOK_PROGRAM, Raydium, TxVersion } from "@raydium-io/raydium-sdk-v2";
|
||||
import { MintLayout, TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { openbookCreateMarket } from "../tools";
|
||||
|
||||
const createOpenbookMarketAction: Action = {
|
||||
name: "solana_create_openbook_market",
|
||||
@@ -57,54 +58,18 @@ const createOpenbookMarketAction: Action = {
|
||||
const lotSize = input.lotSize || 1;
|
||||
const tickSize = input.tickSize || 0.01;
|
||||
|
||||
const raydium = await Raydium.load({
|
||||
owner: agent.wallet,
|
||||
connection: agent.connection,
|
||||
});
|
||||
|
||||
// Get mint info
|
||||
const baseMintInfo = await agent.connection.getAccountInfo(baseMint);
|
||||
const quoteMintInfo = await agent.connection.getAccountInfo(quoteMint);
|
||||
|
||||
if (!baseMintInfo || !quoteMintInfo) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Failed to fetch mint information"
|
||||
};
|
||||
}
|
||||
|
||||
// Verify token program
|
||||
if (
|
||||
baseMintInfo.owner.toString() !== TOKEN_PROGRAM_ID.toBase58() ||
|
||||
quoteMintInfo.owner.toString() !== TOKEN_PROGRAM_ID.toBase58()
|
||||
) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Openbook market only supports TOKEN_PROGRAM_ID mints. For token-2022, please use Raydium CPMM pool instead."
|
||||
};
|
||||
}
|
||||
|
||||
// Create market
|
||||
const { execute } = await raydium.marketV2.create({
|
||||
baseInfo: {
|
||||
mint: baseMint,
|
||||
decimals: MintLayout.decode(baseMintInfo.data).decimals,
|
||||
},
|
||||
quoteInfo: {
|
||||
mint: quoteMint,
|
||||
decimals: MintLayout.decode(quoteMintInfo.data).decimals,
|
||||
},
|
||||
const signatures = await openbookCreateMarket(
|
||||
agent,
|
||||
baseMint,
|
||||
quoteMint,
|
||||
lotSize,
|
||||
tickSize,
|
||||
dexProgramId: OPEN_BOOK_PROGRAM,
|
||||
txVersion: TxVersion.V0,
|
||||
});
|
||||
|
||||
const { txIds } = await execute({ sequentially: true });
|
||||
tickSize
|
||||
);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
signatures: txIds,
|
||||
signatures,
|
||||
message: "Successfully created Openbook market"
|
||||
};
|
||||
} catch (error: any) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { BN } from "@coral-xyz/anchor";
|
||||
import { Decimal } from "decimal.js";
|
||||
import { createOrcaSingleSidedWhirlpool } from "../tools";
|
||||
|
||||
// Fee tiers mapping from the original tool
|
||||
const FEE_TIERS = {
|
||||
@@ -79,7 +80,8 @@ const createOrcaSingleSidedWhirlpoolAction: Action = {
|
||||
const feeTier = input.feeTier as keyof typeof FEE_TIERS;
|
||||
|
||||
// Create the whirlpool
|
||||
const signature = await agent.createOrcaSingleSidedWhirlpool(
|
||||
const signature = await createOrcaSingleSidedWhirlpool(
|
||||
agent,
|
||||
depositTokenAmount,
|
||||
depositTokenMint,
|
||||
otherTokenMint,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { PublicKey } from "@solana/web3.js";
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { deploy_collection } from "../tools";
|
||||
|
||||
interface CollectionOptions {
|
||||
name: string;
|
||||
@@ -64,7 +65,7 @@ const deployCollectionAction: Action = {
|
||||
royaltyBasisPoints: input.royaltyBasisPoints
|
||||
};
|
||||
|
||||
const result = await agent.deployCollection(options);
|
||||
const result = await deploy_collection(agent, options);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
|
||||
@@ -2,6 +2,7 @@ import { PublicKey } from "@solana/web3.js";
|
||||
import { Action, ActionExample } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { deploy_token } from "../tools";
|
||||
|
||||
const deployTokenAction: Action = {
|
||||
name: "deploy_token",
|
||||
@@ -55,19 +56,27 @@ const deployTokenAction: Action = {
|
||||
initialSupply: z.number().optional()
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
const result = await agent.deployToken(
|
||||
input.name,
|
||||
input.uri,
|
||||
input.symbol,
|
||||
input.decimals,
|
||||
input.initialSupply
|
||||
);
|
||||
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"
|
||||
};
|
||||
return {
|
||||
mint: result.mint.toString(),
|
||||
status: "success",
|
||||
message: "Token deployed successfully"
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Token deployment failed: ${error.message}`
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { fetchPrice } from "../tools";
|
||||
|
||||
const fetchPriceAction: Action = {
|
||||
name: "solana_fetch_price",
|
||||
@@ -34,24 +35,7 @@ const fetchPriceAction: Action = {
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const tokenId = new PublicKey(input.tokenAddress);
|
||||
const response = await fetch(`https://api.jup.ag/price/v2?ids=${tokenId}`);
|
||||
|
||||
if (!response.ok) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to fetch price: ${response.statusText}`
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const price = data.data[tokenId.toBase58()]?.price;
|
||||
|
||||
if (!price) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Price data not available for the given token"
|
||||
};
|
||||
}
|
||||
const price = await fetchPrice(tokenId);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { getAllDomainsTLDs } from "../tools";
|
||||
|
||||
const getAllDomainsTLDsAction: Action = {
|
||||
name: "solana_get_all_domains_tlds",
|
||||
@@ -30,7 +31,7 @@ const getAllDomainsTLDsAction: Action = {
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
// Get all domain TLDs
|
||||
const tlds = await agent.getAllDomainsTLDs();
|
||||
const tlds = await getAllDomainsTLDs(agent);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { getAllRegisteredAllDomains } from "../tools";
|
||||
|
||||
const getAllRegisteredAllDomainsAction: Action = {
|
||||
name: "solana_get_all_registered_all_domains",
|
||||
@@ -47,14 +48,12 @@ const getAllRegisteredAllDomainsAction: Action = {
|
||||
const offset = input.offset || 0;
|
||||
|
||||
// Get all registered domains
|
||||
const domains = await agent.getAllRegisteredAllDomains();
|
||||
const domains = await getAllRegisteredAllDomains(agent);
|
||||
|
||||
// Apply pagination
|
||||
const paginatedDomains = domains.slice(offset, offset + limit);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
domains: paginatedDomains,
|
||||
domains: domains.slice(offset, offset + limit),
|
||||
total: domains.length,
|
||||
message: "Successfully retrieved registered domains"
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { TldParser } from "@onsol/tldparser";
|
||||
import { getMainAllDomainsDomain } from "../tools";
|
||||
|
||||
const getMainAllDomainsDomainAction: Action = {
|
||||
name: "solana_get_main_all_domains_domain",
|
||||
@@ -37,11 +38,7 @@ const getMainAllDomainsDomainAction: Action = {
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const address = new PublicKey(input.address);
|
||||
|
||||
// Get the main domain using TldParser
|
||||
const parser = new TldParser(agent.connection);
|
||||
const mainDomain = await parser.getMainDomain(address);
|
||||
const mainDomain = await getMainAllDomainsDomain(agent, new PublicKey(input.address));
|
||||
|
||||
if (!mainDomain) {
|
||||
return {
|
||||
@@ -52,7 +49,7 @@ const getMainAllDomainsDomainAction: Action = {
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
domain: mainDomain.domain,
|
||||
domain: mainDomain,
|
||||
message: "Successfully retrieved main domain"
|
||||
};
|
||||
} catch (error: any) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { getOwnedAllDomains } from "../tools";
|
||||
|
||||
const getOwnedAllDomainsAction: Action = {
|
||||
name: "solana_get_owned_all_domains",
|
||||
@@ -40,7 +41,7 @@ const getOwnedAllDomainsAction: Action = {
|
||||
const address = new PublicKey(input.address);
|
||||
|
||||
// Get owned domains
|
||||
const domains = await agent.getOwnedAllDomains(address);
|
||||
const domains = await getOwnedAllDomains(agent, address);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { getOwnedDomainsForTLD } from "../tools";
|
||||
|
||||
const getOwnedDomainsForTLDAction: Action = {
|
||||
name: "solana_get_owned_domains_for_tld",
|
||||
@@ -40,7 +41,7 @@ const getOwnedDomainsForTLDAction: Action = {
|
||||
const tld = input.tld.toLowerCase();
|
||||
|
||||
// Get owned domains for TLD
|
||||
const domains = await agent.getOwnedDomainsForTLD(tld);
|
||||
const domains = await getOwnedDomainsForTLD(agent, tld);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
|
||||
@@ -3,6 +3,7 @@ import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { getPrimaryDomain as _getPrimaryDomain } from "@bonfida/spl-name-service";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { getPrimaryDomain } from "../tools";
|
||||
|
||||
const getPrimaryDomainAction: Action = {
|
||||
name: "solana_get_primary_domain",
|
||||
@@ -39,22 +40,16 @@ const getPrimaryDomainAction: Action = {
|
||||
try {
|
||||
const account = new PublicKey(input.account);
|
||||
|
||||
const { reverse, stale } = await _getPrimaryDomain(
|
||||
agent.connection,
|
||||
const response = await getPrimaryDomain(
|
||||
agent,
|
||||
account
|
||||
);
|
||||
|
||||
if (stale) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Primary domain is stale for account: ${account.toBase58()}`
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
domain: reverse,
|
||||
message: `Primary domain: ${reverse}`
|
||||
domain: response,
|
||||
message: `Primary domain: ${response}`
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { getTPS } from "../tools";
|
||||
|
||||
const getTPSAction: Action = {
|
||||
name: "solana_get_tps",
|
||||
@@ -28,27 +29,11 @@ const getTPSAction: Action = {
|
||||
schema: z.object({}), // No input parameters required
|
||||
handler: async (agent: SolanaAgentKit, _input: Record<string, any>) => {
|
||||
try {
|
||||
const perfSamples = await agent.connection.getRecentPerformanceSamples();
|
||||
|
||||
if (
|
||||
!perfSamples.length ||
|
||||
!perfSamples[0]?.numTransactions ||
|
||||
!perfSamples[0]?.samplePeriodSecs
|
||||
) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "No performance samples available"
|
||||
};
|
||||
}
|
||||
|
||||
const tps = Math.round(
|
||||
perfSamples[0].numTransactions / perfSamples[0].samplePeriodSecs
|
||||
);
|
||||
|
||||
const response = await getTPS(agent);
|
||||
return {
|
||||
status: "success",
|
||||
tps,
|
||||
message: `Current network TPS: ${tps}`
|
||||
response,
|
||||
message: `Current network TPS: ${response}`
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import { JupiterTokenData } from "../types";
|
||||
import { getTokenAddressFromTicker, getTokenDataByAddress } from "../tools";
|
||||
|
||||
const getTokenDataAction: Action = {
|
||||
name: "solana_get_token_data",
|
||||
@@ -59,59 +60,20 @@ const getTokenDataAction: Action = {
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
let tokenData: JupiterTokenData | undefined;
|
||||
|
||||
if (input.address) {
|
||||
const mint = new PublicKey(input.address);
|
||||
const response = await fetch("https://tokens.jup.ag/tokens?tags=verified", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
const data = (await response.json()) as JupiterTokenData[];
|
||||
tokenData = data.find((token: JupiterTokenData) => token.address === mint.toBase58());
|
||||
tokenData = await getTokenDataByAddress(new PublicKey(input.address));
|
||||
} else if (input.ticker) {
|
||||
const response = await fetch(
|
||||
`https://api.dexscreener.com/latest/dex/search?q=${input.ticker}`
|
||||
);
|
||||
const data = await response.json();
|
||||
|
||||
if (!data.pairs || data.pairs.length === 0) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `No token found for ticker: ${input.ticker}`
|
||||
};
|
||||
const address = await getTokenAddressFromTicker(input.ticker);
|
||||
if (address) {
|
||||
tokenData = await getTokenDataByAddress(new PublicKey(address));
|
||||
}
|
||||
|
||||
let solanaPairs = data.pairs
|
||||
.filter((pair: any) => pair.chainId === "solana")
|
||||
.sort((a: any, b: any) => (b.fdv || 0) - (a.fdv || 0))
|
||||
.filter(
|
||||
(pair: any) =>
|
||||
pair.baseToken.symbol.toLowerCase() === input.ticker.toLowerCase()
|
||||
);
|
||||
|
||||
if (solanaPairs.length === 0) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `No Solana token found for ticker: ${input.ticker}`
|
||||
};
|
||||
}
|
||||
|
||||
const address = solanaPairs[0].baseToken.address;
|
||||
const jupResponse = await fetch("https://tokens.jup.ag/tokens?tags=verified");
|
||||
const jupData = (await jupResponse.json()) as JupiterTokenData[];
|
||||
tokenData = jupData.find((token: JupiterTokenData) => token.address === address);
|
||||
}
|
||||
|
||||
if (!tokenData) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Token not found or not verified"
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
token: {
|
||||
|
||||
@@ -16,15 +16,12 @@ import createGibworkTaskAction from "./createGibworkTask";
|
||||
import resolveSolDomainAction from "./resolveSolDomain";
|
||||
import pythFetchPriceAction from "./pythFetchPrice";
|
||||
import getOwnedDomainsForTLDAction from "./getOwnedDomainsForTLD";
|
||||
import createRaydiumCLMMAction from "./createRaydiumCLMM";
|
||||
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 createRaydiumCPMMAction from "./createRaydiumCPMM";
|
||||
import sendCompressedAirdropAction from "./sendCompressedAirdrop";
|
||||
import raydiumCreateCpmmAction from "./raydiumCreateCpmm";
|
||||
import raydiumCreateAmmV4Action from "./raydiumCreateAmmV4";
|
||||
import createOrcaSingleSidedWhirlpoolAction from "./createOrcaSingleSidedWhirlpool";
|
||||
@@ -49,15 +46,12 @@ export const actions = [
|
||||
resolveSolDomainAction,
|
||||
pythFetchPriceAction,
|
||||
getOwnedDomainsForTLDAction,
|
||||
createRaydiumCLMMAction,
|
||||
getPrimaryDomainAction,
|
||||
getAllDomainsTLDsAction,
|
||||
getOwnedAllDomainsAction,
|
||||
createImageAction,
|
||||
getMainAllDomainsDomainAction,
|
||||
getAllRegisteredAllDomainsAction,
|
||||
createRaydiumCPMMAction,
|
||||
sendCompressedAirdropAction,
|
||||
raydiumCreateCpmmAction,
|
||||
raydiumCreateAmmV4Action,
|
||||
createOrcaSingleSidedWhirlpoolAction,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { VersionedTransaction, Keypair } from "@solana/web3.js";
|
||||
import { launchPumpFunToken } from "../tools";
|
||||
|
||||
const launchPumpfunTokenAction: Action = {
|
||||
name: "solana_launch_pumpfun_token",
|
||||
@@ -82,113 +83,14 @@ const launchPumpfunTokenAction: Action = {
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const mintKeypair = Keypair.generate();
|
||||
|
||||
// Upload metadata
|
||||
const formData = new URLSearchParams();
|
||||
formData.append("name", input.tokenName);
|
||||
formData.append("symbol", input.tokenTicker);
|
||||
formData.append("description", input.description);
|
||||
formData.append("showName", "true");
|
||||
|
||||
if (input.twitter) {
|
||||
formData.append("twitter", input.twitter);
|
||||
}
|
||||
if (input.telegram) {
|
||||
formData.append("telegram", input.telegram);
|
||||
}
|
||||
if (input.website) {
|
||||
formData.append("website", input.website);
|
||||
}
|
||||
|
||||
// Fetch and process image
|
||||
const imageResponse = await fetch(input.imageUrl);
|
||||
const imageBlob = await imageResponse.blob();
|
||||
const imageFile = new File([imageBlob], "token_image.png", { type: "image/png" });
|
||||
|
||||
// Create final form data
|
||||
const finalFormData = new FormData();
|
||||
for (const [key, value] of formData.entries()) {
|
||||
finalFormData.append(key, value);
|
||||
}
|
||||
finalFormData.append("file", imageFile);
|
||||
|
||||
// Upload metadata to IPFS
|
||||
const metadataResponse = await fetch("https://pump.fun/api/ipfs", {
|
||||
method: "POST",
|
||||
body: finalFormData,
|
||||
});
|
||||
|
||||
if (!metadataResponse.ok) {
|
||||
throw new Error(`Metadata upload failed: ${metadataResponse.statusText}`);
|
||||
}
|
||||
|
||||
const metadataResult = await metadataResponse.json();
|
||||
|
||||
// Create token transaction
|
||||
const payload = {
|
||||
publicKey: agent.wallet_address.toBase58(),
|
||||
action: "create",
|
||||
tokenMetadata: {
|
||||
name: metadataResult.metadata.name,
|
||||
symbol: metadataResult.metadata.symbol,
|
||||
uri: metadataResult.metadataUri,
|
||||
},
|
||||
mint: mintKeypair.publicKey.toBase58(),
|
||||
denominatedInSol: "true",
|
||||
amount: input.initialLiquiditySOL || 0.0001,
|
||||
slippage: input.slippageBps || 5,
|
||||
priorityFee: input.priorityFee || 0.00005,
|
||||
pool: "pump",
|
||||
};
|
||||
|
||||
const txResponse = await fetch("https://pumpportal.fun/api/trade-local", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
if (!txResponse.ok) {
|
||||
const errorText = await txResponse.text();
|
||||
throw new Error(`Transaction creation failed: ${txResponse.status} - ${errorText}`);
|
||||
}
|
||||
|
||||
// Process and sign transaction
|
||||
const transactionData = await txResponse.arrayBuffer();
|
||||
const tx = VersionedTransaction.deserialize(new Uint8Array(transactionData));
|
||||
|
||||
// Get latest blockhash
|
||||
const { blockhash, lastValidBlockHeight } = await agent.connection.getLatestBlockhash();
|
||||
tx.message.recentBlockhash = blockhash;
|
||||
|
||||
// Sign transaction
|
||||
tx.sign([mintKeypair, agent.wallet]);
|
||||
|
||||
// Send transaction
|
||||
const signature = await agent.connection.sendTransaction(tx, {
|
||||
skipPreflight: false,
|
||||
preflightCommitment: "confirmed",
|
||||
maxRetries: 5,
|
||||
});
|
||||
|
||||
// Wait for confirmation
|
||||
const confirmation = await agent.connection.confirmTransaction({
|
||||
signature,
|
||||
blockhash,
|
||||
lastValidBlockHeight,
|
||||
});
|
||||
|
||||
if (confirmation.value.err) {
|
||||
throw new Error(`Transaction failed: ${confirmation.value.err}`);
|
||||
}
|
||||
const { tokenName, tokenTicker, description, imageUrl } = input;
|
||||
const result = await launchPumpFunToken(agent, tokenName, tokenTicker, description, imageUrl, input);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
signature,
|
||||
mint: mintKeypair.publicKey.toBase58(),
|
||||
metadataUri: metadataResult.metadataUri,
|
||||
signature: result.signature,
|
||||
mint: result.mint,
|
||||
metadataUri: result.metadataUri,
|
||||
message: "Successfully launched token on Pump.fun"
|
||||
};
|
||||
} catch (error: any) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { VersionedTransaction } from "@solana/web3.js";
|
||||
import { lendAsset } from "../tools";
|
||||
|
||||
const lendAssetAction: Action = {
|
||||
name: "solana_lend_asset",
|
||||
@@ -38,55 +39,11 @@ const lendAssetAction: Action = {
|
||||
try {
|
||||
const amount = input.amount as number;
|
||||
|
||||
const response = await fetch(
|
||||
`https://blink.lulo.fi/actions?amount=${amount}&symbol=USDC`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
account: agent.wallet.publicKey.toBase58(),
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to get lending transaction: ${response.statusText}`
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
// Deserialize the transaction
|
||||
const luloTxn = VersionedTransaction.deserialize(
|
||||
Buffer.from(data.transaction, "base64")
|
||||
);
|
||||
|
||||
// Get a recent blockhash and set it
|
||||
const { blockhash } = await agent.connection.getLatestBlockhash();
|
||||
luloTxn.message.recentBlockhash = blockhash;
|
||||
|
||||
// Sign and send transaction
|
||||
luloTxn.sign([agent.wallet]);
|
||||
const signature = await agent.connection.sendTransaction(luloTxn, {
|
||||
preflightCommitment: "confirmed",
|
||||
maxRetries: 3,
|
||||
});
|
||||
|
||||
// Wait for confirmation
|
||||
const latestBlockhash = await agent.connection.getLatestBlockhash();
|
||||
await agent.connection.confirmTransaction({
|
||||
signature,
|
||||
blockhash: latestBlockhash.blockhash,
|
||||
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
|
||||
});
|
||||
const response = await lendAsset(agent, amount);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
signature,
|
||||
signature: response,
|
||||
message: `Successfully lent ${amount} USDC`
|
||||
};
|
||||
} catch (error: any) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { PublicKey } from "@solana/web3.js";
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { mintCollectionNFT } from "../tools";
|
||||
|
||||
const mintNFTAction: Action = {
|
||||
name: "solana_mint_nft",
|
||||
@@ -63,13 +64,14 @@ const mintNFTAction: Action = {
|
||||
recipient: z.string().min(32, "Invalid recipient address").optional()
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
const result = await agent.mintNFT(
|
||||
const result = await mintCollectionNFT(
|
||||
agent,
|
||||
new PublicKey(input.collectionMint),
|
||||
{
|
||||
name: input.name,
|
||||
uri: input.uri,
|
||||
uri: input.uri
|
||||
},
|
||||
input.recipient ? new PublicKey(input.recipient) : agent.wallet_address
|
||||
input.recipient ? new PublicKey(input.recipient) : undefined
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { PriceServiceConnection } from "@pythnetwork/price-service-client";
|
||||
import BN from "bn.js";
|
||||
import { pythFetchPrice } from "../tools";
|
||||
|
||||
const pythFetchPriceAction: Action = {
|
||||
name: "solana_pyth_fetch_price",
|
||||
@@ -39,27 +40,7 @@ const pythFetchPriceAction: Action = {
|
||||
try {
|
||||
const priceFeedId = input.priceFeedId as string;
|
||||
|
||||
// Connect to Hermes service
|
||||
const stableHermesServiceUrl = "https://hermes.pyth.network";
|
||||
const connection = new PriceServiceConnection(stableHermesServiceUrl);
|
||||
const feeds = [priceFeedId];
|
||||
|
||||
const currentPrice = await connection.getLatestPriceFeeds(feeds);
|
||||
|
||||
if (!currentPrice || currentPrice.length === 0) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Price data not available for the given feed ID"
|
||||
};
|
||||
}
|
||||
|
||||
// Get price and exponent from price feed
|
||||
const price = new BN(currentPrice[0].getPriceUnchecked().price);
|
||||
const exponent = new BN(currentPrice[0].getPriceUnchecked().expo);
|
||||
|
||||
// Convert to scaled price
|
||||
const scaledPrice = price.div(new BN(10).pow(exponent));
|
||||
const priceStr = scaledPrice.toString();
|
||||
const priceStr = await pythFetchPrice(priceFeedId);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
import { MintLayout, TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import BN from "bn.js";
|
||||
import { raydiumCreateAmmV4 } from "../tools";
|
||||
|
||||
const raydiumCreateAmmV4Action: Action = {
|
||||
name: "solana_raydium_create_amm_v4",
|
||||
@@ -72,70 +73,7 @@ const raydiumCreateAmmV4Action: Action = {
|
||||
const quoteAmount = new BN(input.quoteAmount);
|
||||
const startTime = new BN(input.startTime);
|
||||
|
||||
const raydium = await Raydium.load({
|
||||
owner: agent.wallet,
|
||||
connection: agent.connection,
|
||||
});
|
||||
|
||||
const marketBufferInfo = await agent.connection.getAccountInfo(
|
||||
new PublicKey(marketId),
|
||||
);
|
||||
const { baseMint, quoteMint } = MARKET_STATE_LAYOUT_V3.decode(
|
||||
marketBufferInfo!.data,
|
||||
);
|
||||
|
||||
const baseMintInfo = await agent.connection.getAccountInfo(baseMint);
|
||||
const quoteMintInfo = await agent.connection.getAccountInfo(quoteMint);
|
||||
|
||||
if (
|
||||
baseMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58() ||
|
||||
quoteMintInfo?.owner.toString() !== TOKEN_PROGRAM_ID.toBase58()
|
||||
) {
|
||||
throw new Error(
|
||||
"amm pools with openbook market only support TOKEN_PROGRAM_ID mints, if you want to create pool with token-2022, please create cpmm pool instead",
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
baseAmount
|
||||
.mul(quoteAmount)
|
||||
.lte(
|
||||
new BN(1)
|
||||
.mul(new BN(10 ** MintLayout.decode(baseMintInfo.data).decimals))
|
||||
.pow(new BN(2)),
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
"initial liquidity too low, try adding more baseAmount/quoteAmount",
|
||||
);
|
||||
}
|
||||
|
||||
const { execute } = await raydium.liquidity.createPoolV4({
|
||||
programId: AMM_V4,
|
||||
marketInfo: {
|
||||
marketId,
|
||||
programId: OPEN_BOOK_PROGRAM,
|
||||
},
|
||||
baseMintInfo: {
|
||||
mint: baseMint,
|
||||
decimals: MintLayout.decode(baseMintInfo.data).decimals,
|
||||
},
|
||||
quoteMintInfo: {
|
||||
mint: quoteMint,
|
||||
decimals: MintLayout.decode(quoteMintInfo.data).decimals,
|
||||
},
|
||||
baseAmount,
|
||||
quoteAmount,
|
||||
startTime,
|
||||
ownerInfo: {
|
||||
useSOLBalance: true,
|
||||
},
|
||||
associatedOnly: false,
|
||||
txVersion: TxVersion.V0,
|
||||
feeDestinationId: FEE_DESTINATION_ID,
|
||||
});
|
||||
|
||||
const { txId } = await execute({ sendAndConfirm: true });
|
||||
const txId = await raydiumCreateAmmV4(agent, marketId, baseAmount, quoteAmount, startTime);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
import { MintLayout } from "@solana/spl-token";
|
||||
import { PublicKey } from "@solana/web3.js";
|
||||
import BN from "bn.js";
|
||||
import { raydiumCreateCpmm } from "../tools";
|
||||
|
||||
const raydiumCreateCpmmAction: Action = {
|
||||
name: "solana_raydium_create_cpmm",
|
||||
@@ -68,62 +69,7 @@ const raydiumCreateCpmmAction: Action = {
|
||||
const mintBAmount = new BN(input.quoteAmount);
|
||||
const startTime = new BN(input.startTime);
|
||||
|
||||
const raydium = await Raydium.load({
|
||||
owner: agent.wallet,
|
||||
connection: agent.connection,
|
||||
});
|
||||
|
||||
const [mintInfoA, mintInfoB] = await agent.connection.getMultipleAccountsInfo(
|
||||
[mintA, mintB],
|
||||
);
|
||||
if (mintInfoA === null || mintInfoB === null) {
|
||||
throw Error("fetch mint info error");
|
||||
}
|
||||
|
||||
const mintDecodeInfoA = MintLayout.decode(mintInfoA.data);
|
||||
const mintDecodeInfoB = MintLayout.decode(mintInfoB.data);
|
||||
|
||||
const mintFormatInfoA = {
|
||||
chainId: 101,
|
||||
address: mintA.toString(),
|
||||
programId: mintInfoA.owner.toString(),
|
||||
logoURI: "",
|
||||
symbol: "",
|
||||
name: "",
|
||||
decimals: mintDecodeInfoA.decimals,
|
||||
tags: [],
|
||||
extensions: {},
|
||||
};
|
||||
const mintFormatInfoB = {
|
||||
chainId: 101,
|
||||
address: mintB.toString(),
|
||||
programId: mintInfoB.owner.toString(),
|
||||
logoURI: "",
|
||||
symbol: "",
|
||||
name: "",
|
||||
decimals: mintDecodeInfoB.decimals,
|
||||
tags: [],
|
||||
extensions: {},
|
||||
};
|
||||
|
||||
const { execute } = await raydium.cpmm.createPool({
|
||||
programId: CREATE_CPMM_POOL_PROGRAM,
|
||||
poolFeeAccount: CREATE_CPMM_POOL_FEE_ACC,
|
||||
mintA: mintFormatInfoA,
|
||||
mintB: mintFormatInfoB,
|
||||
mintAAmount,
|
||||
mintBAmount,
|
||||
startTime,
|
||||
//@ts-expect-error sdk bug
|
||||
feeConfig: { id: configId.toString() },
|
||||
associatedOnly: false,
|
||||
ownerInfo: {
|
||||
useSOLBalance: true,
|
||||
},
|
||||
txVersion: TxVersion.V0,
|
||||
});
|
||||
|
||||
const { txId } = await execute({ sendAndConfirm: true });
|
||||
const txId = await raydiumCreateCpmm(agent, mintA, mintB, configId, mintAAmount, mintBAmount, startTime);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Transaction } from "@solana/web3.js";
|
||||
import { registerDomainNameV2 } from "@bonfida/spl-name-service";
|
||||
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
|
||||
import { TOKENS } from "../constants";
|
||||
import { registerDomain } from "../tools";
|
||||
|
||||
const registerDomainAction: Action = {
|
||||
name: "solana_register_domain",
|
||||
@@ -48,50 +49,7 @@ const registerDomainAction: Action = {
|
||||
const name = input.name as string;
|
||||
const spaceKB = (input.spaceKB as number) || 1;
|
||||
|
||||
// Validate space size
|
||||
if (spaceKB > 10) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Maximum domain size is 10KB"
|
||||
};
|
||||
}
|
||||
|
||||
// Convert KB to bytes
|
||||
const space = spaceKB * 1_000;
|
||||
|
||||
const buyerTokenAccount = await getAssociatedTokenAddressSync(
|
||||
agent.wallet_address,
|
||||
TOKENS.USDC
|
||||
);
|
||||
|
||||
// Create registration instruction
|
||||
const instruction = await registerDomainNameV2(
|
||||
agent.connection,
|
||||
name,
|
||||
space,
|
||||
agent.wallet_address,
|
||||
buyerTokenAccount
|
||||
);
|
||||
|
||||
// Create and sign transaction
|
||||
const transaction = new Transaction().add(...instruction);
|
||||
transaction.recentBlockhash = (
|
||||
await agent.connection.getLatestBlockhash()
|
||||
).blockhash;
|
||||
transaction.feePayer = agent.wallet_address;
|
||||
|
||||
// Sign and send transaction
|
||||
const signature = await agent.connection.sendTransaction(transaction, [
|
||||
agent.wallet
|
||||
]);
|
||||
|
||||
// Wait for confirmation
|
||||
const latestBlockhash = await agent.connection.getLatestBlockhash();
|
||||
await agent.connection.confirmTransaction({
|
||||
signature,
|
||||
blockhash: latestBlockhash.blockhash,
|
||||
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
|
||||
});
|
||||
const signature = await registerDomain(agent, name, spaceKB);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { request_faucet_funds } from "../tools";
|
||||
|
||||
const requestFundsAction: Action = {
|
||||
name: "solana_request_funds",
|
||||
@@ -27,7 +28,7 @@ const requestFundsAction: Action = {
|
||||
],
|
||||
schema: z.object({}), // No input parameters required
|
||||
handler: async (agent: SolanaAgentKit, _input: Record<string, any>) => {
|
||||
await agent.requestFaucetFunds();
|
||||
await request_faucet_funds(agent);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { TldParser } from "@onsol/tldparser";
|
||||
import { resolveAllDomains } from "../tools";
|
||||
|
||||
const resolveDomainAction: Action = {
|
||||
name: "solana_resolve_domain",
|
||||
@@ -33,20 +34,10 @@ const resolveDomainAction: Action = {
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
try {
|
||||
const domain = input.domain as string;
|
||||
const tld = await new TldParser(agent.connection).getOwnerFromDomainTld(
|
||||
domain
|
||||
);
|
||||
|
||||
if (!tld) {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Domain not found"
|
||||
};
|
||||
}
|
||||
|
||||
const tld = await resolveAllDomains(agent, domain);
|
||||
return {
|
||||
status: "success",
|
||||
owner: tld.toBase58(),
|
||||
owner: tld,
|
||||
message: `Successfully resolved domain ${domain}`
|
||||
};
|
||||
} catch (error: any) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { resolve } from "@bonfida/spl-name-service";
|
||||
import { resolveSolDomain } from "../tools";
|
||||
|
||||
const resolveSolDomainAction: Action = {
|
||||
name: "solana_resolve_sol_domain",
|
||||
@@ -38,24 +39,12 @@ const resolveSolDomainAction: Action = {
|
||||
try {
|
||||
const domain = input.domain as string;
|
||||
|
||||
if (!domain || typeof domain !== "string") {
|
||||
return {
|
||||
status: "error",
|
||||
message: "Invalid domain. Expected a non-empty string."
|
||||
};
|
||||
}
|
||||
|
||||
// Remove .sol suffix if present for consistent handling
|
||||
const cleanDomain = domain.toLowerCase().endsWith(".sol")
|
||||
? domain.slice(0, -4)
|
||||
: domain;
|
||||
|
||||
const ownerAddress = await resolve(agent.connection, cleanDomain);
|
||||
const res = await resolveSolDomain(agent,domain)
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
owner: ownerAddress.toBase58(),
|
||||
message: `Successfully resolved ${cleanDomain}.sol`
|
||||
owner: res.toString(),
|
||||
message: `Successfully resolved ${res}`
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { VersionedTransaction } from "@solana/web3.js";
|
||||
import { stakeWithJup, trade } from "../tools";
|
||||
|
||||
const stakeWithJupAction: Action = {
|
||||
name: "solana_stake_with_jup",
|
||||
@@ -38,55 +39,10 @@ const stakeWithJupAction: Action = {
|
||||
try {
|
||||
const amount = input.amount as number;
|
||||
|
||||
// Get staking transaction from Jupiter
|
||||
const res = await fetch(
|
||||
`https://worker.jup.ag/blinks/swap/So11111111111111111111111111111111111111112/jupSoLaHXQiZZTSfEWMTRRgpnyFm8f6sZdosWBjx93v/${amount}`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
account: agent.wallet.publicKey.toBase58(),
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
if (!res.ok) {
|
||||
return {
|
||||
status: "error",
|
||||
message: `Failed to get staking transaction: ${res.statusText}`
|
||||
};
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
// Deserialize and prepare transaction
|
||||
const txn = VersionedTransaction.deserialize(
|
||||
Buffer.from(data.transaction, "base64")
|
||||
);
|
||||
|
||||
const { blockhash } = await agent.connection.getLatestBlockhash();
|
||||
txn.message.recentBlockhash = blockhash;
|
||||
|
||||
// Sign and send transaction
|
||||
txn.sign([agent.wallet]);
|
||||
const signature = await agent.connection.sendTransaction(txn, {
|
||||
preflightCommitment: "confirmed",
|
||||
maxRetries: 3,
|
||||
});
|
||||
|
||||
// Confirm transaction
|
||||
const latestBlockhash = await agent.connection.getLatestBlockhash();
|
||||
await agent.connection.confirmTransaction({
|
||||
signature,
|
||||
blockhash: latestBlockhash.blockhash,
|
||||
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
|
||||
});
|
||||
|
||||
const res = await stakeWithJup(agent,amount)
|
||||
return {
|
||||
status: "success",
|
||||
signature,
|
||||
res,
|
||||
message: `Successfully staked ${amount} SOL for jupSOL`
|
||||
};
|
||||
} catch (error: any) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { PublicKey } from "@solana/web3.js";
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { trade } from "../tools";
|
||||
|
||||
const tradeAction: Action = {
|
||||
name: "solana_trade",
|
||||
@@ -58,7 +59,7 @@ const tradeAction: Action = {
|
||||
slippageBps: z.number().min(0).max(10000).optional()
|
||||
}),
|
||||
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
||||
const tx = await agent.trade(
|
||||
const tx = await trade(agent,
|
||||
new PublicKey(input.outputMint),
|
||||
input.inputAmount,
|
||||
input.inputMint
|
||||
|
||||
@@ -2,6 +2,7 @@ import { PublicKey } from "@solana/web3.js";
|
||||
import { Action } from "../types/action";
|
||||
import { SolanaAgentKit } from "../agent";
|
||||
import { z } from "zod";
|
||||
import { transfer } from "../tools";
|
||||
|
||||
const transferAction: Action = {
|
||||
name: "solana_transfer",
|
||||
@@ -59,7 +60,7 @@ const transferAction: Action = {
|
||||
const recipient = new PublicKey(input.to);
|
||||
const mintAddress = input.mint ? new PublicKey(input.mint) : undefined;
|
||||
|
||||
const tx = await agent.transfer(recipient, input.amount, mintAddress);
|
||||
const tx = await transfer(agent,recipient, input.amount, mintAddress);
|
||||
|
||||
return {
|
||||
status: "success",
|
||||
|
||||
Reference in New Issue
Block a user