Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why does using Jupiter API swap-instructions to invoke a wallet not show correct data, but using swapTransaction works fine? #33

Open
yyidota opened this issue May 16, 2024 · 0 comments

Comments

@yyidota
Copy link

yyidota commented May 16, 2024

I'm encountering an issue with the Jupiter API V6 Swap API when invoking a wallet. Using swapTransaction, everything works perfectly, but when using swap-instructions, the wallet does not display the correct data. Here is the relevant part of my code:

import { SOL_COIN_ADDR } from '@/config';
import { createJupiterApiClient } from '@jup-ag/api';
import { AddressLookupTableAccount, ComputeBudgetProgram, Connection, PublicKey, TransactionInstruction, TransactionMessage, VersionedTransaction } from '@solana/web3.js';

const jupiterQuoteApi = createJupiterApiClient();

const deserializeInstruction = (instruction) => {
  return new TransactionInstruction({
    programId: new PublicKey(instruction.programId),
    keys: instruction.accounts.map((key) => ({
      pubkey: new PublicKey(key.pubkey),
      isSigner: key.isSigner,
      isWritable: key.isWritable,
    })),
    data: Buffer.from(instruction.data, "base64"),
  });
};

const getAddressLookupTableAccounts = async (connection, keys) => {
  const addressLookupTableAccountInfos = await connection.getMultipleAccountsInfo(
    keys.map((key) => new PublicKey(key))
  );

  return addressLookupTableAccountInfos.reduce((acc, accountInfo, index) => {
    const addressLookupTableAddress = keys[index];
    if (accountInfo) {
      const addressLookupTableAccount = new AddressLookupTableAccount({
        key: new PublicKey(addressLookupTableAddress),
        state: AddressLookupTableAccount.deserialize(accountInfo.data),
      });
      acc.push(addressLookupTableAccount);
    }
    return acc;
  }, []);
};

export async function queryInfo() {
  const quote = await jupiterQuoteApi.quoteGet({
    inputMint: SOL_COIN_ADDR,
    outputMint: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
    amount: 0.001 * Math.pow(10, 9),
    slippageBps: 50,
    asLegacyTransaction: false,
  });

  return quote;
}

export async function getIns(quoteResponse, owner) {
  const instructions = await jupiterQuoteApi.swapInstructionsPost({
    swapRequest: {
      "quoteResponse": quoteResponse,
      "userPublicKey": owner.toString(),
      "asLegacyTransaction": false,
      "prioritizationFeeLamports": "auto",
      "feeAccount": "D2D7GpNq38G8fgZM6ujtaBEts7CsxHFmabzHojuPVPYp"
    }
  });

  return instructions;
}

export async function getJupTranstion(connection, instructions, owner) {
  const {
    computeBudgetInstructions,
    setupInstructions,
    swapInstruction: swapInstructionPayload,
    cleanupInstruction,
    addressLookupTableAddresses,
  } = instructions;

  const addressLookupTableAccounts = await getAddressLookupTableAccounts(connection, addressLookupTableAddresses);

  const computeUnitMaxLimit = 10000;
  const microLamports = 50000;

  const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnitMaxLimit });
  const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({ microLamports: Number(microLamports) });

  const swapInstruction = deserializeInstruction(swapInstructionPayload);

  const blockhash = (await connection.getLatestBlockhash()).blockhash;
  const messageV0 = new TransactionMessage({
    payerKey: owner,
    recentBlockhash: blockhash,
    instructions: [
      // Uncomment if needed
      // modifyComputeUnits,
      // addPriorityFee,
      swapInstruction,
      // Uncomment if needed
      // deserializeInstruction(cleanupInstruction),
    ],
  }).compileToV0Message(addressLookupTableAccounts);

  const transaction = new VersionedTransaction(messageV0);

  return {
    transaction,
    blockhash
  };
}
 async function jupSwap() {
    const  quote = await queryInfo()
    const ins = await getIns(quote, publicKey)
    const { transaction } = await getJupTranstion(connection, ins, publicKey)


    const signedTxns = await signAllTransactions([transaction]);

  }

log

{
    "context": {
        "apiVersion": "1.17.28",
        "slot": 266085023
    },
    "value": {
        "accounts": null,
        "err": {
            "InstructionError": [
                0,
                "ProgramFailedToComplete"
            ]
        },
        "logs": [
            "Program JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4 invoke [1]",
            "Program log: Instruction: SharedAccountsRoute",
            "Program log: panicked at 'range end index 64 out of range for slice of length 0', src/token.rs:551:38",
            "Program JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4 consumed 16399 of 200000 compute units",
            "Program JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4 failed: SBF program panicked"
        ],
        "returnData": null,
        "unitsConsumed": 0
    }
}

When using swap-instructions, the wallet does not display the correct data, but with swapTransaction, it works fine. Could someone help me identify what might be going wrong?
screenshot-20240516-102203

Additional Details:
Solana Network Version: 1.9.25
Wallet: Phantom
Thanks in advance for any insights!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant