This commit is contained in:
Arihant Bansal
2024-12-11 02:12:15 +05:30
26 changed files with 1070 additions and 165 deletions

39
src/tools/create_image.ts Normal file
View File

@@ -0,0 +1,39 @@
import { SolanaAgentKit } from "../index";
import OpenAI from "openai";
/**
* Generate an image using OpenAI's DALL-E
* @param agent SolanaAgentKit instance
* @param prompt Text description of the image to generate
* @param size Image size ('256x256', '512x512', or '1024x1024') (default: '1024x1024')
* @param n Number of images to generate (default: 1)
* @returns Object containing the generated image URLs
*/
export async function create_image(
agent: SolanaAgentKit,
prompt: string,
size: "256x256" | "512x512" | "1024x1024" = "1024x1024",
n: number = 1,
) {
try {
if (!agent.openai_api_key) {
throw new Error("OpenAI API key not found in agent configuration");
}
const openai = new OpenAI({
apiKey: agent.openai_api_key,
});
const response = await openai.images.generate({
prompt,
n,
size,
});
return {
images: response.data.map((img: any) => img.url),
};
} catch (error: any) {
throw new Error(`Image generation failed: ${error.message}`);
}
}

View File

@@ -6,5 +6,6 @@ export * from "./mint_nft";
export * from "./transfer";
export * from "./trade";
export * from "./register_domain";
export * from "./launch_pumpfun_token";
export * from "./lend";
export * from "./get_tps";

View File

@@ -0,0 +1,192 @@
// src/tools/launch_pumpfun_token.ts
import { VersionedTransaction, Keypair } from "@solana/web3.js";
import { PumpFunTokenOptions, SolanaAgentKit } from "../index";
async function uploadMetadata(
tokenName: string,
tokenTicker: string,
description: string,
imageUrl: string,
options?: PumpFunTokenOptions
): Promise<any> {
// Create metadata object
const formData = new URLSearchParams();
formData.append('name', tokenName);
formData.append("symbol", tokenTicker);
formData.append("description", description);
formData.append("showName", "true");
if (options?.twitter) formData.append('twitter', options.twitter);
if (options?.telegram) formData.append("telegram", options.telegram);
if (options?.website) formData.append("website", options.website);
const imageResponse = await fetch(imageUrl);
const imageBlob = await imageResponse.blob();
const files = {
file: new File([imageBlob], "token_image.png", { type: "image/png" }),
};
// Create form data with both metadata and file
const finalFormData = new FormData();
// Add all metadata fields
for (const [key, value] of formData.entries()) {
finalFormData.append(key, value);
}
// Add file if exists
if (files?.file) {
finalFormData.append('file', files.file);
}
console.log("Final form data:", finalFormData);
const metadataResponse = await fetch("https://pump.fun/api/ipfs", {
method: "POST",
body: finalFormData
});
if (!metadataResponse.ok) {
console.log("Metadata response:", await metadataResponse.json());
throw new Error(`Metadata upload failed: ${metadataResponse.statusText}`);
}
return await metadataResponse.json();
}
async function createTokenTransaction(
agent: SolanaAgentKit,
mintKeypair: Keypair,
metadataResponse: any,
options?: PumpFunTokenOptions
) {
const payload = {
publicKey: agent.wallet_address.toBase58(),
action: "create",
tokenMetadata: {
name: metadataResponse.metadata.name,
symbol: metadataResponse.metadata.symbol,
uri: metadataResponse.metadataUri,
},
mint: mintKeypair.publicKey.toBase58(),
denominatedInSol: "true", // API expects string "true"
amount: options?.initialLiquiditySOL || 0.0001,
slippage: options?.slippageBps || 5,
priorityFee: options?.priorityFee || 0.00005,
pool: "pump",
};
const response = await fetch("https://pumpportal.fun/api/trade-local", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload)
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Transaction creation failed: ${response.status} - ${errorText}`);
}
return response;
}
async function signAndSendTransaction(
kit: SolanaAgentKit,
tx: VersionedTransaction,
mintKeypair: Keypair
) {
try {
// Get the latest blockhash
const { blockhash, lastValidBlockHeight } = await kit.connection.getLatestBlockhash();
// Update transaction with latest blockhash
tx.message.recentBlockhash = blockhash;
// Sign the transaction
tx.sign([mintKeypair, kit.wallet]);
// Send and confirm transaction with options
const signature = await kit.connection.sendTransaction(tx, {
skipPreflight: false,
preflightCommitment: 'confirmed',
maxRetries: 5
});
// Wait for confirmation
const confirmation = await kit.connection.confirmTransaction({
signature,
blockhash,
lastValidBlockHeight
});
if (confirmation.value.err) {
throw new Error(`Transaction failed: ${confirmation.value.err}`);
}
return signature;
} catch (error) {
console.error('Transaction send error:', error);
if (error instanceof Error && 'logs' in error) {
console.error('Transaction logs:', error.logs);
}
throw error;
}
}
/**
* Launch a token on Pump.fun
* @param agent - SolanaAgentKit instance
* @param tokenName - Name of the token
* @param tokenTicker - Ticker of the token
* @param description - Description of the token
* @param imageUrl - URL of the token image
* @param options - Optional token options (twitter, telegram, website, initialLiquiditySOL, slippageBps, priorityFee)
*/
export async function launchPumpFunToken(
agent: SolanaAgentKit,
tokenName: string,
tokenTicker: string,
description: string,
imageUrl: string,
options?: PumpFunTokenOptions
) {
try {
// TBD : Remove clgs after approval
console.log("Starting token launch process...");
// Generate mint keypair
const mintKeypair = Keypair.generate();
console.log("Mint public key:", mintKeypair.publicKey.toBase58());
// Upload metadata
console.log("Uploading metadata to IPFS...");
const metadataResponse = await uploadMetadata(tokenName, tokenTicker, description, imageUrl, options);
console.log("Metadata response:", metadataResponse);
// Create token transaction
console.log("Creating token transaction...");
const response = await createTokenTransaction(agent, mintKeypair, metadataResponse, options);
const transactionData = await response.arrayBuffer();
const tx = VersionedTransaction.deserialize(new Uint8Array(transactionData));
// Send transaction with proper blockhash handling
console.log("Sending transaction...");
const signature = await signAndSendTransaction(agent, tx, mintKeypair);
console.log("Token launch successful!");
return {
signature,
mint: mintKeypair.publicKey.toBase58(),
metadataUri: metadataResponse.metadataUri,
};
} catch (error) {
console.error("Error in launchpumpfuntoken:", error);
if (error instanceof Error && 'logs' in error) {
console.error('Transaction logs:', (error as any).logs);
}
throw error;
}
}

View File

@@ -1,4 +1,4 @@
import { VersionedTransaction, PublicKey } from "@solana/web3.js";
import { VersionedTransaction, PublicKey, LAMPORTS_PER_SOL } from "@solana/web3.js";
import { SolanaAgentKit } from "../index";
import { TOKENS, DEFAULT_OPTIONS, JUP_API } from "../constants";
@@ -20,12 +20,13 @@ export async function trade(
): Promise<string> {
try {
// Get quote for the swap
console.log(inputMint.toString(), outputMint.toString(), inputAmount, slippageBps);
const quoteResponse = await (
await fetch(
`${JUP_API}/quote?` +
`inputMint=${inputMint.toString()}` +
`&outputMint=${outputMint.toString()}` +
`&amount=${inputAmount}` +
`&amount=${inputAmount * LAMPORTS_PER_SOL}` +
`&slippageBps=${slippageBps}` +
`&onlyDirectRoutes=true` +
`&maxAccounts=20`,
@@ -48,11 +49,10 @@ export async function trade(
}),
})
).json();
// Deserialize transaction
const swapTransactionBuf = Buffer.from(swapTransaction, "base64");
const transaction = VersionedTransaction.deserialize(swapTransactionBuf);
const transaction = VersionedTransaction.deserialize(swapTransactionBuf);
// Sign and send transaction
transaction.sign([agent.wallet]);
const signature = await agent.connection.sendTransaction(transaction);