diff --git a/src/actions/balance.ts b/src/actions/balance.ts index 2a4d34d..36d9304 100644 --- a/src/actions/balance.ts +++ b/src/actions/balance.ts @@ -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) => { - 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", diff --git a/src/actions/createGibworkTask.ts b/src/actions/createGibworkTask.ts index 8ae28ce..419b7b5 100644 --- a/src/actions/createGibworkTask.ts +++ b/src/actions/createGibworkTask.ts @@ -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) { diff --git a/src/actions/createImage.ts b/src/actions/createImage.ts index 4d16b9a..722a683 100644 --- a/src/actions/createImage.ts +++ b/src/actions/createImage.ts @@ -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) { diff --git a/src/actions/createOpenbookMarket.ts b/src/actions/createOpenbookMarket.ts index 991ab97..0e923c0 100644 --- a/src/actions/createOpenbookMarket.ts +++ b/src/actions/createOpenbookMarket.ts @@ -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) { diff --git a/src/actions/createOrcaSingleSidedWhirlpool.ts b/src/actions/createOrcaSingleSidedWhirlpool.ts index 11c8289..f23389d 100644 --- a/src/actions/createOrcaSingleSidedWhirlpool.ts +++ b/src/actions/createOrcaSingleSidedWhirlpool.ts @@ -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, diff --git a/src/actions/deployCollection.ts b/src/actions/deployCollection.ts index 0127b5c..77efc10 100644 --- a/src/actions/deployCollection.ts +++ b/src/actions/deployCollection.ts @@ -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", diff --git a/src/actions/deployToken.ts b/src/actions/deployToken.ts index 046c120..2a1793d 100644 --- a/src/actions/deployToken.ts +++ b/src/actions/deployToken.ts @@ -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) => { - 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}` + }; + } } } diff --git a/src/actions/fetchPrice.ts b/src/actions/fetchPrice.ts index 40b9a1d..9512e14 100644 --- a/src/actions/fetchPrice.ts +++ b/src/actions/fetchPrice.ts @@ -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) => { 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", diff --git a/src/actions/getAllDomainsTLDs.ts b/src/actions/getAllDomainsTLDs.ts index fbda0b8..60c05d2 100644 --- a/src/actions/getAllDomainsTLDs.ts +++ b/src/actions/getAllDomainsTLDs.ts @@ -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) => { try { // Get all domain TLDs - const tlds = await agent.getAllDomainsTLDs(); + const tlds = await getAllDomainsTLDs(agent); return { status: "success", diff --git a/src/actions/getAllRegisteredAllDomains.ts b/src/actions/getAllRegisteredAllDomains.ts index 19a5542..96fe879 100644 --- a/src/actions/getAllRegisteredAllDomains.ts +++ b/src/actions/getAllRegisteredAllDomains.ts @@ -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" }; diff --git a/src/actions/getMainAllDomainsDomain.ts b/src/actions/getMainAllDomainsDomain.ts index 81f911d..4f301f9 100644 --- a/src/actions/getMainAllDomainsDomain.ts +++ b/src/actions/getMainAllDomainsDomain.ts @@ -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) => { 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) { diff --git a/src/actions/getOwnedAllDomains.ts b/src/actions/getOwnedAllDomains.ts index 7c41760..9cb279a 100644 --- a/src/actions/getOwnedAllDomains.ts +++ b/src/actions/getOwnedAllDomains.ts @@ -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", diff --git a/src/actions/getOwnedDomainsForTLD.ts b/src/actions/getOwnedDomainsForTLD.ts index 36924e4..3b2a06e 100644 --- a/src/actions/getOwnedDomainsForTLD.ts +++ b/src/actions/getOwnedDomainsForTLD.ts @@ -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", diff --git a/src/actions/getPrimaryDomain.ts b/src/actions/getPrimaryDomain.ts index 778fadb..f19b091 100644 --- a/src/actions/getPrimaryDomain.ts +++ b/src/actions/getPrimaryDomain.ts @@ -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 { diff --git a/src/actions/getTPS.ts b/src/actions/getTPS.ts index 8baadff..546da65 100644 --- a/src/actions/getTPS.ts +++ b/src/actions/getTPS.ts @@ -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) => { 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 { diff --git a/src/actions/getTokenData.ts b/src/actions/getTokenData.ts index 4b75cb9..8ac9721 100644 --- a/src/actions/getTokenData.ts +++ b/src/actions/getTokenData.ts @@ -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) => { 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: { diff --git a/src/actions/index.ts b/src/actions/index.ts index 1e15f58..d3b1679 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -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, diff --git a/src/actions/launchPumpfunToken.ts b/src/actions/launchPumpfunToken.ts index ea38076..00f0add 100644 --- a/src/actions/launchPumpfunToken.ts +++ b/src/actions/launchPumpfunToken.ts @@ -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) => { 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) { diff --git a/src/actions/lendAsset.ts b/src/actions/lendAsset.ts index 25e7258..b4b0885 100644 --- a/src/actions/lendAsset.ts +++ b/src/actions/lendAsset.ts @@ -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) { diff --git a/src/actions/mintNFT.ts b/src/actions/mintNFT.ts index 4e9e6ae..ef26ec4 100644 --- a/src/actions/mintNFT.ts +++ b/src/actions/mintNFT.ts @@ -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) => { - 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 { diff --git a/src/actions/pythFetchPrice.ts b/src/actions/pythFetchPrice.ts index acafeb0..1c1f9e0 100644 --- a/src/actions/pythFetchPrice.ts +++ b/src/actions/pythFetchPrice.ts @@ -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", diff --git a/src/actions/raydiumCreateAmmV4.ts b/src/actions/raydiumCreateAmmV4.ts index 6c4c357..afda966 100644 --- a/src/actions/raydiumCreateAmmV4.ts +++ b/src/actions/raydiumCreateAmmV4.ts @@ -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", diff --git a/src/actions/raydiumCreateCpmm.ts b/src/actions/raydiumCreateCpmm.ts index faea973..0e6795c 100644 --- a/src/actions/raydiumCreateCpmm.ts +++ b/src/actions/raydiumCreateCpmm.ts @@ -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", diff --git a/src/actions/registerDomain.ts b/src/actions/registerDomain.ts index 02b92d3..50b398a 100644 --- a/src/actions/registerDomain.ts +++ b/src/actions/registerDomain.ts @@ -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", diff --git a/src/actions/requestFunds.ts b/src/actions/requestFunds.ts index 03159a7..49e4c2b 100644 --- a/src/actions/requestFunds.ts +++ b/src/actions/requestFunds.ts @@ -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) => { - await agent.requestFaucetFunds(); + await request_faucet_funds(agent); return { status: "success", diff --git a/src/actions/resolveDomain.ts b/src/actions/resolveDomain.ts index 049c3df..1d6307a 100644 --- a/src/actions/resolveDomain.ts +++ b/src/actions/resolveDomain.ts @@ -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) => { 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) { diff --git a/src/actions/resolveSolDomain.ts b/src/actions/resolveSolDomain.ts index 481acef..ce13fe3 100644 --- a/src/actions/resolveSolDomain.ts +++ b/src/actions/resolveSolDomain.ts @@ -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 { diff --git a/src/actions/stakeWithJup.ts b/src/actions/stakeWithJup.ts index 271f902..7110a72 100644 --- a/src/actions/stakeWithJup.ts +++ b/src/actions/stakeWithJup.ts @@ -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) { diff --git a/src/actions/trade.ts b/src/actions/trade.ts index 8a536b3..bb27f79 100644 --- a/src/actions/trade.ts +++ b/src/actions/trade.ts @@ -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) => { - const tx = await agent.trade( + const tx = await trade(agent, new PublicKey(input.outputMint), input.inputAmount, input.inputMint diff --git a/src/actions/transfer.ts b/src/actions/transfer.ts index 426a071..3769481 100644 --- a/src/actions/transfer.ts +++ b/src/actions/transfer.ts @@ -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",