I am unable to have proper swap transaction. i tried raydium & orca api both throwed poolInfo undefined.
can you please go through my code and let me know the reason. i just want to loop over my wallets and want to swap sol to kalki token.
I am new to this so please help
thanks
const BigNumber = require('bignumber.js');
const { Connection, PublicKey, Keypair } = require('@solana/web3.js');
const { getMint } = require('@solana/spl-token');
const { Jupiter, SwapMode } = require('@jup-ag/api');
require('dotenv').config();
console.log(Jupiter, SwapMode)
// --- Configuration ---
const RPC_URL = process.env.RPC_URL || 'https://api.mainnet-beta.solana.com';
const connection = new Connection(RPC_URL, 'confirmed');
const SOURCE_TOKEN_MINT = new PublicKey('So11111111111111111111111111111111111111112'); // Token A (e.g., SOL)
const TARGET_TOKEN_MINT = new PublicKey('8rKrd91nu6uRJa8hntaft5YDwmwkMhSGkTuRitRNdJKE'); // Replace with actual Kalki token mint address
// Load wallets from environment variables
const wallets = [
process.env.WALLET_PRIVATE_KEY1,
process.env.WALLET_PRIVATE_KEY2,
process.env.WALLET_PRIVATE_KEY3,
process.env.WALLET_PRIVATE_KEY4,
// Add more wallets here
].map((key) => Keypair.fromSecretKey(Uint8Array.from(JSON.parse(key))));
// --- Helper Function: Initialize Jupiter ---
async function initializeJupiter(connection) {
const jupiter = await Jupiter.load({
connection,
cluster: 'mainnet-beta', // Use 'mainnet-beta' or 'devnet'
});
return jupiter;
}
// --- Helper Function: Check Wallet Balance ---
async function checkWalletBalance(wallet) {
const balance = await connection.getBalance(wallet.publicKey);
console.log(`Wallet ${wallet.publicKey.toBase58()} balance: ${(balance / 10 ** 9).toFixed(5)} SOL`);
return balance;
}
// --- Helper Function: Fetch Token Decimals ---
const tokenDecimals = async (mintAddress) => {
const mintInfo = await getMint(connection, new PublicKey(mintAddress));
return mintInfo.decimals;
};
// --- Execute the Swap using Jupiter ---
async function executeSwap(wallet, amountInLamports, jupiter) {
try {
const swapAmount = new BigNumber(amountInLamports).toString(); // Amount in lamports
console.log('Executing swap with amount (in SOL):', swapAmount / 10 ** 9);
// Find the best route for the swap
const routes = await jupiter.computeRoutes({
inputMint: SOURCE_TOKEN_MINT,
outputMint: TARGET_TOKEN_MINT,
amount: amountInLamports, // Amount in lamports
slippage: 1, // Slippage tolerance in percentage
});
if (!routes.routesInfos || routes.routesInfos.length === 0) {
throw new Error('No routes found for the swap.');
}
const bestRoute = routes.routesInfos[0]; // Take the best route
console.log('Best route:', bestRoute);
// Execute the swap
const { swapTransaction } = await jupiter.executeSwap({
routeInfo: bestRoute,
swapMode: SwapMode.ExactIn, // Swap exact input amount
});
if (!swapTransaction) {
throw new Error('Failed to create a swap transaction.');
}
// Sign and send the transaction
const latestBlockhash = await connection.getLatestBlockhash();
swapTransaction.recentBlockhash = latestBlockhash.blockhash;
swapTransaction.feePayer = wallet.publicKey;
swapTransaction.sign(wallet);
const signature = await connection.sendRawTransaction(swapTransaction.serialize());
await connection.confirmTransaction(signature, 'confirmed');
console.log(`Swap executed successfully! View on Explorer: https://explorer.solana.com/tx/${signature}?cluster=mainnet`);
} catch (error) {
console.error('Error during swap execution:', error.message);
throw error;
}
}
// --- Main Function ---
(async () => {
try {
console.log('Connecting to Solana...');
const version = await connection.getVersion();
console.log('Connected to Solana cluster:', version);
const jupiter = await initializeJupiter(connection);
for (const [index, wallet] of wallets.entries()) {
console.log(`n--- Processing Wallet ${index + 1} ---`);
const balance = await checkWalletBalance(wallet);
// Check if balance is sufficient
const lamports = balance; // Balance in lamports
const halfBalance = lamports / 2; // Half of wallet balance
const transactionFee = 0.000005 * 10 ** 9; // Fee in lamports
if (lamports < transactionFee) {
console.error('Insufficient SOL balance for transaction fees. Skipping wallet.');
continue;
}
const availableForSwap = halfBalance - transactionFee; // Deduct transaction fees
if (availableForSwap <= 0) {
console.error('Not enough SOL to perform the swap after deducting fees. Skipping wallet.');
continue;
}
console.log(`Swapping half of the wallet balance: ${availableForSwap / 10 ** 9} SOL`);
const swapAmount = new BigNumber(availableForSwap); // Amount to swap in lamports
await executeSwap(wallet, swapAmount, jupiter); // Execute swap
}
console.log('nAll transactions completed!');
} catch (error) {
console.error('Error during token swap process:', error.message);
}
})();
errors:
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
undefined { ExactIn: 'ExactIn', ExactOut: 'ExactOut' }
Connecting to Solana...
Connected to Solana cluster: { 'feature-set': 3039680930, 'solana-core': '2.1.8' }
Error during token swap process: Cannot read properties of undefined (reading 'load')
i tried with raydium too.
const {
Connection,
PublicKey,
Keypair,
Transaction,
SystemProgram,
sendAndConfirmTransaction,
} = require("@solana/web3.js");
const {
Amm,
LIQUIDITY_POOLS,
createAssociatedTokenAccountInstruction,
} = require("@raydium-io/raydium-sdk");
const { TOKEN_PROGRAM_ID, getOrCreateAssociatedTokenAccount, createSyncNativeInstruction } = require("@solana/spl-token");
const bs58 = require("bs58");
require("dotenv").config();
// --- Configuration ---
const RPC_URL = process.env.RPC_URL || "https://api.mainnet-beta.solana.com";
const connection = new Connection(RPC_URL, "confirmed");
// Replace with your private key (use environment variables for security)
const WALLET_PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY1;
const userWallet = Keypair.fromSecretKey(Uint8Array.from(JSON.parse(WALLET_PRIVATE_KEY)));
// Replace with the Raydium pool ID for SOL-to-KALKI swaps
const RAYDIUM_POOL_ID = ""; // Example Pool ID
// --- Fetch Pool Details ---
async function getPoolDetails() {
try {
const response = await connection.getParsedAccountInfo(new PublicKey(RAYDIUM_POOL_ID));
const poolInfo = response.value.data;
if (!poolInfo) {
throw new Error("Failed to fetch pool details. Pool data not found.");
}
console.log("Fetched Pool Info:", poolInfo);
return poolInfo;
} catch (error) {
console.error("Error fetching pool details:", error.message);
throw error;
}
}
async function wrapSol(amount) {
try {
// Check wallet balance
const balance = await connection.getBalance(userWallet.publicKey);
console.log("Wallet Balance:", balance / 10 ** 9, "SOL");
if (balance < amount + 0.000005 * 10 ** 9) {
throw new Error("Insufficient SOL balance for wrapping and transaction fees.");
}
// WSOL mint address
const wsolMintAddress = new PublicKey("So11111111111111111111111111111111111111112");
// Create or get associated WSOL account
const wsolAccount = await getOrCreateAssociatedTokenAccount(
connection,
userWallet,
wsolMintAddress,
userWallet.publicKey
);
console.log("WSOL Account Address:", wsolAccount.address.toBase58());
// Transfer SOL to WSOL account
const transaction = new Transaction().add(
SystemProgram.transfer({
fromPubkey: userWallet.publicKey,
toPubkey: wsolAccount.address,
lamports: amount,
}),
createSyncNativeInstruction(wsolAccount.address)
);
const signature = await sendAndConfirmTransaction(connection, transaction, [userWallet]);
console.log(`Wrapped ${amount / 10 ** 9} SOL to WSOL. Transaction: https://explorer.solana.com/tx/${signature}?cluster=mainnet`);
return wsolAccount.address;
} catch (error) {
console.error("Error wrapping SOL:", error.message);
throw error;
}
}
// --- Perform Token Swap ---
async function executeSwap(poolData, solAmount) {
try {
console.log("Executing swap with", solAmount, "lamports...");
// Fetch the Kalki token mint address from the pool data
const destinationVault = new PublicKey(poolData[0].mintB.address);
// Create or fetch the associated token account for Kalki tokens
const destinationTokenAccount = await getOrCreateAssociatedTokenAccount(
connection,
userWallet,
destinationVault,
userWallet.publicKey
);
console.log("Destination Token Account:", destinationTokenAccount.address.toBase58());
// Construct the swap instruction
const swapInstruction = AmmV3.makeSwapInstruction({
poolInfo: poolData,
userWallet: userWallet.publicKey,
inputTokenAccount: userWallet.publicKey, // For SOL, inputTokenAccount is the wallet
outputTokenAccount: destinationTokenAccount.address,
amountIn: solAmount, // Amount of SOL to swap (in lamports)
minAmountOut: 1, // Minimum acceptable Kalki tokens (adjust for slippage)
});
const transaction = new Transaction().add(swapInstruction);
// Sign and send the transaction
const signature = await connection.sendTransaction(transaction, [userWallet]);
console.log(`Swap executed! View on Explorer: https://explorer.solana.com/tx/${signature}?cluster=mainnet`);
} catch (error) {
console.error("Error during swap execution:", error.message);
throw error;
}
}
// --- Main Function ---
(async () => {
try {
console.log("Connecting to Solana...");
const version = await connection.getVersion();
console.log("Connected to Solana cluster:", version);
console.log("Fetching pool details...");
const poolData = await getPoolDetails();
console.log("Wrapping SOL...");
const solAmount = 0.001 * 10 ** 9; // 0.002 SOL in lamports
const kalkiAmount = solAmount / poolData[0].price; // SOL to Kalki conversion
console.log(`You will receive approximately ${kalkiAmount} Kalki tokens.`);
const wsolAccount = await wrapSol(solAmount);
console.log("Swapping SOL for Kalki tokens...");
await executeSwap(poolData, wsolAccount, solAmount);
console.log("Swap completed!");
} catch (error) {
console.error("Error during token swap process:", error.message);
}
})();
error :
bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)
Connecting to Solana...
Connected to Solana cluster: { 'feature-set': 3039680930, 'solana-core': '2.1.8' }
Fetching pool details...
Fetched Pool Info: <Buffer f7 ed e3 f5 d7 c3 de 46 b3 21 3f ba 8b f9 c8 7f a9 1e 47 81 96 28 c3 83 e0 0b ea 7e 98 c7 a0 3e 03 ba 10 69 cf c3 f6 f3 88 f0 27 32 a4 b0 59 75 61 71 ... 587 more bytes>
Wrapping SOL...
You will receive approximately NaN Kalki tokens.
Wallet Balance: 0.007096975 SOL
WSOL Account Address: 6CajUsnhEEvr2YiBaUyDjPUXYJfTTxcPEancJNucPv4Z
Error wrapping SOL: Signature QgyMVa5nW4UmaLKBKh62sfW1EEdv2CEcCzJY1ikQqzVU4V28RGPCC6U8z8UUUAPUoM8vzLjX5jXwJDMHRDrrMEB has expired: block height exceeded.
Error during token swap process: Signature QgyMVa5nW4UmaLKBKh62sfW1EEdv2CEcCzJY1ikQqzVU4V28RGPCC6U8z8UUUAPUoM8vzLjX5jXwJDMHRDrrMEB has expired: block height exceeded.