mirror of
https://github.com/d0zingcat/solana-agent-kit.git
synced 2026-05-19 07:36:46 +00:00
203 lines
6.0 KiB
TypeScript
203 lines
6.0 KiB
TypeScript
import { Action } from "../types/action";
|
|
import { SolanaAgentKit } from "../agent";
|
|
import { z } from "zod";
|
|
import { VersionedTransaction, Keypair } from "@solana/web3.js";
|
|
|
|
const launchPumpfunTokenAction: Action = {
|
|
name: "solana_launch_pumpfun_token",
|
|
similes: [
|
|
"create pumpfun token",
|
|
"launch token on pumpfun",
|
|
"deploy pumpfun token",
|
|
"create meme token",
|
|
"launch memecoin",
|
|
"create pump token"
|
|
],
|
|
description: "Launch a new token on Pump.fun with customizable metadata and initial liquidity",
|
|
examples: [
|
|
[
|
|
{
|
|
input: {
|
|
tokenName: "Sample Token",
|
|
tokenTicker: "SMPL",
|
|
description: "A sample token for demonstration",
|
|
imageUrl: "https://example.com/token.png",
|
|
twitter: "@sampletoken",
|
|
telegram: "t.me/sampletoken",
|
|
website: "https://sampletoken.com",
|
|
initialLiquiditySOL: 0.1,
|
|
slippageBps: 10,
|
|
priorityFee: 0.0001
|
|
},
|
|
output: {
|
|
status: "success",
|
|
signature: "2ZE7Rz...",
|
|
mint: "7nxQB...",
|
|
metadataUri: "https://arweave.net/...",
|
|
message: "Successfully launched token on Pump.fun"
|
|
},
|
|
explanation: "Launch a new token with custom metadata and 0.1 SOL initial liquidity"
|
|
}
|
|
]
|
|
],
|
|
schema: z.object({
|
|
tokenName: z.string()
|
|
.min(1)
|
|
.max(32)
|
|
.describe("Name of the token"),
|
|
tokenTicker: z.string()
|
|
.min(2)
|
|
.max(10)
|
|
.describe("Ticker symbol of the token"),
|
|
description: z.string()
|
|
.min(1)
|
|
.max(1000)
|
|
.describe("Description of the token"),
|
|
imageUrl: z.string()
|
|
.url()
|
|
.describe("URL of the token image"),
|
|
twitter: z.string()
|
|
.optional()
|
|
.describe("Twitter handle (optional)"),
|
|
telegram: z.string()
|
|
.optional()
|
|
.describe("Telegram group link (optional)"),
|
|
website: z.string()
|
|
.url()
|
|
.optional()
|
|
.describe("Website URL (optional)"),
|
|
initialLiquiditySOL: z.number()
|
|
.min(0.0001)
|
|
.default(0.0001)
|
|
.describe("Initial liquidity in SOL"),
|
|
slippageBps: z.number()
|
|
.min(1)
|
|
.max(1000)
|
|
.default(5)
|
|
.describe("Slippage tolerance in basis points"),
|
|
priorityFee: z.number()
|
|
.min(0.00001)
|
|
.default(0.00005)
|
|
.describe("Priority fee in SOL")
|
|
}),
|
|
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
|
|
try {
|
|
const 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}`);
|
|
}
|
|
|
|
return {
|
|
status: "success",
|
|
signature,
|
|
mint: mintKeypair.publicKey.toBase58(),
|
|
metadataUri: metadataResult.metadataUri,
|
|
message: "Successfully launched token on Pump.fun"
|
|
};
|
|
} catch (error: any) {
|
|
return {
|
|
status: "error",
|
|
message: `Failed to launch token: ${error.message}`
|
|
};
|
|
}
|
|
}
|
|
};
|
|
|
|
export default launchPumpfunTokenAction;
|