jup-ag / jupiter-swap-api

The jupiter swap api binary
72 stars 20 forks source link

Error confirm transaction SWAP API #35

Closed Ismola closed 1 month ago

Ismola commented 1 month ago

Good morning again. I'm still trying to improve the swap times. I'm starting to use jupiter to perform the swaps.

I followed this official tutorial: https://station.jup.ag/docs/apis/swap-api

But, the transactions it performs always give me an error:

Example: https://solscan.io/tx/28eaS6HiEgyjWTBKFGDxPVjx3CRajHBviNjMSghPPstPT1Sjo6i1734QjRmrsWGSQNxMho7BMFKb7t1SoeS7Erbb

My code:

import {
  Connection,
  Keypair,
  VersionedTransaction,
  sendAndConfirmRawTransaction,
  Commitment,
  TransactionInstruction,
  PublicKey
} from '@solana/web3.js';

import fetch from 'cross-fetch';
import { getSettings } from '../controllers/botSettingsControllers';
import { Wallet } from '@coral-xyz/anchor';
import { bs58 } from '@coral-xyz/anchor/dist/cjs/utils/bytes';
import { logger } from '../helpers';
import { addTransaction } from '../controllers/TransactionControllers';

export const jupiterTransactionExecutor = async (quoteA: string, quoteB: string, amount: number) => {
  const settings = await getSettings();

  const {
    private_key: PRIVATE_KEY,
    rpc_endpoint: RPC_ENDPOINT,
    commitment_level: COMMITMENT_LEVEL,
    sell_slippage: SELL_SLIPPAGE,
  } = settings;

  const connection = new Connection(RPC_ENDPOINT, COMMITMENT_LEVEL as Commitment);

  console.log(quoteA);
  console.log(quoteB); // SOL
  console.log(amount);

  // Convert to lamports (smallest unit of SOL)
  const amountLamports: number = amount * 1e9;

  logger.info(`Loading wallet for Token: ${quoteA}`);
  const secretKey = Array.isArray(JSON.parse(PRIVATE_KEY)) ? Uint8Array.from(JSON.parse(PRIVATE_KEY)) : bs58.decode(PRIVATE_KEY);
  const wallet = new Wallet(Keypair.fromSecretKey(secretKey));

  logger.info(`Loading pools for Token: ${quoteA}`);

  // Swapping SOL to USDC with input amount and specified slippage
  const quoteResponse = await (
    await fetch(`https://quote-api.jup.ag/v6/quote?inputMint=${quoteB}&outputMint=${quoteA}&amount=${amountLamports}&slippageBps=${SELL_SLIPPAGE}`)
  ).json();

  console.log({ quoteResponse });

  logger.info(`Loading transaction for Token: ${quoteA}`);

  // Get serialized transactions for the swap
  const { swapTransaction } = await (
    await fetch('https://quote-api.jup.ag/v6/swap', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        quoteResponse,
        userPublicKey: wallet.publicKey.toString(),
        wrapAndUnwrapSol: true
      })
    })
  ).json();

  logger.info(`Signing transaction for Token: ${quoteA}`);

  // Deserialize the transaction
  const swapTransactionBuf = Buffer.from(swapTransaction, 'base64');
  const transaction = VersionedTransaction.deserialize(swapTransactionBuf);

  console.log(wallet.payer);

  // Get the latest block hash immediately before sending the transaction
  const latestBlockHash = await connection.getLatestBlockhash();

  // Update the blockhash in the transaction
  transaction.message.recentBlockhash = latestBlockHash.blockhash;

  // Sign the transaction
  transaction.sign([wallet.payer]);

  logger.info(`Executing transaction for Token: ${quoteA}`);

  // Execute the transaction
  const rawTransaction = transaction.serialize();

  try {
    const txid = await connection.sendRawTransaction(rawTransaction, {
      skipPreflight: true,
      maxRetries: 5 // Increased retry count
    });

    logger.info(`Confirming transaction for Token: ${quoteA}`);
    await connection.confirmTransaction({
      blockhash: latestBlockHash.blockhash,
      lastValidBlockHeight: latestBlockHash.lastValidBlockHeight,
      signature: txid
    });

    console.log(`https://solscan.io/tx/${txid}`);

    await addTransaction({
      id: quoteB,
      mint: quoteB,
      dex: `https://dexscreener.com/solana/${quoteB}?maker=${wallet.publicKey.toString()}`,
      url: `https://solscan.io/tx/${txid}`,
      signature: txid,
      success: true,
      direction: 'sell',
    });

  } catch (error) {
    logger.error(`Transaction failed: ${error}`);
    throw new Error(`Transaction failed: ${error}`);
  }
};
siong1987 commented 1 month ago

sendRawTransaction doesn't work. i will highly suggest looking into transactionSender https://github.com/jup-ag/jupiter-quote-api-node/blob/main/example/utils/transactionSender.ts

this also has nothing to do with the API. just how you land your transaction.