Skip to main content
Glama
monostate

100ms Raydium Sniper MCP

by monostate
ata-manager.ts5.8 kB
import { Connection, PublicKey, Keypair, Transaction, ComputeBudgetProgram } from '@solana/web3.js'; import { getAssociatedTokenAddress, createAssociatedTokenAccountInstruction } from '@solana/spl-token'; async function sleep(ms: number) { return new Promise(resolve => setTimeout(resolve, ms)); } async function waitForConfirmation(connection: Connection, signature: string, maxRetries = 5) { console.error('[ATA] Waiting for confirmation...'); // Wait for transaction to propagate await sleep(2000); // Try up to maxRetries times with 2 second intervals for (let i = 0; i < maxRetries; i++) { try { const response = await connection.getSignatureStatus(signature); const status = response?.value; console.error(`[ATA] Status check ${i + 1}/${maxRetries}:`, status?.confirmationStatus || 'unknown'); if (status?.err) { throw new Error(`Transaction failed: ${JSON.stringify(status.err)}`); } if (status?.confirmationStatus === 'processed' || status?.confirmationStatus === 'confirmed' || status?.confirmationStatus === 'finalized') { console.error('[ATA] Transaction confirmed!'); return true; } } catch (error: any) { console.error(`[ATA] Error checking status: ${error.message}`); } if (i < maxRetries - 1) { // Don't sleep on the last iteration await sleep(2000); } } throw new Error('Transaction confirmation timeout'); } export class ATAManager { constructor(private readonly connection: Connection) {} async getOrCreateATA( wallet: Keypair, mint: PublicKey, options = { skipBalanceCheck: false } ): Promise<{ address: PublicKey; created: boolean }> { try { // Get ATA address const ataAddress = await getAssociatedTokenAddress( mint, wallet.publicKey ); console.error(`[ATA] Address would be at: ${ataAddress.toString()}`); // Check SOL balance first to avoid unnecessary errors const solBalance = await this.connection.getBalance(wallet.publicKey); console.error(`[ATA] Wallet SOL balance: ${solBalance / 1e9} SOL`); if (solBalance < 5000000) { // 0.005 SOL minimum console.error('[ATA] WARNING: Wallet has insufficient SOL balance for ATA creation'); return { address: ataAddress, created: false }; } // Check if account already exists const accountInfo = await this.connection.getAccountInfo(ataAddress); if (accountInfo) { console.error('[ATA] ATA already exists'); // Only check balance if account exists and skipBalanceCheck is false if (!options.skipBalanceCheck) { try { const balance = await this.connection.getTokenAccountBalance(ataAddress); console.error(`[ATA] Token balance: ${balance.value.uiAmount}`); } catch (error) { console.error('[ATA] Failed to get token balance:', error); } } return { address: ataAddress, created: false }; } console.error('[ATA] Creating new ATA...'); // Create transaction const transaction = new Transaction(); // Add priority fee instruction (0.01 SOL) transaction.add( ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 10_000_000 }) ); // Add ATA instruction transaction.add( createAssociatedTokenAccountInstruction( wallet.publicKey, // payer ataAddress, // ata wallet.publicKey, // owner mint // mint ) ); // Get recent blockhash const { blockhash } = await this.connection.getLatestBlockhash('processed'); transaction.recentBlockhash = blockhash; transaction.feePayer = wallet.publicKey; // Sign and send transaction console.error('[ATA] Sending transaction...'); transaction.sign(wallet); try { const signature = await this.connection.sendRawTransaction(transaction.serialize(), { skipPreflight: false, preflightCommitment: 'processed', maxRetries: 3 }); console.error(`[ATA] Transaction sent: ${signature}`); // Wait for confirmation await waitForConfirmation(this.connection, signature); console.error('[ATA] ATA creation confirmed'); // Check balance after creation if skipBalanceCheck is false if (!options.skipBalanceCheck) { try { const balance = await this.connection.getTokenAccountBalance(ataAddress); console.error(`[ATA] New token balance: ${balance.value.uiAmount}`); } catch (error) { console.error('[ATA] Failed to get token balance:', error); } } return { address: ataAddress, created: true }; } catch (error: any) { // Check for insufficient funds error if (error.message && ( error.message.includes('Attempt to debit an account but found no record of a prior credit') || error.message.includes('insufficient funds') )) { console.error('[ATA] Transaction failed due to insufficient funds'); console.error('[ATA] Make sure the wallet has SOL to pay for transaction fees'); // Still return the ATA address even though creation failed return { address: ataAddress, created: false }; } // Rethrow other errors throw error; } } catch (error: any) { console.error('[ATA] Failed to create ATA:', error); throw error; } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/monostate/100ms-SPL-Token-Sniper-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server