0

I am developing a payment gateway on Solana and need to swap tokens programmatically using Node.js. Currently, I am testing SOL to USDC swaps with the Jupiter API.

Everything works until generating the transaction signature. However, after that, the swap does not execute—tokens remain the same. I don’t see any errors, but the transaction does not go through.

const {
 Connection,
 Keypair,
 PublicKey,
 clusterApiUrl,
 LAMPORTS_PER_SOL,
 VersionedTransaction,
} = require("@solana/web3.js");
const {
 getAssociatedTokenAddressSync,
 TOKEN_PROGRAM_ID,
 ASSOCIATED_TOKEN_PROGRAM_ID,
} = require("@solana/spl-token");
const fetch = require("node-fetch"); // Ensure you have node-fetch installed
const connection = new Connection(clusterApiUrl("mainnet-beta"), "confirmed");
const swapTokens = async (req, res) => {
 try {
 // **STEP 1: Get Best Quote**
 const inputMint = "So11111111111111111111111111111111111111112"; // SOL
 const outputMint = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; // USDC
 const userPublicKey = new PublicKey("YOUR_WALLET_PUBLIC_KEY"); // Replace with actual user public key
 const amount = 0.000010; // Amount in SOL
 const solAmount = Math.floor(amount * 1e9); // Convert SOL to lamports
 const quoteResponse = await (
 await fetch(
 `https://api.jup.ag/swap/v1/quote?inputMint=${inputMint}&outputMint=${outputMint}&amount=${solAmount}&slippageBps=50&restrictIntermediateTokens=true&swapMode=ExactIn`
 )
 ).json();
 console.log("Quote Response:", JSON.stringify(quoteResponse, null, 2));
 // **STEP 2: Execute Swap**
 const swapResponse = await (
 await fetch("https://api.jup.ag/swap/v1/swap", {
 method: "POST",
 headers: {
 "Content-Type": "application/json",
 },
 body: JSON.stringify({
 quoteResponse,
 userPublicKey: userPublicKey.toBase58(),
 }),
 })
 ).json();
 console.log("Swap Response:", swapResponse);
 // **STEP 3: Sign and Send Transaction**
 const transactionBase64 = swapResponse.swapTransaction;
 const transaction = VersionedTransaction.deserialize(Buffer.from(transactionBase64, "base64"));
 
 console.log("Deserialized Transaction:", transaction);
 const mainWallet = Keypair.fromSecretKey(Uint8Array.from(YOUR_SECRET_KEY)); // Replace with your private key
 transaction.sign([mainWallet]);
 const transactionBinary = transaction.serialize();
 console.log("Serialized Transaction:", transactionBinary);
 const signature = await connection.sendRawTransaction(transactionBinary, {
 maxRetries: 2,
 skipPreflight: true,
 });
 console.log("Transaction Signature:", signature);
 const confirmation = await connection.confirmTransaction({ signature }, "finalized");
 
 console.log("Transaction Confirmation:", confirmation);
 if (confirmation.value.err) {
 console.log(`Transaction failed: ${JSON.stringify(confirmation.value.err)}\nhttps://solscan.io/tx/${signature}/`);
 } else {
 console.log(`Transaction successful: https://solscan.io/tx/${signature}/`);
 }
 res.status(200).json({ message: "Swap executed successfully", signature });
 } catch (error) {
 console.error("Swap Error:", error);
 res.status(500).json({ message: "Swap failed: " + error.message });
 }
};
asked Feb 2, 2025 at 3:04

1 Answer 1

0

Pass quoteResponse.quote instead of full quoteResponse and Enable preflight to ensure transaction executes properly

const swapTokens = async (req, res) => {
 try {
 const inputMint = "So11111111111111111111111111111111111111112"; // SOL
 const outputMint = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; // USDC
 const userPublicKey = new PublicKey("YOUR_WALLET_PUBLIC_KEY"); // Replace
 const amount = 0.000010;
 const solAmount = Math.floor(amount * 1e9);
 const quoteResponse = await (
 await fetch(
 `https://api.jup.ag/swap/v1/quote?inputMint=${inputMint}&outputMint=${outputMint}&amount=${solAmount}&slippageBps=50`
 )
 ).json();
 console.log("Quote Response:", quoteResponse);
 // **Extract only `quoteResponse.quote`**
 const swapResponse = await (
 await fetch("https://api.jup.ag/swap/v1/swap", {
 method: "POST",
 headers: { "Content-Type": "application/json" },
 body: JSON.stringify({
 quoteResponse: quoteResponse.quote, // Only pass `quote`
 userPublicKey: userPublicKey.toBase58(),
 }),
 })
 ).json();
 console.log("Swap Response:", swapResponse);
 // Deserialize transaction
 const transactionBase64 = swapResponse.swapTransaction;
 const transaction = VersionedTransaction.deserialize(Buffer.from(transactionBase64, "base64"));
 console.log("Deserialized Transaction:", transaction);
 // Sign with the main wallet
 const mainWallet = Keypair.fromSecretKey(Uint8Array.from(YOUR_SECRET_KEY)); // Replace
 transaction.sign([mainWallet]);
 // Convert to binary
 const transactionBinary = Buffer.from(transaction.serialize());
 // Send transaction
 const signature = await connection.sendRawTransaction(transactionBinary, {
 maxRetries: 2,
 skipPreflight: false, // Ensure preflight checks
 });
 console.log("Transaction Signature:", signature);
 // Confirm transaction
 const confirmation = await connection.confirmTransaction(signature, "confirmed");
 if (confirmation.value.err) {
 console.log(`Transaction failed: https://solscan.io/tx/${signature}`);
 } else {
 console.log(`Transaction successful: https://solscan.io/tx/${signature}`);
 }
 res.status(200).json({ message: "Swap executed successfully", signature });
 } catch (error) {
 console.error("Swap Error:", error);
 res.status(500).json({ message: "Swap failed: " + error.message });
 }
};
answered Feb 2, 2025 at 8:39
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.